ESPUI/src/dataControlsJS.h

133 lines
36 KiB
C++

const char JS_CONTROLS[] PROGMEM = R"=====(
const UI_INITIAL_GUI=200;const UI_RELOAD=201;const UPDATE_OFFSET=100;const UI_EXTEND_GUI=210;const UI_TITEL=0;const UI_PAD=1;const UPDATE_PAD=101;const UI_CPAD=2;const UPDATE_CPAD=102;const UI_BUTTON=3;const UPDATE_BUTTON=103;const UI_LABEL=4;const UPDATE_LABEL=104;const UI_SWITCHER=5;const UPDATE_SWITCHER=105;const UI_SLIDER=6;const UPDATE_SLIDER=106;const UI_NUMBER=7;const UPDATE_NUMBER=107;const UI_TEXT_INPUT=8;const UPDATE_TEXT_INPUT=108;const UI_GRAPH=9;const ADD_GRAPH_POINT=10;const CLEAR_GRAPH=109;const UI_TAB=11;const UPDATE_TAB=111;const UI_SELECT=12;const UPDATE_SELECT=112;const UI_OPTION=13;const UPDATE_OPTION=113;const UI_MIN=14;const UPDATE_MIN=114;const UI_MAX=15;const UPDATE_MAX=115;const UI_STEP=16;const UPDATE_STEP=116;const UI_GAUGE=17;const UPDATE_GAUGE=117;const UI_ACCEL=18;const UPDATE_ACCEL=118;const UI_SEPARATOR=19;const UPDATE_SEPARATOR=119;const UI_TIME=20;const UPDATE_TIME=120;const UI_FRAGMENT=21;const UP=0;const DOWN=1;const LEFT=2;const RIGHT=3;const CENTER=4;const C_TURQUOISE=0;const C_EMERALD=1;const C_PETERRIVER=2;const C_WETASPHALT=3;const C_SUNFLOWER=4;const C_CARROT=5;const C_ALIZARIN=6;const C_DARK=7;const C_NONE=255;var controlAssemblyArray=new Object();var FragmentAssemblyTimer=new Object();var graphData=new Array();var hasAccel=false;var sliderContinuous=false;function colorClass(colorId){colorId=Number(colorId);switch(colorId){case C_TURQUOISE:return"turquoise";case C_EMERALD:return"emerald";case C_PETERRIVER:return"peterriver";case C_WETASPHALT:return"wetasphalt";case C_SUNFLOWER:return"sunflower";case C_CARROT:return"carrot";case C_ALIZARIN:return"alizarin";case C_DARK:case C_NONE:return"dark";default:return"";}}
var websock;var websockConnected=false;var WebSocketTimer=null;function requestOrientationPermission(){}
function saveGraphData(){localStorage.setItem("espuigraphs",JSON.stringify(graphData));}
function restoreGraphData(id){var savedData=localStorage.getItem("espuigraphs",graphData);if(savedData!=null){savedData=JSON.parse(savedData);let idData=savedData[id];return Array.isArray(idData)?idData:[];}
return[];}
function restart(){$(document).add("*").off();$("#row").html("");conStatusError();start();}
function conStatusError(){if(true===websockConnected){websockConnected=false;websock.close();$("#conStatus").removeClass("color-green");$("#conStatus").addClass("color-red");$("#conStatus").html("Error / No Connection ↻");$("#conStatus").off();$("#conStatus").on({click:restart,});}}
function handleVisibilityChange(){if(!websockConnected&&!document.hidden){restart();}}
function start(){let location=window.location.hostname;let port=window.location.port;document.addEventListener("visibilitychange",handleVisibilityChange,false);if(port!=""||port!=80||port!=443){websock=new WebSocket("ws://"+location+"/ws");}else{websock=new WebSocket("ws://"+location+"/ws");}
if(null===WebSocketTimer){WebSocketTimer=setInterval(function(){if(websock.readyState===3){restart();}},5000);}
websock.onopen=function(evt){console.log("websock open");$("#conStatus").addClass("color-green");$("#conStatus").text("Connected");websockConnected=true;};websock.onclose=function(evt){console.log("websock close");conStatusError();};websock.onerror=function(evt){console.log("websock Error");restart();};var handleEvent=function(evt){try{var data=JSON.parse(evt.data);}
catch(Event){console.error(Event);websock.send("uiok:"+0);return;}
var e=document.body;var center="";switch(data.type){case UI_INITIAL_GUI:$("#row").html("");$("#tabsnav").html("");$("#tabscontent").html("");if(data.sliderContinuous){sliderContinuous=data.sliderContinuous;}
data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});if(data.totalcontrols>(data.controls.length-1)){websock.send("uiok:"+(data.controls.length-1));}
break;case UI_EXTEND_GUI:data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});if(data.totalcontrols>data.startindex+(data.controls.length-1)){websock.send("uiok:"+(data.startindex+(data.controls.length-1)));}
break;case UI_RELOAD:window.location.reload();break;case UI_TITEL:document.title=data.label;$("#mainHeader").html(data.label);break;case UI_LABEL:case UI_NUMBER:case UI_TEXT_INPUT:case UI_SELECT:case UI_GAUGE:case UI_SEPARATOR:if(data.visible)addToHTML(data);break;case UI_BUTTON:if(data.visible){addToHTML(data);$("#btn"+data.id).on({touchstart:function(e){e.preventDefault();buttonclick(data.id,true);},touchend:function(e){e.preventDefault();buttonclick(data.id,false);},});}
break;case UI_SWITCHER:if(data.visible){addToHTML(data);switcher(data.id,data.value);}
break;case UI_CPAD:case UI_PAD:if(data.visible){addToHTML(data);$("#pf"+data.id).on({touchstart:function(e){e.preventDefault();padclick(UP,data.id,true);},touchend:function(e){e.preventDefault();padclick(UP,data.id,false);},});$("#pl"+data.id).on({touchstart:function(e){e.preventDefault();padclick(LEFT,data.id,true);},touchend:function(e){e.preventDefault();padclick(LEFT,data.id,false);},});$("#pr"+data.id).on({touchstart:function(e){e.preventDefault();padclick(RIGHT,data.id,true);},touchend:function(e){e.preventDefault();padclick(RIGHT,data.id,false);},});$("#pb"+data.id).on({touchstart:function(e){e.preventDefault();padclick(DOWN,data.id,true);},touchend:function(e){e.preventDefault();padclick(DOWN,data.id,false);},});$("#pc"+data.id).on({touchstart:function(e){e.preventDefault();padclick(CENTER,data.id,true);},touchend:function(e){e.preventDefault();padclick(CENTER,data.id,false);},});}
break;case UI_SLIDER:if(data.visible){addToHTML(data);rangeSlider(!sliderContinuous);}
break;case UI_TAB:if(data.visible){$("#tabsnav").append("<li><a onmouseup='tabclick("+data.id+")' href='#tab"+data.id+"'>"+data.value+"</a></li>");$("#tabscontent").append("<div id='tab"+data.id+"'></div>");tabs=$(".tabscontent").tabbedContent({loop:true}).data("api");$("a").filter(function(){return $(this).attr("href")==="#click-to-switch";}).on("click",function(e){var tab=prompt("Tab to switch to (number or id)?");if(!tabs.switchTab(tab)){alert("That tab does not exist :\\");}
e.preventDefault();});}
break;case UI_OPTION:if(data.parentControl){var parent=$("#select"+data.parentControl);parent.append("<option id='option"+
data.id+
"' value='"+
data.value+
"' "+
data.selected+
">"+
data.label+
"</option>");}
break;case UI_MIN:if(data.parentControl){if($('#sl'+data.parentControl).length){$('#sl'+data.parentControl).attr("min",data.value);}else if($('#num'+data.parentControl).length){$('#num'+data.parentControl).attr("min",data.value);}}
break;case UI_MAX:if(data.parentControl){if($('#sl'+data.parentControl).length){$('#sl'+data.parentControl).attr("max",data.value);}else if($('#text'+data.parentControl).length){$('#text'+data.parentControl).attr("maxlength",data.value);}else if($('#num'+data.parentControl).length){$('#num'+data.parentControl).attr("max",data.value);}}
break;case UI_STEP:if(data.parentControl){if($('#sl'+data.parentControl).length){$('#sl'+data.parentControl).attr("step",data.value);}else if($('#num'+data.parentControl).length){$('#num'+data.parentControl).attr("step",data.value);}}
break;case UI_GRAPH:if(data.visible){addToHTML(data);graphData[data.id]=restoreGraphData(data.id);renderGraphSvg(graphData[data.id],"graph"+data.id);}
break;case ADD_GRAPH_POINT:var ts=new Date().getTime();graphData[data.id].push({x:ts,y:data.value});saveGraphData();renderGraphSvg(graphData[data.id],"graph"+data.id);break;case CLEAR_GRAPH:graphData[data.id]=[];saveGraphData();renderGraphSvg(graphData[data.id],"graph"+data.id);break;case UI_ACCEL:if(hasAccel)break;hasAccel=true;if(data.visible){addToHTML(data);requestOrientationPermission();}
break;case UPDATE_LABEL:$("#l"+data.id).html(data.value);if(data.hasOwnProperty('elementStyle')){$("#l"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_SWITCHER:switcher(data.id,data.value=="0"?0:1);if(data.hasOwnProperty('elementStyle')){$("#sl"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_SLIDER:$("#sl"+data.id).attr("value",data.value)
slider_move($("#sl"+data.id).parent().parent(),data.value,"100",false);if(data.hasOwnProperty('elementStyle')){$("#sl"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_NUMBER:$("#num"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#num"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_TEXT_INPUT:$("#text"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#text"+data.id).attr("style",data.elementStyle);}
if(data.hasOwnProperty('inputType')){$("#text"+data.id).attr("type",data.inputType);}
break;case UPDATE_SELECT:$("#select"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#select"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_BUTTON:$("#btn"+data.id).val(data.value);$("#btn"+data.id).text(data.value);if(data.hasOwnProperty('elementStyle')){$("#btn"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_PAD:case UPDATE_CPAD:break;case UPDATE_GAUGE:$("#gauge"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#gauge"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_ACCEL:break;case UPDATE_TIME:var rv=new Date().toISOString();websock.send("time:"+rv+":"+data.id);break;case UI_FRAGMENT:let FragmentLen=data.length;let FragementOffset=data.offset;let NextFragmentOffset=FragementOffset+FragmentLen;let Total=data.total;let Arrived=(FragmentLen+FragementOffset);let FragmentFinal=Total===Arrived;if(!data.hasOwnProperty('control'))
{console.error("UI_FRAGMENT:Missing control record, skipping control");break;}
let control=data.control;StopFragmentAssemblyTimer(data.control.id);if(0===FragementOffset)
{controlAssemblyArray[control.id]=data;controlAssemblyArray[control.id].offset=NextFragmentOffset;StartFragmentAssemblyTimer(control.id);let TotalRequest=JSON.stringify({'id':control.id,'offset':NextFragmentOffset});websock.send("uifragmentok:"+0+": "+TotalRequest+":");break;}
if("undefined"===typeof controlAssemblyArray[control.id])
{console.error("Missing first fragment for control: "+control.id);StartFragmentAssemblyTimer(control.id);let TotalRequest=JSON.stringify({'id':control.id,'offset':0});websock.send("uifragmentok:"+0+": "+TotalRequest+":");break;}
if(FragementOffset!==controlAssemblyArray[control.id].offset)
{console.error("Wrong next fragment. Expected: "+controlAssemblyArray[control.id].offset+" Got: "+FragementOffset);StartFragmentAssemblyTimer(control.id);let TotalRequest=JSON.stringify({'id':control.id,'offset':controlAssemblyArray[control.id].length+controlAssemblyArray[control.id].offset});websock.send("uifragmentok:"+0+": "+TotalRequest+":");break;}
controlAssemblyArray[control.id].control.value+=control.value;controlAssemblyArray[control.id].offset=NextFragmentOffset;if(true===FragmentFinal)
{var fauxEvent={data:JSON.stringify(controlAssemblyArray[control.id].control),};handleEvent(fauxEvent);controlAssemblyArray[control.id]=null;}
else
{StartFragmentAssemblyTimer(control.id);let TotalRequest=JSON.stringify({'id':control.id,'offset':NextFragmentOffset});websock.send("uifragmentok:"+0+": "+TotalRequest+":");}
break;default:console.error("Unknown type or event");break;}
if(data.type>=UI_TITEL&&data.type<UPDATE_OFFSET){processEnabled(data);}
if(data.type>=UPDATE_OFFSET&&data.type<UI_INITIAL_GUI){var element=$("#id"+data.id);if(data.hasOwnProperty('panelStyle')){$("#id"+data.id).attr("style",data.panelStyle);}
if(data.hasOwnProperty('visible')){if(data['visible'])
$("#id"+data.id).show();else
$("#id"+data.id).hide();}
if(data.type==UPDATE_SLIDER){element.removeClass("slider-turquoise slider-emerald slider-peterriver slider-wetasphalt slider-sunflower slider-carrot slider-alizarin");element.addClass("slider-"+colorClass(data.color));}else{element.removeClass("turquoise emerald peterriver wetasphalt sunflower carrot alizarin");element.addClass(colorClass(data.color));}
processEnabled(data);}
$(".range-slider__range").each(function(){$(this)[0].value=$(this).attr("value");$(this).next().html($(this).attr("value"));});};websock.onmessage=handleEvent;}
function StartFragmentAssemblyTimer(Id)
{StopFragmentAssemblyTimer(Id);FragmentAssemblyTimer[Id]=setInterval(function(_Id)
{if("undefined"!==typeof controlAssemblyArray[_Id])
{if(null!==controlAssemblyArray[_Id])
{let TotalRequest=JSON.stringify({'id':controlAssemblyArray[_Id].control.id,'offset':controlAssemblyArray[_Id].offset});websock.send("uifragmentok:"+0+": "+TotalRequest+":");}}},1000,Id);}
function StopFragmentAssemblyTimer(Id)
{if("undefined"!==typeof FragmentAssemblyTimer[Id])
{if(FragmentAssemblyTimer[Id])
{clearInterval(FragmentAssemblyTimer[Id]);}}}
function sliderchange(number){var val=$("#sl"+number).val();websock.send("slvalue:"+val+":"+number);$(".range-slider__range").each(function(){$(this).attr("value",$(this)[0].value);});}
function numberchange(number){var val=$("#num"+number).val();websock.send("nvalue:"+val+":"+number);}
function textchange(number){var val=$("#text"+number).val();websock.send("tvalue:"+val+":"+number);}
function tabclick(number){var val=$("#tab"+number).val();websock.send("tabvalue:"+val+":"+number);}
function selectchange(number){var val=$("#select"+number).val();websock.send("svalue:"+val+":"+number);}
function buttonclick(number,isdown){if(isdown)websock.send("bdown:"+number);else websock.send("bup:"+number);}
function padclick(type,number,isdown){if($("#id"+number+" nav").hasClass("disabled")){return;}
switch(type){case CENTER:if(isdown)websock.send("pcdown:"+number);else websock.send("pcup:"+number);break;case UP:if(isdown)websock.send("pfdown:"+number);else websock.send("pfup:"+number);break;case DOWN:if(isdown)websock.send("pbdown:"+number);else websock.send("pbup:"+number);break;case LEFT:if(isdown)websock.send("pldown:"+number);else websock.send("plup:"+number);break;case RIGHT:if(isdown)websock.send("prdown:"+number);else websock.send("prup:"+number);break;}}
function switcher(number,state){if(state==null){if(!$("#sl"+number).hasClass("checked")){websock.send("sactive:"+number);$("#sl"+number).addClass("checked");}else{websock.send("sinactive:"+number);$("#sl"+number).removeClass("checked");}}else if(state==1){$("#sl"+number).addClass("checked");$("#sl"+number).prop("checked",true);}else if(state==0){$("#sl"+number).removeClass("checked");$("#sl"+number).prop("checked",false);}}
var rangeSlider=function(isDiscrete){var range=$(".range-slider__range");var slidercb=function(){sliderchange($(this).attr("id").replace(/^\D+/g,""));};range.on({input:function(){$(this).next().html(this.value)}});range.each(function(){$(this).next().html(this.value);if($(this).attr("callbackSet")!="true"){if(!isDiscrete){$(this).on({input:slidercb});}else{$(this).on({change:slidercb});}
$(this).attr("callbackSet","true");}});};var addToHTML=function(data){panelStyle=data.hasOwnProperty('panelStyle')?" style='"+data.panelStyle+"' ":"";panelwide=data.hasOwnProperty('wide')?"wide":"";if(!data.hasOwnProperty('parentControl')||$("#tab"+data.parentControl).length>0){var parent=data.hasOwnProperty('parentControl')?$("#tab"+data.parentControl):$("#row");var html="";switch(data.type){case UI_LABEL:case UI_BUTTON:case UI_SWITCHER:case UI_CPAD:case UI_PAD:case UI_SLIDER:case UI_NUMBER:case UI_TEXT_INPUT:case UI_SELECT:case UI_GRAPH:case UI_GAUGE:case UI_ACCEL:html="<div id='id"+data.id+"' "+panelStyle+" class='two columns "+panelwide+" card tcenter "+
colorClass(data.color)+"'><h5>"+data.label+"</h5><hr/>"+
elementHTML(data)+
"</div>";break;case UI_SEPARATOR:html="<div id='id"+data.id+"' "+panelStyle+" class='sectionbreak columns'>"+
"<h5>"+data.label+"</h5><hr/></div>";break;case UI_TIME:break;}
parent.append(html);}else{var parent=$("#id"+data.parentControl);parent.append(elementHTML(data));}}
var elementHTML=function(data){var id=data.id
var elementStyle=data.hasOwnProperty('elementStyle')?" style='"+data.elementStyle+"' ":"";var inputType=data.hasOwnProperty('inputType')?" type='"+data.inputType+"' ":"";switch(data.type){case UI_LABEL:return"<span id='l"+id+"' "+elementStyle+
" class='label label-wrap'>"+data.value+"</span>";case UI_BUTTON:return"<button id='btn"+id+"' "+elementStyle+
" onmousedown='buttonclick("+id+", true)'"+
" onmouseup='buttonclick("+id+", false)'>"+
data.value+"</button>";case UI_SWITCHER:return"<label id='sl"+id+"' "+elementStyle+
" class='switch "+(data.value=="1"?"checked":"")+
(data.hasOwnProperty('vertical')?" vert-switcher ":"")+
"'>"+
"<div class='in'>"+
"<input type='checkbox' id='s"+id+"' onClick='switcher("+id+",null)' "+
(data.value=="1"?"checked":"")+"/></div></label>";case UI_CPAD:case UI_PAD:return"<nav class='control'><ul>"+
"<li><a onmousedown='padclick(UP, "+id+", true)' "+
"onmouseup='padclick(UP, "+id+", false)' id='pf"+id+"'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(RIGHT, "+id+", true)' "+
"onmouseup='padclick(RIGHT, "+id+", false)' id='pr"+id+"'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(LEFT, "+id+", true)' "+
"onmouseup='padclick(LEFT, "+id+", false)' id='pl"+id+"'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(DOWN, "+id+", true)' "+
"onmouseup='padclick(DOWN, "+id+", false)' id='pb"+id+"'>&#9650;</a></li>"+
"</ul>"+
(data.type==UI_CPAD?"<a class='confirm' onmousedown='padclick(CENTER,"+id+", true)' "+
"onmouseup='padclick(CENTER, "+id+", false)' id='pc"+id+"'>OK</a>":"")+
"</nav>";case UI_SLIDER:return"<div class='range-slider "+
(data.hasOwnProperty('vertical')?" vert-slider ":"")+
"'>"+
"<input id='sl"+id+"' type='range' min='0' max='100' value='"+data.value+"' "+
elementStyle+" class='range-slider__range'><span class='range-slider__value'>"+
data.value+"</span></div>";case UI_NUMBER:return"<input style='color:black; "+data.elementStyle+"' id='num"+id+
"' type='number' value='"+data.value+"' onchange='numberchange("+id+")' />";case UI_TEXT_INPUT:return"<input "+inputType+"style='color:black; "+data.elementStyle+"' id='text"+id+
"' value='"+data.value+"' onchange='textchange("+id+")' />";case UI_SELECT:return"<select style='color:black; "+data.elementStyle+"' id='select"+id+
"' onchange='selectchange("+id+")' />";case UI_GRAPH:return"<figure id='graph"+id+"'><figcaption>"+data.label+"</figcaption></figure>";case UI_GAUGE:return"WILL BE A GAUGE <input style='color:black;' id='gauge"+id+
"' type='number' value='"+data.value+"' onchange='numberchange("+id+")' />";case UI_ACCEL:return"ACCEL // Not implemented fully!<div class='accelerometer' id='accel"+id+
"' ><div class='ball"+id+"'></div><pre class='accelerometeroutput"+id+"'></pre>";default:return"";}}
var processEnabled=function(data){switch(data.type){case UI_SWITCHER:case UPDATE_SWITCHER:if(data.enabled){$("#sl"+data.id).removeClass('disabled');$("#s"+data.id).prop("disabled",false);}else{$("#sl"+data.id).addClass('disabled');$("#s"+data.id).prop("disabled",true);}
break;case UI_SLIDER:case UPDATE_SLIDER:$("#sl"+data.id).prop("disabled",!data.enabled);break;case UI_NUMBER:case UPDATE_NUMBER:$("#num"+data.id).prop("disabled",!data.enabled);break;case UI_TEXT_INPUT:case UPDATE_TEXT_INPUT:$("#text"+data.id).prop("disabled",!data.enabled);break;case UI_SELECT:case UPDATE_SELECT:$("#select"+data.id).prop("disabled",!data.enabled);break;case UI_BUTTON:case UPDATE_BUTTON:$("#btn"+data.id).prop("disabled",!data.enabled);break;case UI_PAD:case UI_CPAD:case UPDATE_PAD:case UPDATE_CPAD:if(data.enabled){$("#id"+data.id+" nav").removeClass('disabled');}else{$("#id"+data.id+" nav").addClass('disabled');}
break;}}
)=====";
const uint8_t JS_CONTROLS_GZIP[4803] PROGMEM = { 31,139,8,0,75,240,254,100,2,255,213,60,107,119,218,200,146,223,253,43,100,101,78,128,53,198,144,76,114,51,96,57,135,96,146,176,215,54,94,27,223,204,217,76,214,71,160,198,232,90,72,186,146,240,99,25,254,251,86,87,63,212,173,7,96,123,178,123,246,203,4,85,87,87,87,215,163,187,170,186,60,147,192,143,19,227,106,112,61,56,27,140,6,221,147,235,47,87,3,235,77,179,217,153,136,129,139,254,201,176,123,12,176,150,128,157,31,119,71,253,235,225,231,207,151,253,145,213,82,113,251,191,143,250,103,199,140,70,75,129,143,6,163,254,137,165,0,206,129,98,134,30,130,210,69,6,215,61,10,121,163,35,245,24,214,155,20,235,211,213,104,52,60,179,222,234,120,28,218,106,190,77,49,79,186,159,128,137,95,117,68,6,108,53,127,77,241,46,191,13,70,189,175,253,11,235,157,142,42,225,173,230,59,5,251,100,112,12,176,247,25,92,6,109,53,223,167,152,103,87,167,159,0,246,55,29,147,67,91,205,191,41,226,2,57,130,66,206,175,70,214,7,29,91,25,105,53,63,164,51,190,92,116,207,191,90,191,113,64,247,248,152,65,174,207,135,131,51,138,202,7,122,39,253,238,5,71,110,53,127,83,86,236,126,178,90,25,133,48,152,162,144,203,254,73,191,7,212,50,58,17,224,150,162,149,225,249,104,64,229,159,81,139,0,183,20,181,156,14,0,144,209,10,194,90,138,78,78,187,191,91,173,140,62,16,214,82,85,49,234,159,91,173,172,38,16,216,82,244,240,165,123,245,165,111,181,50,122,224,208,150,162,134,110,175,71,109,35,163,2,14,109,125,80,5,115,222,189,232,142,134,160,198,223,178,178,145,35,45,85,220,131,211,62,120,84,70,222,20,216,122,163,120,201,231,139,238,151,211,62,40,240,77,170,26,233,69,199,195,111,103,210,135,78,250,159,71,210,87,46,6,95,190,142,164,71,244,128,0,24,152,16,102,239,122,116,117,241,31,87,195,193,101,95,146,234,93,247,79,251,23,221,147,212,39,123,215,231,125,152,117,49,248,7,76,125,35,129,223,250,163,238,229,249,215,238,137,66,254,250,242,234,236,243,201,240,155,182,70,175,123,113,49,28,73,15,234,93,119,79,6,255,217,189,0,181,190,151,160,227,238,197,223,165,55,244,174,207,134,103,32,147,119,239,58,119,118,100,0,48,137,2,175,27,199,100,62,246,30,187,81,100,63,90,62,185,55,134,227,127,146,73,82,173,33,214,231,200,190,153,19,63,17,104,35,119,78,162,60,218,77,100,135,179,99,59,177,113,8,105,241,145,153,29,119,39,19,226,89,83,219,139,9,130,98,207,117,72,212,131,245,93,127,17,44,98,62,52,93,248,147,196,13,124,224,204,11,162,158,103,199,113,21,127,14,156,218,146,255,176,206,22,243,49,137,36,188,19,223,187,201,100,166,224,217,49,81,21,208,142,72,178,136,124,19,254,243,175,69,224,198,196,236,112,20,174,15,129,64,96,95,182,231,200,225,84,57,2,35,36,9,137,34,247,142,68,18,41,85,150,64,186,39,137,29,135,51,219,75,36,146,84,158,192,137,23,254,212,11,238,21,58,76,151,98,124,98,71,81,144,206,23,122,21,195,182,231,254,183,29,185,190,68,160,90,110,243,223,84,197,2,209,177,163,91,179,227,144,169,189,240,18,1,52,59,171,213,14,213,194,61,25,199,193,228,182,163,252,6,149,248,160,83,226,40,202,250,70,198,151,48,68,18,174,249,133,231,165,154,138,200,191,22,36,78,134,145,11,38,98,83,208,57,137,230,110,28,195,175,106,109,185,218,145,152,177,125,71,190,8,35,129,33,47,152,216,222,101,18,128,121,145,70,76,146,65,66,230,85,147,196,225,194,69,91,138,205,250,191,95,14,207,26,113,2,59,189,113,167,143,85,105,98,181,90,71,33,28,193,250,65,164,208,118,193,10,208,202,96,69,7,77,82,91,235,166,112,173,148,120,199,157,86,229,212,93,220,111,109,153,210,66,166,66,59,138,73,138,85,235,120,36,49,92,134,32,161,223,93,231,71,135,9,157,57,68,195,141,153,99,48,204,218,71,246,111,251,251,15,216,15,67,196,159,218,214,236,8,92,108,249,75,213,9,38,11,234,135,181,134,237,56,85,243,223,204,90,35,152,78,193,199,126,169,154,175,162,224,30,190,103,201,220,171,154,102,141,186,251,37,104,99,17,247,193,142,34,192,225,100,84,218,89,156,37,108,59,137,22,196,178,172,172,49,212,150,37,230,193,193,141,137,23,128,56,24,43,146,46,48,20,145,121,112,71,152,35,155,232,161,251,55,17,33,190,153,71,133,77,105,120,17,113,10,176,216,14,145,99,227,192,56,11,12,206,17,221,208,235,87,31,222,191,125,215,41,152,149,202,73,131,250,213,229,196,115,39,183,109,46,230,250,170,70,93,67,74,104,102,251,142,71,254,225,198,238,216,245,220,228,177,7,128,27,194,36,181,155,149,200,235,215,187,66,67,141,153,235,56,196,175,45,165,250,52,178,66,165,212,100,168,97,82,160,117,239,250,78,112,223,16,223,141,89,16,39,190,61,39,104,88,97,16,37,57,12,10,236,200,37,65,124,253,59,248,113,226,198,9,241,225,124,52,239,36,223,19,228,219,172,23,239,167,142,170,68,171,167,36,119,45,211,252,243,79,246,235,67,83,252,250,245,215,183,210,8,240,128,151,135,66,213,188,143,219,7,7,230,158,96,108,207,60,184,7,241,118,86,4,200,62,117,206,14,112,65,29,14,140,80,63,118,106,203,204,49,68,79,12,31,142,227,59,219,171,10,209,50,213,8,163,140,136,237,60,82,109,83,147,126,171,107,163,254,174,217,108,210,245,4,114,224,7,33,241,45,73,137,220,37,244,202,241,227,192,35,32,243,27,96,153,97,26,20,111,11,251,45,179,243,132,60,192,254,165,217,0,70,206,183,168,23,118,86,157,148,53,116,175,109,120,67,196,34,255,87,169,17,10,219,134,26,78,6,106,138,224,248,133,78,237,8,205,45,67,38,137,30,241,228,117,50,7,37,12,54,28,60,39,87,59,160,113,184,174,113,118,186,46,242,196,129,146,213,152,248,112,208,45,220,224,182,109,238,53,107,252,40,237,176,203,139,88,210,246,199,129,243,200,2,26,66,45,2,12,88,4,5,116,205,70,242,24,18,30,22,232,41,88,187,224,228,164,160,196,30,199,190,125,87,4,166,33,19,44,162,14,129,197,225,50,217,152,6,238,140,108,148,83,136,7,251,65,56,143,198,226,198,52,136,250,54,48,79,60,66,183,103,29,161,72,225,10,127,96,34,95,82,244,118,230,110,228,200,181,250,170,163,168,167,42,103,129,228,83,86,147,32,177,61,177,222,81,85,95,222,35,254,77,50,219,111,213,164,195,235,138,40,69,135,141,140,193,231,110,59,66,212,105,162,218,254,191,221,33,147,59,181,97,56,67,201,195,222,179,118,188,205,252,188,12,88,98,223,206,30,222,17,241,2,219,1,143,210,177,49,133,111,75,195,78,220,196,35,204,106,60,123,76,60,52,195,185,237,250,95,225,104,131,224,145,91,97,138,144,165,135,137,119,91,124,177,44,88,126,166,105,174,4,177,44,83,126,98,186,166,12,242,52,171,45,164,140,87,140,71,106,112,246,141,130,175,163,211,147,42,115,114,157,9,86,38,200,77,90,102,103,209,205,141,19,223,220,67,52,8,226,240,134,78,130,197,100,134,178,111,167,103,77,109,73,26,97,68,168,218,143,89,112,75,69,185,72,18,122,86,194,141,94,229,36,234,244,40,5,165,212,145,10,232,244,57,52,248,253,184,194,240,32,163,94,81,174,216,188,59,118,34,193,197,44,200,50,116,219,67,6,51,100,105,5,70,202,157,254,222,74,120,225,244,217,178,11,109,135,109,250,234,188,254,92,217,21,209,80,101,135,44,122,47,103,145,166,225,47,103,82,163,146,99,51,122,57,155,88,32,120,57,159,58,153,28,163,227,151,51,74,107,28,47,231,83,163,146,99,115,242,114,54,89,137,229,229,140,102,232,172,245,110,44,48,110,118,190,136,198,209,151,120,175,87,119,115,113,64,142,236,168,251,41,79,83,15,60,236,48,196,27,232,208,115,143,14,109,35,240,231,64,137,44,66,171,2,56,108,31,82,162,123,102,173,98,204,34,50,181,42,148,130,2,175,28,241,15,60,102,246,204,195,3,251,232,240,0,72,22,70,52,114,77,199,189,131,92,22,151,210,136,29,30,192,8,157,75,231,89,64,160,161,19,128,175,49,113,122,236,187,10,9,126,16,182,169,154,86,53,12,254,170,166,29,186,108,101,27,176,167,174,7,193,154,26,187,243,84,249,151,106,50,115,99,224,39,73,32,141,161,27,51,107,16,193,67,24,77,247,189,159,4,251,236,44,53,225,194,167,198,100,34,220,172,171,6,64,227,9,96,199,10,163,96,30,66,188,61,178,199,70,18,24,108,34,253,5,89,6,45,35,25,144,71,130,77,126,100,113,220,46,221,79,131,33,193,140,42,124,66,76,96,123,36,162,36,102,118,66,105,26,78,64,98,195,15,18,131,60,64,178,101,180,255,248,3,51,151,2,155,43,48,41,86,156,149,234,135,240,24,102,244,88,36,193,216,102,32,42,222,87,49,196,60,147,132,235,64,71,237,176,207,84,105,65,136,201,37,213,27,251,105,238,237,8,221,237,152,21,3,77,192,170,8,40,179,8,58,32,32,108,49,66,177,143,4,12,131,10,0,28,30,48,154,71,102,126,71,167,131,210,237,0,248,151,106,229,85,236,85,138,182,192,227,38,106,250,229,56,204,8,230,174,111,234,23,38,77,46,13,78,31,84,185,121,129,82,164,178,21,114,251,236,254,254,243,247,105,63,172,217,39,77,29,55,175,80,142,37,215,96,232,63,91,162,185,189,228,142,215,81,255,252,167,139,52,78,72,248,147,119,90,176,68,118,171,248,26,180,249,34,145,69,200,239,220,117,127,88,185,234,166,184,71,33,29,134,100,36,194,129,203,187,155,106,126,110,221,68,88,122,245,234,190,155,121,192,106,227,153,25,99,165,6,200,144,106,141,86,74,105,177,165,90,196,88,35,92,196,179,234,242,161,157,196,245,199,118,186,121,56,243,50,149,222,231,48,170,176,169,60,167,181,11,228,243,253,199,95,188,158,120,147,162,218,18,79,23,53,54,46,95,50,176,66,179,57,44,88,91,27,207,28,164,202,75,41,214,37,212,64,57,205,242,184,125,137,165,129,161,225,189,127,30,5,33,92,81,143,213,10,207,145,47,147,71,143,84,106,44,168,80,9,9,123,133,97,110,176,234,140,98,150,100,138,179,38,131,129,219,185,105,126,108,182,91,79,99,45,126,49,111,44,64,43,161,133,172,105,142,185,195,130,179,107,90,149,174,230,102,49,231,174,166,63,148,169,117,179,213,108,154,74,173,244,127,111,147,60,109,167,180,224,32,82,136,209,210,231,115,173,66,167,244,28,182,148,242,1,198,146,112,237,252,69,188,101,72,109,102,174,140,184,235,135,139,100,244,24,174,167,76,235,131,156,176,156,80,98,110,172,60,146,11,205,94,186,225,28,177,231,232,131,151,89,242,85,148,44,103,121,12,172,73,63,151,121,157,212,115,56,79,139,29,105,255,73,59,143,198,170,81,116,201,27,123,113,67,254,34,217,103,105,61,103,3,236,190,40,112,145,193,105,31,175,213,232,78,189,86,147,96,112,57,188,196,194,102,53,91,237,78,224,190,109,155,123,209,221,158,217,46,189,159,68,203,66,155,62,14,137,247,249,19,226,243,82,33,70,46,29,49,134,204,15,167,211,152,36,108,60,192,223,56,126,6,138,23,243,57,74,102,202,158,66,30,167,140,104,101,213,74,139,172,8,236,226,171,184,99,85,21,236,189,12,165,90,71,229,246,179,235,3,25,70,204,178,248,124,204,193,10,53,199,107,173,160,180,157,204,155,129,169,202,227,148,94,174,254,141,232,108,48,34,50,9,34,167,110,196,183,110,24,42,3,166,144,232,106,135,50,197,161,150,90,214,237,92,38,65,88,216,251,160,85,127,81,59,192,118,19,118,145,221,48,178,154,235,176,248,158,206,252,129,43,118,54,97,113,141,89,121,109,1,147,118,148,20,115,169,50,40,21,119,193,66,18,43,83,91,95,86,92,167,210,78,103,212,43,108,201,74,59,191,230,42,255,64,51,229,8,236,161,6,44,23,146,74,117,57,106,203,169,196,65,90,230,2,34,180,169,235,19,199,4,185,209,3,56,152,26,155,196,144,87,189,80,247,212,141,32,17,23,92,24,211,64,246,182,80,78,84,65,252,116,121,53,255,10,241,100,12,105,215,178,182,52,145,188,136,190,69,1,8,200,7,45,74,249,52,140,254,67,136,169,190,34,157,77,148,247,76,227,75,144,208,9,57,183,254,233,50,221,200,34,59,241,182,221,202,139,53,180,113,29,241,155,21,89,44,237,243,37,222,158,118,104,104,199,40,104,125,139,247,179,109,185,94,243,192,182,241,56,195,222,160,213,14,77,176,119,150,255,159,206,38,113,171,139,86,169,236,29,227,223,250,193,189,111,208,147,138,150,12,177,206,167,251,172,124,106,62,178,196,67,222,235,215,18,120,168,245,243,214,150,97,20,76,72,28,247,125,27,50,71,167,42,222,198,51,116,212,57,26,49,237,25,155,149,13,197,91,42,141,105,92,71,9,29,202,130,161,208,246,137,167,133,66,234,180,130,56,40,157,176,46,230,230,217,48,165,201,81,190,75,24,28,225,185,117,226,89,112,15,81,16,154,76,110,112,6,217,90,53,43,24,203,210,178,191,218,146,111,93,239,54,98,153,222,190,236,250,227,61,135,251,188,203,79,124,166,45,125,2,146,246,239,9,136,236,214,19,0,214,158,39,190,100,55,30,221,5,17,221,56,58,27,244,156,149,45,141,60,126,128,239,154,104,147,41,220,66,202,187,96,90,225,86,101,83,242,199,25,91,199,81,41,31,59,37,54,73,235,252,248,192,177,207,147,231,107,252,50,107,13,66,223,240,149,250,61,47,220,127,111,254,224,85,1,189,146,207,210,113,154,127,48,40,189,148,170,188,184,81,136,201,10,232,74,231,202,28,216,131,203,199,82,142,39,181,163,109,205,129,51,112,106,244,64,42,139,232,104,31,105,225,200,247,1,156,106,133,173,70,215,72,82,143,101,118,215,199,50,48,229,7,155,67,207,201,178,91,157,99,61,233,88,204,83,104,108,125,145,34,246,11,111,198,213,106,85,111,53,155,205,250,192,169,233,26,89,35,241,114,233,149,170,130,205,89,55,60,241,136,29,73,109,149,99,82,150,149,150,60,180,108,214,39,199,95,134,216,169,10,68,44,81,196,225,112,204,54,179,130,138,61,180,89,144,17,252,139,169,27,199,238,60,217,125,244,226,85,214,167,248,163,146,228,156,45,179,134,115,44,244,172,99,221,47,227,92,89,133,22,8,214,172,193,202,42,235,22,73,182,89,68,188,108,22,46,65,223,34,215,174,96,143,183,88,131,85,90,214,41,154,151,98,214,42,123,139,133,212,70,18,54,92,119,99,7,98,8,188,22,249,79,157,236,152,194,20,106,248,76,145,65,89,132,197,203,201,215,109,234,65,245,252,130,226,102,101,35,16,204,243,254,54,59,230,119,141,227,198,120,236,195,169,187,148,125,118,188,139,78,105,160,99,143,231,237,178,45,132,147,205,123,8,39,218,38,180,170,73,57,225,233,22,132,167,101,132,105,111,66,57,233,45,228,30,142,203,72,211,54,146,114,210,222,22,164,189,50,210,216,249,81,78,59,218,130,118,84,64,91,59,247,68,73,159,91,76,76,187,101,209,96,98,214,55,203,154,223,105,89,38,123,10,166,166,3,4,38,183,204,114,50,126,98,195,42,119,68,63,12,53,34,74,211,172,32,162,247,13,11,74,144,230,108,162,165,247,154,167,228,228,115,31,223,82,43,45,203,175,99,35,139,3,209,81,152,142,139,246,147,12,237,102,158,118,9,91,27,200,139,174,20,214,235,170,244,151,164,13,183,110,124,236,198,19,240,85,222,238,128,72,86,233,117,163,252,221,205,100,108,41,215,142,118,247,233,119,16,156,24,116,3,161,103,79,72,245,224,191,254,56,222,59,184,169,155,24,152,177,158,23,236,229,193,162,121,187,224,34,83,3,60,10,225,55,216,106,197,59,102,74,111,192,146,137,29,60,200,84,6,39,182,231,141,237,201,237,37,129,108,108,215,50,169,86,76,102,175,170,120,196,164,148,91,33,136,149,176,55,21,133,201,66,195,217,41,95,183,206,87,237,172,86,162,65,90,62,4,166,114,198,104,122,153,166,80,214,198,156,236,163,105,96,246,69,123,54,50,249,215,30,109,219,104,155,102,7,65,247,192,102,49,57,58,66,9,209,127,17,191,180,190,170,189,107,87,106,127,254,41,239,220,242,183,241,163,166,214,176,178,13,221,143,235,200,166,237,216,172,203,28,180,191,190,149,91,239,110,229,239,31,185,206,204,210,158,202,76,151,215,243,187,100,241,105,186,184,103,150,189,12,176,173,200,190,42,37,197,69,77,238,169,154,53,38,244,168,176,42,201,125,64,255,12,110,49,247,99,129,65,213,72,17,236,200,49,18,214,235,78,187,119,138,51,58,108,216,154,189,19,29,96,172,147,199,60,60,0,208,225,44,58,160,45,62,60,55,76,95,172,177,211,7,123,188,50,15,14,105,235,239,115,182,18,179,63,208,65,146,98,79,180,53,13,86,91,195,96,49,39,248,164,34,202,46,122,15,20,101,77,184,115,166,145,74,178,185,182,137,42,39,15,121,0,43,35,89,151,166,195,32,9,46,4,21,123,141,159,235,15,81,57,79,87,135,165,175,227,66,226,125,210,218,244,222,9,52,177,86,34,72,202,33,73,111,147,95,241,191,22,60,140,65,165,168,107,184,173,132,150,53,6,119,164,162,81,135,6,254,119,255,62,178,195,124,255,33,37,118,100,102,91,195,197,82,44,104,198,197,240,85,177,108,57,222,14,73,3,32,192,84,34,109,54,165,110,224,237,76,123,221,76,181,117,178,8,147,93,180,149,35,189,47,14,56,101,200,10,175,242,64,17,220,178,221,82,102,227,205,162,225,157,135,226,143,9,68,215,68,203,252,40,47,125,80,10,120,96,73,85,13,254,113,225,214,65,197,210,143,125,17,186,25,124,158,201,61,138,122,38,95,211,245,57,12,149,207,237,1,87,27,7,15,21,198,185,96,60,240,123,84,46,130,81,250,7,100,76,66,24,1,98,151,224,6,206,77,225,178,135,7,40,25,69,116,185,163,87,136,16,178,16,193,172,120,225,59,58,92,120,140,107,173,245,149,233,90,109,49,55,116,101,83,14,77,69,217,133,168,92,219,184,117,218,45,207,250,90,95,191,250,237,253,187,102,39,237,142,221,180,58,235,201,222,150,129,12,182,198,67,244,108,30,176,127,125,91,22,116,100,141,3,239,217,28,96,199,247,182,28,232,200,26,7,227,181,28,28,48,115,208,202,191,204,162,62,154,192,90,106,61,83,55,154,87,74,88,229,61,223,91,242,202,177,139,185,157,8,110,135,127,167,140,10,239,59,60,0,91,86,79,11,22,84,8,67,87,188,82,141,206,83,183,218,194,225,249,12,221,221,153,107,235,135,16,115,116,92,167,98,204,93,16,68,19,254,181,31,172,74,171,217,84,58,129,213,3,15,165,161,223,59,69,12,243,116,2,188,20,175,133,66,12,164,88,112,162,226,217,47,110,245,76,180,37,228,196,182,195,111,67,12,100,218,99,200,62,110,59,70,201,213,72,119,142,37,46,222,230,204,246,206,178,170,210,173,194,37,128,33,190,64,228,201,15,147,31,40,250,64,97,80,137,255,116,38,1,59,189,83,159,200,49,43,152,101,59,179,203,152,84,170,111,133,44,242,120,84,94,216,88,194,122,170,16,69,225,139,51,149,174,174,149,204,10,215,103,1,176,88,126,234,222,44,34,130,52,121,151,37,255,235,1,24,152,216,188,141,60,19,243,41,67,248,1,4,84,250,24,82,115,250,223,6,39,39,198,167,190,209,53,16,108,148,155,12,219,23,239,239,249,89,230,193,2,124,206,27,126,24,7,244,15,211,193,39,231,33,19,51,113,140,41,92,162,143,187,234,41,96,211,62,82,18,5,115,250,162,195,56,69,144,228,244,72,197,30,67,190,41,229,200,46,217,16,100,92,68,43,88,36,32,143,20,57,68,81,150,253,47,32,244,55,159,108,108,91,30,34,102,178,171,76,167,168,120,173,35,140,108,65,31,164,90,21,169,136,218,99,133,151,69,212,150,76,44,139,200,226,164,172,139,240,156,61,219,93,41,234,56,79,33,201,43,57,197,127,250,179,77,179,105,150,224,174,182,247,76,254,162,101,151,27,250,59,159,68,56,151,167,110,211,165,249,164,21,180,180,119,115,67,228,147,104,107,201,251,134,126,198,39,17,86,35,207,94,182,209,176,176,241,176,208,120,181,60,151,23,207,203,108,56,53,206,162,89,133,54,42,172,111,181,250,31,204,169,27,69,43,76,0,0 };