// Create Base64 Object
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}
function detect_img(encoded, Base64) {
// Define the string, also meaning that you need to know the file extension
//var encoded = "Base64 encoded image returned from your service";
// Decode the string
var decoded = Base64.decode(encoded);
//console.log(decoded);
// if the file extension is unknown
var extension = undefined;
// do something like this
var lowerCase = decoded.toLowerCase();
if (lowerCase.indexOf("png") !== -1) extension = "png"
else if (lowerCase.indexOf("jpg") !== -1 || lowerCase.indexOf("jpeg") !== -1)
extension = "jpg"
else extension = "tiff";
// and then to display the image
//var img = document.createElement("img");
//img.src = decoded;
// alternatively, you can do this
//img.src = "data:image/" + extension + ";base64," + encoded;
return extension;
}
imgs = {
"img.bmp": "Qk2KAwAAAAAAAIoAAAB8AAAAGAAAAAgAAAABACAAAwAAAAADAAATCwAAEwsAAAAAAAAAAAAAAAD/AAD/AAD/AAAAAAAA/0JHUnMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAA////////////////UE5H/1BOR/9QTkf/UE5H////////////UE5H/////////////////1BOR///////UE5H////////////////////////////////////////////////////////////UE5H/////////////////1BOR///////UE5H/////////////////1BOR///////UE5H////////////////////////////////////////////////////////////UE5H/////////////////1BOR///////UE5H/////////////////1BOR///////UE5H////////////////////////////////////////////////////////////UE5H/1BOR/9QTkf/UE5H////////////UE5H/////////////////1BOR///////UE5H/1BOR/9QTkf/UE5H////////////////////////////////////////////UE5H/////////////////1BOR///////UE5H//////9QTkf//////1BOR///////UE5H/////////////////1BOR///////////////////////////////////////UE5H/////////////////1BOR///////UE5H/1BOR///////UE5H/1BOR///////UE5H/////////////////1BOR///////////////////////////////////////UE5H/1BOR/9QTkf/UE5H////////////UE5H/////////////////1BOR///////UE5H/1BOR/9QTkf/UE5H////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////",
"img.gif": "R0lGODlhGAAIAIABACYmJv///yH+A1BORwAh+QQBCgABACwAAAAAGAAIAAACHYyPqXvgBoJ7rNkYa8pXb/lglMdhkoeUJ4eCmckUADs=",
"img.jpeg": "/9j/4AAQSkZJRgABAQEASABIAAD//gAFUE5H/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8IAEQgACAAYAwERAAIRAQMRAf/EABYAAAMAAAAAAAAAAAAAAAAAAAQFB//EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAawAjI//xAAZEAEAAwEBAAAAAAAAAAAAAAAEAQMFAgb/2gAIAQEAAQUC9G/tCWxZntC2ydz/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AX//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AX//xAAkEAACAgEDAgcAAAAAAAAAAAABAwIRBAASIQVRFCIxMkFDUv/aAAgBAQAGPwJasN07hS3LiySqkchAAkRzGxvo9rrXT05+WEY7A6WyXUmLEBavs9WH3Gj+q+NQgZmb5OdFsPEndCAM9lpqhGgvzcHkd+f/xAAZEAEBAQEBAQAAAAAAAAAAAAABESEAMYH/2gAIAQEAAT8hTB+CdTAxrVHIBoCkAGdpx9VC8XbL7snT5jZ3b7//2gAMAwEAAgADAAAAEBJ//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxB//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxB//8QAGBABAAMBAAAAAAAAAAAAAAAAAQARITH/2gAIAQEAAT8QuOimHFedNNz6rOMpcMA7FYGDCS91tSxBSnIxf//Z",
"img.png": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAICAYAAADjoT9jAAAAXUlEQVQoz7VRwQ0AIQgTwyzdf54u471IGkIUTa4vi0JbHONnmBIASzlJi3qcM9cefVMiCwQHsPRO66cEsxuVpHUGZvguxTFyo8crp7cuq/+4XtHrmvzFbYhkwSr9B/CFOdb5KVaaAAAAAElFTkSuQmCC",
"img.tiff": "SUkqAAgDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmJib/JiYm/yYmJv8mJib/JiYm/wAAAAAmJib/AAAAACYmJv8mJib/JiYm/yYmJv8AAAAAJiYm/yYmJv8mJib/JiYm/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYmJv8AAAAAAAAAAAAAAAAmJib/AAAAACYmJv8AAAAAAAAAAAAAAAAAAAAAJiYm/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYmJv8AAAAAAAAAAAAAAAAmJib/AAAAACYmJv8AAAAAAAAAAAAAAAAAAAAAJiYm/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYmJv8AAAAAAAAAAAAAAAAmJib/AAAAACYmJv8mJib/JiYm/wAAAAAAAAAAJiYm/yYmJv8mJib/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYmJv8AAAAAAAAAAAAAAAAmJib/AAAAACYmJv8AAAAAAAAAAAAAAAAAAAAAJiYm/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYmJv8AAAAAAAAAAAAAAAAmJib/AAAAACYmJv8AAAAAAAAAAAAAAAAAAAAAJiYm/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYmJv8AAAAAAAAAAAAAAAAmJib/AAAAACYmJv8AAAAAAAAAAAAAAAAAAAAAJiYm/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATAAABAwABAAAAGAAAAAEBAwABAAAACAAAAAIBAwAEAAAAAgQAAAMBAwABAAAAAQAAAAYBAwABAAAAAgAAAA0BAgA7AAAAEgQAAA4BAgAEAAAAUE5HABEBBAABAAAACAAAABIBAwABAAAAAQAAABUBAwABAAAABAAAABYBAwABAAAAgAAAABcBBAABAAAAAAMAABoBBQABAAAA8gMAABsBBQABAAAA+gMAABwBAwABAAAAAQAAAB0BAgAHAAAATgQAACgBAwABAAAAAgAAAFIBAwABAAAAAQAAAFMBAwAEAAAACgQAAAAAAABIAAAAAQAAAEgAAAABAAAACAAIAAgACAABAAEAAQABAEM6XFVzZXJzXGdyZWdvXFByb2plY3RzXFNPIHRlc3RcYmFzZXI2NGltZ19kZXRlY3RcaW1nLnRpZmYAAE96YWRqZQA="
}
function test(imgs, Base64) {
for (const [name, base64data] of Object.entries(imgs)) {
const header = [...atob(base64data)]
.slice(0, 16)
.map(c => c.charCodeAt(0))
.filter(c => 32 <= c && c <= 126)
.map(c => String.fromCharCode(c))
.join("")
;
console.log(name);
console.log(" header:", header);
console.log(" deteted:", detect_img(base64data, Base64));
}
}
console.log("=== Broken Base64 ===");
test(imgs, Base64);
console.log();
console.log("=== Proper Base64 ===");
test(imgs, {decode:b64 => atob(b64)});
Ly8gQ3JlYXRlIEJhc2U2NCBPYmplY3QKdmFyIEJhc2U2ND17X2tleVN0cjoiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz0iLGVuY29kZTpmdW5jdGlvbihlKXt2YXIgdD0iIjt2YXIgbixyLGkscyxvLHUsYTt2YXIgZj0wO2U9QmFzZTY0Ll91dGY4X2VuY29kZShlKTt3aGlsZShmPGUubGVuZ3RoKXtuPWUuY2hhckNvZGVBdChmKyspO3I9ZS5jaGFyQ29kZUF0KGYrKyk7aT1lLmNoYXJDb2RlQXQoZisrKTtzPW4+PjI7bz0obiYzKTw8NHxyPj40O3U9KHImMTUpPDwyfGk+PjY7YT1pJjYzO2lmKGlzTmFOKHIpKXt1PWE9NjR9ZWxzZSBpZihpc05hTihpKSl7YT02NH10PXQrdGhpcy5fa2V5U3RyLmNoYXJBdChzKSt0aGlzLl9rZXlTdHIuY2hhckF0KG8pK3RoaXMuX2tleVN0ci5jaGFyQXQodSkrdGhpcy5fa2V5U3RyLmNoYXJBdChhKX1yZXR1cm4gdH0sZGVjb2RlOmZ1bmN0aW9uKGUpe3ZhciB0PSIiO3ZhciBuLHIsaTt2YXIgcyxvLHUsYTt2YXIgZj0wO2U9ZS5yZXBsYWNlKC9bXkEtWmEtejAtOVwrXC9cPV0vZywiIik7d2hpbGUoZjxlLmxlbmd0aCl7cz10aGlzLl9rZXlTdHIuaW5kZXhPZihlLmNoYXJBdChmKyspKTtvPXRoaXMuX2tleVN0ci5pbmRleE9mKGUuY2hhckF0KGYrKykpO3U9dGhpcy5fa2V5U3RyLmluZGV4T2YoZS5jaGFyQXQoZisrKSk7YT10aGlzLl9rZXlTdHIuaW5kZXhPZihlLmNoYXJBdChmKyspKTtuPXM8PDJ8bz4+NDtyPShvJjE1KTw8NHx1Pj4yO2k9KHUmMyk8PDZ8YTt0PXQrU3RyaW5nLmZyb21DaGFyQ29kZShuKTtpZih1IT02NCl7dD10K1N0cmluZy5mcm9tQ2hhckNvZGUocil9aWYoYSE9NjQpe3Q9dCtTdHJpbmcuZnJvbUNoYXJDb2RlKGkpfX10PUJhc2U2NC5fdXRmOF9kZWNvZGUodCk7cmV0dXJuIHR9LF91dGY4X2VuY29kZTpmdW5jdGlvbihlKXtlPWUucmVwbGFjZSgvXHJcbi9nLCJcbiIpO3ZhciB0PSIiO2Zvcih2YXIgbj0wO248ZS5sZW5ndGg7bisrKXt2YXIgcj1lLmNoYXJDb2RlQXQobik7aWYocjwxMjgpe3QrPVN0cmluZy5mcm9tQ2hhckNvZGUocil9ZWxzZSBpZihyPjEyNyYmcjwyMDQ4KXt0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKHI+PjZ8MTkyKTt0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKHImNjN8MTI4KX1lbHNle3QrPVN0cmluZy5mcm9tQ2hhckNvZGUocj4+MTJ8MjI0KTt0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKHI+PjYmNjN8MTI4KTt0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKHImNjN8MTI4KX19cmV0dXJuIHR9LF91dGY4X2RlY29kZTpmdW5jdGlvbihlKXt2YXIgdD0iIjt2YXIgbj0wO3ZhciByPWMxPWMyPTA7d2hpbGUobjxlLmxlbmd0aCl7cj1lLmNoYXJDb2RlQXQobik7aWYocjwxMjgpe3QrPVN0cmluZy5mcm9tQ2hhckNvZGUocik7bisrfWVsc2UgaWYocj4xOTEmJnI8MjI0KXtjMj1lLmNoYXJDb2RlQXQobisxKTt0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKChyJjMxKTw8NnxjMiY2Myk7bis9Mn1lbHNle2MyPWUuY2hhckNvZGVBdChuKzEpO2MzPWUuY2hhckNvZGVBdChuKzIpO3QrPVN0cmluZy5mcm9tQ2hhckNvZGUoKHImMTUpPDwxMnwoYzImNjMpPDw2fGMzJjYzKTtuKz0zfX1yZXR1cm4gdH19CiAKZnVuY3Rpb24gZGV0ZWN0X2ltZyhlbmNvZGVkLCBCYXNlNjQpIHsKCS8vIERlZmluZSB0aGUgc3RyaW5nLCBhbHNvIG1lYW5pbmcgdGhhdCB5b3UgbmVlZCB0byBrbm93IHRoZSBmaWxlIGV4dGVuc2lvbgoJLy92YXIgZW5jb2RlZCA9ICJCYXNlNjQgZW5jb2RlZCBpbWFnZSByZXR1cm5lZCBmcm9tIHlvdXIgc2VydmljZSI7CiAKCS8vIERlY29kZSB0aGUgc3RyaW5nCgl2YXIgZGVjb2RlZCA9IEJhc2U2NC5kZWNvZGUoZW5jb2RlZCk7CgkvL2NvbnNvbGUubG9nKGRlY29kZWQpOwogCgkvLyBpZiB0aGUgZmlsZSBleHRlbnNpb24gaXMgdW5rbm93bgoJdmFyIGV4dGVuc2lvbiA9IHVuZGVmaW5lZDsKCS8vIGRvIHNvbWV0aGluZyBsaWtlIHRoaXMKCXZhciBsb3dlckNhc2UgPSBkZWNvZGVkLnRvTG93ZXJDYXNlKCk7CglpZiAobG93ZXJDYXNlLmluZGV4T2YoInBuZyIpICE9PSAtMSkgZXh0ZW5zaW9uID0gInBuZyIKCWVsc2UgaWYgKGxvd2VyQ2FzZS5pbmRleE9mKCJqcGciKSAhPT0gLTEgfHwgbG93ZXJDYXNlLmluZGV4T2YoImpwZWciKSAhPT0gLTEpCgkJZXh0ZW5zaW9uID0gImpwZyIKCWVsc2UgZXh0ZW5zaW9uID0gInRpZmYiOwogCgkvLyBhbmQgdGhlbiB0byBkaXNwbGF5IHRoZSBpbWFnZQoJLy92YXIgaW1nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiaW1nIik7CgkvL2ltZy5zcmMgPSBkZWNvZGVkOwogCgkvLyBhbHRlcm5hdGl2ZWx5LCB5b3UgY2FuIGRvIHRoaXMKCS8vaW1nLnNyYyA9ICJkYXRhOmltYWdlLyIgKyBleHRlbnNpb24gKyAiO2Jhc2U2NCwiICsgZW5jb2RlZDsKCXJldHVybiBleHRlbnNpb247Cn0KIAppbWdzID0gewoJImltZy5ibXAiOiAiUWsyS0F3QUFBQUFBQUlvQUFBQjhBQUFBR0FBQUFBZ0FBQUFCQUNBQUF3QUFBQUFEQUFBVEN3QUFFd3NBQUFBQUFBQUFBQUFBQUFEL0FBRC9BQUQvQUFBQUFBQUEvMEpIVW5NQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUNBQUFBQUFBQUFBQUFBQUFBQUFBQS8vLy8vLy8vLy8vLy8vLy9VRTVILzFCT1IvOVFUa2YvVUU1SC8vLy8vLy8vLy8vL1VFNUgvLy8vLy8vLy8vLy8vLy8vLzFCT1IvLy8vLy8vVUU1SC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1VFNUgvLy8vLy8vLy8vLy8vLy8vLzFCT1IvLy8vLy8vVUU1SC8vLy8vLy8vLy8vLy8vLy8vMUJPUi8vLy8vLy9VRTVILy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vVUU1SC8vLy8vLy8vLy8vLy8vLy8vMUJPUi8vLy8vLy9VRTVILy8vLy8vLy8vLy8vLy8vLy8xQk9SLy8vLy8vL1VFNUgvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9VRTVILzFCT1IvOVFUa2YvVUU1SC8vLy8vLy8vLy8vL1VFNUgvLy8vLy8vLy8vLy8vLy8vLzFCT1IvLy8vLy8vVUU1SC8xQk9SLzlRVGtmL1VFNUgvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1VFNUgvLy8vLy8vLy8vLy8vLy8vLzFCT1IvLy8vLy8vVUU1SC8vLy8vLzlRVGtmLy8vLy8vMUJPUi8vLy8vLy9VRTVILy8vLy8vLy8vLy8vLy8vLy8xQk9SLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vVUU1SC8vLy8vLy8vLy8vLy8vLy8vMUJPUi8vLy8vLy9VRTVILzFCT1IvLy8vLy8vVUU1SC8xQk9SLy8vLy8vL1VFNUgvLy8vLy8vLy8vLy8vLy8vLzFCT1IvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9VRTVILzFCT1IvOVFUa2YvVUU1SC8vLy8vLy8vLy8vL1VFNUgvLy8vLy8vLy8vLy8vLy8vLzFCT1IvLy8vLy8vVUU1SC8xQk9SLzlRVGtmL1VFNUgvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8iLAoJImltZy5naWYiOiAiUjBsR09EbGhHQUFJQUlBQkFDWW1Kdi8vL3lIK0ExQk9Sd0FoK1FRQkNnQUJBQ3dBQUFBQUdBQUlBQUFDSFl5UHFYdmdCb0o3ck5rWWE4cFhiL2xnbE1kaGtvZVVKNGVDbWNrVUFEcz0iLAoJImltZy5qcGVnIjogIi85ai80QUFRU2taSlJnQUJBUUVBU0FCSUFBRC8vZ0FGVUU1SC85c0FRd0FEQWdJREFnSURBd01EQkFNREJBVUlCUVVFQkFVS0J3Y0dDQXdLREF3TENnc0xEUTRTRUEwT0VRNExDeEFXRUJFVEZCVVZGUXdQRnhnV0ZCZ1NGQlVVLzlzQVF3RURCQVFGQkFVSkJRVUpGQTBMRFJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVUvOElBRVFnQUNBQVlBd0VSQUFJUkFRTVJBZi9FQUJZQUFBTUFBQUFBQUFBQUFBQUFBQUFBQUFRRkIvL0VBQlFCQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBTUF3RUFBaEFERUFBQUFhd0FqSS8veEFBWkVBRUFBd0VCQUFBQUFBQUFBQUFBQUFBRUFRTUZBZ2IvMmdBSUFRRUFBUVVDOUcvdENXeFpudEMyeWR6L3hBQVVFUUVBQUFBQUFBQUFBQUFBQUFBQUFBQVEvOW9BQ0FFREFRRS9BWC8veEFBVUVRRUFBQUFBQUFBQUFBQUFBQUFBQUFBUS85b0FDQUVDQVFFL0FYLy94QUFrRUFBQ0FnRURBZ2NBQUFBQUFBQUFBQUFCQXdJUkJBQVNJUVZSRkNJeE1rRkRVdi9hQUFnQkFRQUdQd0phc04wN2hTM0xpeVNxa2NoQUFrUnpHeHZvOXJyWFQwNStXRVk3QTZXeVhVbUxFQmF2czlXSDNHaitxK05RZ1ptYjVPZEZzUEVuZENBTTlscHFoR2d2emNIa2QrZi94QUFaRUFFQkFRRUJBUUFBQUFBQUFBQUFBQUFCRVNFQU1ZSC8yZ0FJQVFFQUFUOGhUQitDZFRBeHJWSElCb0NrQUdkcHg5VkM4WGJMN3NuVDVqWjNiNy8vMmdBTUF3RUFBZ0FEQUFBQUVCSi8vOFFBRkJFQkFBQUFBQUFBQUFBQUFBQUFBQUFBRVAvYUFBZ0JBd0VCUHhCLy84UUFGQkVCQUFBQUFBQUFBQUFBQUFBQUFBQUFFUC9hQUFnQkFnRUJQeEIvLzhRQUdCQUJBQU1CQUFBQUFBQUFBQUFBQUFBQUFRQVJJVEgvMmdBSUFRRUFBVDhRdU9pbUhGZWROTno2ck9NcGNNQTdGWUdEQ1M5MXRTeEJTbkl4Zi8vWiIsCgkiaW1nLnBuZyI6ICJpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQmdBQUFBSUNBWUFBQURqb1Q5akFBQUFYVWxFUVZRb3o3VlJ3UTBBSVFnVHd5emRmNTR1NDcxSUdrSVVUYTR2aTBKYkhPTm5tQklBU3psSmkzcWNNOWNlZlZNaUN3UUhzUFJPNjZjRXN4dVZwSFVHWnZndXhURnlvOGNycDdjdXEvKzRYdEhybXZ6RmJZaGt3U3I5Qi9DRk9kYjVLVmFhQUFBQUFFbEZUa1N1UW1DQyIsCgkiaW1nLnRpZmYiOiAiU1VrcUFBZ0RBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFtSmliL0ppWW0veVltSnY4bUppYi9KaVltL3dBQUFBQW1KaWIvQUFBQUFDWW1KdjhtSmliL0ppWW0veVltSnY4QUFBQUFKaVltL3lZbUp2OG1KaWIvSmlZbS93QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFDWW1KdjhBQUFBQUFBQUFBQUFBQUFBbUppYi9BQUFBQUNZbUp2OEFBQUFBQUFBQUFBQUFBQUFBQUFBQUppWW0vd0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUNZbUp2OEFBQUFBQUFBQUFBQUFBQUFtSmliL0FBQUFBQ1ltSnY4QUFBQUFBQUFBQUFBQUFBQUFBQUFBSmlZbS93QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ1ltSnY4QUFBQUFBQUFBQUFBQUFBQW1KaWIvQUFBQUFDWW1KdjhtSmliL0ppWW0vd0FBQUFBQUFBQUFKaVltL3lZbUp2OG1KaWIvQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFDWW1KdjhBQUFBQUFBQUFBQUFBQUFBbUppYi9BQUFBQUNZbUp2OEFBQUFBQUFBQUFBQUFBQUFBQUFBQUppWW0vd0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUNZbUp2OEFBQUFBQUFBQUFBQUFBQUFtSmliL0FBQUFBQ1ltSnY4QUFBQUFBQUFBQUFBQUFBQUFBQUFBSmlZbS93QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ1ltSnY4QUFBQUFBQUFBQUFBQUFBQW1KaWIvQUFBQUFDWW1KdjhBQUFBQUFBQUFBQUFBQUFBQUFBQUFKaVltL3dBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBVEFBQUJBd0FCQUFBQUdBQUFBQUVCQXdBQkFBQUFDQUFBQUFJQkF3QUVBQUFBQWdRQUFBTUJBd0FCQUFBQUFRQUFBQVlCQXdBQkFBQUFBZ0FBQUEwQkFnQTdBQUFBRWdRQUFBNEJBZ0FFQUFBQVVFNUhBQkVCQkFBQkFBQUFDQUFBQUJJQkF3QUJBQUFBQVFBQUFCVUJBd0FCQUFBQUJBQUFBQllCQXdBQkFBQUFnQUFBQUJjQkJBQUJBQUFBQUFNQUFCb0JCUUFCQUFBQThnTUFBQnNCQlFBQkFBQUErZ01BQUJ3QkF3QUJBQUFBQVFBQUFCMEJBZ0FIQUFBQVRnUUFBQ2dCQXdBQkFBQUFBZ0FBQUZJQkF3QUJBQUFBQVFBQUFGTUJBd0FFQUFBQUNnUUFBQUFBQUFCSUFBQUFBUUFBQUVnQUFBQUJBQUFBQ0FBSUFBZ0FDQUFCQUFFQUFRQUJBRU02WEZWelpYSnpYR2R5WldkdlhGQnliMnBsWTNSelhGTlBJSFJsYzNSY1ltRnpaWEkyTkdsdFoxOWtaWFJsWTNSY2FXMW5MblJwWm1ZQUFFOTZZV1JxWlFBPSIKfQogCmZ1bmN0aW9uIHRlc3QoaW1ncywgQmFzZTY0KSB7Cglmb3IgKGNvbnN0IFtuYW1lLCBiYXNlNjRkYXRhXSBvZiBPYmplY3QuZW50cmllcyhpbWdzKSkgewoJCWNvbnN0IGhlYWRlciA9IFsuLi5hdG9iKGJhc2U2NGRhdGEpXQoJCQkuc2xpY2UoMCwgMTYpCgkJCS5tYXAoYyA9PiBjLmNoYXJDb2RlQXQoMCkpCgkJCS5maWx0ZXIoYyA9PiAzMiA8PSBjICYmIGMgPD0gMTI2KQoJCQkubWFwKGMgPT4gU3RyaW5nLmZyb21DaGFyQ29kZShjKSkKCQkJLmpvaW4oIiIpCgkJOwoJCWNvbnNvbGUubG9nKG5hbWUpOwoJCWNvbnNvbGUubG9nKCIgIGhlYWRlcjoiLCBoZWFkZXIpOwoJCWNvbnNvbGUubG9nKCIgIGRldGV0ZWQ6IiwgZGV0ZWN0X2ltZyhiYXNlNjRkYXRhLCBCYXNlNjQpKTsKCX0KfQpjb25zb2xlLmxvZygiPT09IEJyb2tlbiBCYXNlNjQgPT09Iik7CnRlc3QoaW1ncywgQmFzZTY0KTsKY29uc29sZS5sb2coKTsKY29uc29sZS5sb2coIj09PSBQcm9wZXIgQmFzZTY0ID09PSIpOwp0ZXN0KGltZ3MsIHtkZWNvZGU6YjY0ID0+IGF0b2IoYjY0KX0pOw==