Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgICAgX19fXyAgICAgICAgICAgICAgICAgICAgICAgIF8gICAgICBfCi8vICAgICAvIF9fX3xfX19fIF8gICBfIF9fX18gICBfX19ffCB8X18gIHwgfAovLyAgICB8IHwgICAvIF9fX3wgfCB8IHwgIF8gIFwvIF9fX3wgIF8gIFx8IHwKLy8gICAgfCB8X19ffCB8ICB8IHxffCB8IHwgfCB8IHxfX198IHwgfCB8fF98Ci8vICAgICBcX19fX3xffCAgXF9fX19ffF98IHxffFxfX19ffF98IHxffChfKSBNZWRpYSBiZW5jaG1hcmtzCi8vICAgICAgICAgICAgICAgICAgICAgICAgIAovLwkgqSAyMDA2LCBJbnRlbCBDb3Jwb3JhdGlvbiwgbGljZW5zZWQgdW5kZXIgQXBhY2hlIDIuMCAKLy8KLy8gIGZpbGUgOiBJbWFnZU1lYXN1cmVtZW50cy5jcHAKLy8gIGF1dGhvciA6IFNjb3R0IEV0dGluZ2VyIC0gc2NvdHQubS5ldHRpbmdlckBpbnRlbC5jb20KLy8JCQkgSmVhbi1ZdmVzIEJvdWd1ZXQgLSBqZWFuLXl2ZXMuYm91Z3VldEBpbnRlbC5jb20KLy8JCQkgCi8vICBkZXNjcmlwdGlvbiA6IEltYWdlIE1lYXN1cmVtZW50cyAoc2lsaG91ZXR0ZSBhbmQgZWRnZXMpCi8vICBtb2RpZmllZCA6IAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojaWYgZGVmaW5lZChIQVZFX0NPTkZJR19IKQojIGluY2x1ZGUgImNvbmZpZy5oIgojZW5kaWYKCiNpbmNsdWRlICJJbWFnZU1lYXN1cmVtZW50cy5oIgojaW5jbHVkZSA8bWF0aC5oPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCi8vMkQgdmVjdG9yIG1hZ25pdHVkZQppbmxpbmUgZG91YmxlIG1hZyhQb2ludCAmcCkKewlyZXR1cm4gc3FydCgoZG91YmxlKShwLnggKiBwLnggKyBwLnkgKiBwLnkpKTsKfQoKLy9hY2N1bXVsYXRlIGVycm9yIGF0IGEgZ2l2ZW4gZWRnZSBzYW1wbGUgcG9pbnQgKHJvdW5kIHRvIG5lYXJlc3QgaW50ZWdyYWwgcG9pbnQpCmlubGluZSB2b2lkIFNhbXBsZUVkZ2VQb2ludChmbG9hdCB4ZiwgZmxvYXQgeWYsIGNvbnN0IEZsZXhJbWFnZTh1ICZFZGdlTWFwLCBpbnQgJmVycm9yLCBpbnQgJnNhbXBsZVBvaW50cykKewoJaW50IHggPSBpbnQoeGYgKyAwLjVmKSwgeSA9IGludCh5ZiArIDAuNWYpOwoJaWYoKHggPj0gMCkgJiYgKHggPCBFZGdlTWFwLldpZHRoKCkpICYmICh5ID49IDApICYmICh5IDwgRWRnZU1hcC5IZWlnaHQoKSkpIC8vY2hlY2sgaW1hZ2UgYm91bmRzCgl7CWludCBlID0gMjU1IC0gRWRnZU1hcCh4LHkpOwkJCQkJCQkJCQkJCS8vZ2V0IHZhbHVlIGZyb20gaW1hZ2UgbWFwIGFuZCBjb21wdXRlIGRpZmZlcmVuY2UKCQllcnJvciArPSAoZSAqIGUpOwkJCQkJCQkJCQkJCQkJLy9zdW0gc3F1YXJlZCBlcnJvciB2YWx1ZXMKCQlzYW1wbGVQb2ludHMrKzsJCQkJCQkJCQkJCQkJCQkvL2NvdW50IHBvaW50cyBzYW1wbGVkCgl9Cn0KCi8vR2VuZXJhdGUgU2FtcGxlcyBmb3IgcG9pbnRzIGFsb25nIHRoZSBub24tam9pbnQgZWRnZXMgb2YgdGhlIGN5bGluZGVyCnZvaWQgSW1hZ2VNZWFzdXJlbWVudHM6OkVkZ2VFcnJvcihjb25zdCBQcm9qZWN0ZWRDeWxpbmRlciAmUHJvakN5bCwgY29uc3QgRmxleEltYWdlOHUgJkVkZ2VNYXAsIGZsb2F0ICZlcnJvciwgaW50ICZzYW1wbGVQb2ludHMpCnsKCWludCBFcnJvclNTRCA9IDA7Cgljb25zdCBQb2ludCAmcDEgPSBQcm9qQ3lsLm1QdHNbMF07CglQb2ludCBzMTsJCQkJCQkJCQkJCQkJCQkJLy9nZXQgZGlyZWN0aW9uIHZlY3RvciBvZiBzaWRlIDEgb2YgdGhlIDJEIGN5bGluZGVyIHByb2plY3Rpb24KCXMxLlNldChQcm9qQ3lsLm1QdHNbMV0ueCAtIHAxLngsIFByb2pDeWwubVB0c1sxXS55IC0gcDEueSk7CglpbnQgbjEgPSBtYXgoKGludCkobWFnKHMxKSAvIG1TdGVwICsgMC41KSwgNCk7CQkJCQkJCS8vY29tcHV0ZSBudW1iZXIgb2YgcG9pbnRzIHNhbXBsZWQgKHNhbXBsZSBhdCBsZWFzdCA0KQoJZmxvYXQgZDEgPSAxLjBmIC8gKGZsb2F0KW4xKys7CQkJCQkJCQkJCQkvL2dldCBmcmFjdGlvbiBvZiBzaWRlIGxlbmd0aCBwZXIgc2FtcGxlCgoJY29uc3QgUG9pbnQgJnAyID0gUHJvakN5bC5tUHRzWzJdOwoJUG9pbnQgczI7CQkJCQkJCQkJCQkJCQkJCS8vcmVwZWF0IGZvciBzaWRlIDIgb2YgY3lsaW5kZXIKCXMyLlNldChQcm9qQ3lsLm1QdHNbM10ueCAtIHAyLngsIFByb2pDeWwubVB0c1szXS55IC0gcDIueSk7CglpbnQgbjIgPSBtYXgoKGludCkobWFnKHMyKSAvIG1TdGVwICsgMC41KSwgNCk7CQkJCQkKCWZsb2F0IGQyID0gMS4wZiAvIChmbG9hdCluMisrOwoKCWZsb2F0IGRlbHRhID0gMDsKCWZvcihpbnQgaSA9IDA7IGkgPCBuMTsgaSsrKQkJCQkJCQkJCQkJCS8vZ2VuZXJhdGUgc2FtcGxlIHBvaW50cyBhbG9uZyBlYWNoIHNpZGUgb2YgY3lsaW5kZXIgcHJvamVjdGlvbgoJewlmbG9hdCB4ID0gcDEueCArIGRlbHRhICogczEueDsKCQlmbG9hdCB5ID0gcDEueSArIGRlbHRhICogczEueTsKCQlTYW1wbGVFZGdlUG9pbnQoeCwgeSwgRWRnZU1hcCwgRXJyb3JTU0QsIHNhbXBsZVBvaW50cyk7CQkJCS8vYWNjdW11bGF0ZSBlcnJvciBhdCBjb21wdXRlZCBlZGdlIHBvaW50cyBvbiBzaWRlIDEKICAJCWRlbHRhICs9IGQxOwoJfQoJZGVsdGEgPSAwOwoJZm9yKGludCBpID0gMDsgaSA8IG4yOyBpKyspCgl7CWZsb2F0IHggPSBwMi54ICsgZGVsdGEgKiBzMi54OwoJCWZsb2F0IHkgPSBwMi55ICsgZGVsdGEgKiBzMi55OwoJCVNhbXBsZUVkZ2VQb2ludCh4LCB5LCBFZGdlTWFwLCBFcnJvclNTRCwgc2FtcGxlUG9pbnRzKTsJCQkJLy9hY2N1bXVsYXRlIGVycm9yIGF0IGNvbXB0dWVkIGVkZ2UgcG9pbnRzIG9uIHNpZGUgMgoJCWRlbHRhICs9IGQyOwoJfQoJZXJyb3IgKz0gKGZsb2F0KUVycm9yU1NEIC8gKDI1NS4wZiAqIDI1NS4wZik7Cn0KCi8vY2hlY2sgYm91bmRzIG9mIG5lYXJlc3QgaW50ZWdyYWwgcG9pbnQgYW5kIGFjY3VtdWxhdGUgZXJyb3IgdmFsdWUKaW5saW5lIHZvaWQgU2FtcGxlSW5zaWRlUG9pbnQoZmxvYXQgeGYsIGZsb2F0IHlmLCBjb25zdCBCaW5hcnlJbWFnZSAmRkdtYXAsIGludCAmZXJyb3IsIGludCAmc2FtcGxlUG9pbnRzKQp7CglpbnQgeCA9IGludCh4ZiArIDAuNWYpLCB5ID0gaW50KHlmICsgMC41Zik7CglpZigoeCA+PSAwKSAmJiAoeCA8IEZHbWFwLldpZHRoKCkpICYmICh5ID49IDApICYmICh5IDwgRkdtYXAuSGVpZ2h0KCkpKSAvL2NoZWNrIGltYWdlIGJvdW5kcwoJewlpbnQgZSA9IDEgLSBGR21hcCh4LHkpOwkJCQkJCQkJCQkJCS8vZ2V0IHZhbHVlIGZyb20gaW1hZ2UgbWFwIGFuZCBjb21wdXRlIGRpZmZlcmVuY2UKCQllcnJvciArPSBlOwkJCQkJCQkJCQkJCQkJCS8vc3VtIHNxdWFyZWQgZXJyb3IgdmFsdWVzIChzaW5jZSBlcnIgPSB7MSwwfSBzYW1lIGFzIHN1bSBvZiBlcnJvcnMpCgkJc2FtcGxlUG9pbnRzKys7CQkJCQkJCQkJCQkJCQkvL2NvdW50IHBvaW50cyBzYW1wbGVkCgl9Cn0KCi8vU2FtcGxlIHBvaW50cyBpbnNpZGUgdGhlIHByb2plY3RlZCBjeWxpbmRlcgp2b2lkIEltYWdlTWVhc3VyZW1lbnRzOjpJbnNpZGVFcnJvcihjb25zdCBQcm9qZWN0ZWRDeWxpbmRlciAmUHJvakN5bCwgY29uc3QgQmluYXJ5SW1hZ2UgJkZHbWFwLCBpbnQgJmVycm9yLCBpbnQgJnNhbXBsZVBvaW50cykKewoJY29uc3QgUG9pbnQgJnAxID0gUHJvakN5bC5tUHRzWzBdLCAmcDIgPSBQcm9qQ3lsLm1QdHNbM107CglQb2ludCBzMSwgczI7CglzMS5TZXQoUHJvakN5bC5tUHRzWzFdLnggLSBwMS54LCBQcm9qQ3lsLm1QdHNbMV0ueSAtIHAxLnkpOwkJCQkvL2dldCB2ZWN0b3JzIGFsb25nIHNpZGVzCglzMi5TZXQoUHJvakN5bC5tUHRzWzJdLnggLSBwMi54LCBQcm9qQ3lsLm1QdHNbMl0ueSAtIHAyLnkpOwoJUG9pbnQgbShwMS54ICsgczEueCAvIDIuMGYgLSAocDIueCArIHMyLnggLyAyLjBmKSwgcDEueSArIHMxLnkgLyAyLjBmIC0gKHAyLnkgKyBzMi55IC8gMi4wZikpOwoJaW50IG4xID0gbWF4KChpbnQpKG1hZyhzMSkgLyBtVnN0ZXAgKyAwLjUpLCA0KTsJCQkJCQkJLy9jb21wdXRlIG51bWJlciBvZiBwb2ludHMgc2FtcGxlZCBvbiBlYWNoIHNpZGUgKHNhbXBsZSBhdCBsZWFzdCA0KQoJaW50IG4yID0gbWF4KChpbnQpKG1hZyhtKSAvIG1Ic3RlcCArIDAuNWYpLCA0KTsJCQkJCQkJLy9jb21wdXRlIG51bWJlciBvZiBpbnRlcmlvciBzYW1wbGVzIHVzaW5nIHRoZSBtaWRwb2ludCBsZW5ndGgKCWZsb2F0IGQxID0gMS4wZiAvIG4xKys7CQkJCQkJCQkJCQkJCS8vZ2V0IGZyYWN0aW9uIG9mIHNpZGUgbGVuZ3RocyBwZXIgc2FtcGxlCglmbG9hdCBkMiA9IDEuMGYgLyBuMjsKCWZsb2F0IGRlbHRhMSA9IDA7CglQb2ludCBlMSwgZTI7Cglmb3IoaW50IGkgPSAwOyBpIDwgbjE7IGkrKykJCQkJCQkJCQkJCQkvL2dlbmVyYXRlIHNhbXBsZSBwb2ludHMgYWxvbmcgZWFjaCBzaWRlIG9mIGN5bGluZGVyIHByb2plY3Rpb24KCXsgICBlMS5TZXQocDEueCArIGRlbHRhMSAqIHMxLngsIHAxLnkgKyBkZWx0YTEgKiBzMS55KTsKCQllMi5TZXQocDIueCArIGRlbHRhMSAqIHMyLngsIHAyLnkgKyBkZWx0YTEgKiBzMi55KTsKCQltLlNldChlMi54IC0gZTEueCwgZTIueSAtIGUxLnkpOwkJCQkJCQkJCS8vZ2V0IHZlY3RvciBiZXR3ZWVuIGVkZ2UgcG9pbnRzCgkJZGVsdGExICs9IGQxOwoJCWZsb2F0IGRlbHRhMiA9IDA7CgkJZm9yKGludCBqID0gMDsgaiA8IG4yOyBqKyspCQkJCQkJCQkJCQkvL2dlbmVyYXRlIGludGVyaW9yIHNhbXBsZXMKCQl7CVNhbXBsZUluc2lkZVBvaW50KGUxLnggKyBkZWx0YTIgKiBtLngsIGUxLnkgKyBkZWx0YTIgKiBtLnksIEZHbWFwLCBlcnJvciwgc2FtcGxlUG9pbnRzKTsKCQkJZGVsdGEyICs9IGQyOwoJCX0KCX0KfQoKLy9jb21wdXRlIGVkZ2UgbWFwIGVycm9yIHRlcm0gZm9yIGFsbCBjYW1lcmFzIGdpdmVuIHRoZSBzZXQgb2YgMkQgYm9keSBnZW9tZXRyeSBwcm9qZWN0aW9ucwpmbG9hdCBJbWFnZU1lYXN1cmVtZW50czo6SW1hZ2VFcnJvckVkZ2Uoc3RkOjp2ZWN0b3I8RmxleEltYWdlOHU+ICZJbWFnZU1hcHMsIE11bHRpQ2FtZXJhUHJvamVjdGVkQm9keSAmUHJvakJvZGllcykgCnsKCWludCBzYW1wbGVzID0gMDsKCWZsb2F0IGVycm9yID0gMDsKCWZvcihpbnQgaSA9IDA7IGkgPCAoaW50KUltYWdlTWFwcy5zaXplKCk7IGkrKykJCQkJCQkJLy9mb3IgZWFjaCBjYW1lcmEsIGNvbXB1dGUgdGhlIGVkZ2UgbWFwIGVycm9yIHRlcm0KCXsJaW50IG5QYXJ0cyA9IFByb2pCb2RpZXMoaSkuU2l6ZSgpOwoJCWZvcihpbnQgaiA9IDA7IGogPCBuUGFydHM7IGorKykJCQkJCQkJCQkJLy9hY2N1bXVsYXRlIGVkZ2UgZXJyb3IgZm9yIGVhY2ggYm9keSBwYXJ0LCBjb3VudGluZyBzYW1wbGVzCgkJCUVkZ2VFcnJvcihQcm9qQm9kaWVzKGkpKGopLCBJbWFnZU1hcHNbaV0sIGVycm9yLCBzYW1wbGVzKTsKCX0KCS8vY291dCA8PCAiU2FtcGxlcyA9ICIgPDwgc2FtcGxlcyA8PCBlbmRsOwoJcmV0dXJuIChmbG9hdCllcnJvciAvIHNhbXBsZXM7CQkJCQkJCQkJCQkvL25vcm1hbGl6ZSB0byBudW1iZXIgb2Ygc2FtcGxlcwp9CgovL2NvbXB1dGUgc2lsaG91ZXR0ZSBlcnJvciB0ZXJtIGZvciBhbGwgY2FtZXJhcyBnaXZlbiB0aGUgc2V0IG9mIDJEIGJvZHkgZ2VvbWV0cnkgcHJvamVjdGlvbnMKZmxvYXQgSW1hZ2VNZWFzdXJlbWVudHM6OkltYWdlRXJyb3JJbnNpZGUoc3RkOjp2ZWN0b3I8QmluYXJ5SW1hZ2U+ICZJbWFnZU1hcHMsIE11bHRpQ2FtZXJhUHJvamVjdGVkQm9keSAmUHJvakJvZGllcykKewoJaW50IHNhbXBsZXMgPSAwOwoJaW50IGVycm9yID0gMDsKCWZvcihpbnQgaSA9IDA7IGkgPCAoaW50KUltYWdlTWFwcy5zaXplKCk7IGkrKykJCQkJCQkJLy9mb3IgZWFjaCBjYW1lcmEsIGNvbXB1dGUgdGhlIGVkZ2UgbWFwIGVycm9yIHRlcm0KCXsJaW50IG5QYXJ0cyA9IFByb2pCb2RpZXMoaSkuU2l6ZSgpOwoJCWZvcihpbnQgaiA9IDA7IGogPCBuUGFydHM7IGorKykJCQkJCQkJCQkJLy9hY2N1bXVsYXRlIGVkZ2UgZXJyb3IgZm9yIGVhY2ggYm9keSBwYXJ0LCBjb3VudGluZyBzYW1wbGVzCgkJCUluc2lkZUVycm9yKFByb2pCb2RpZXMoaSkoaiksIEltYWdlTWFwc1tpXSwgZXJyb3IsIHNhbXBsZXMpOwoJfQoJLy9jb3V0IDw8ICJTYW1wbGVzID0gIiA8PCBzYW1wbGVzIDw8IGVuZGw7CglyZXR1cm4gKGZsb2F0KWVycm9yIC8gc2FtcGxlczsKfQo=