From 459df6ef4034ea01582594fcd389bd0f417bedd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Bov=C3=A9?= Date: Tue, 4 Feb 2020 22:47:28 +0100 Subject: [PATCH 001/878] Added jbm8b --- apps/jbm8b/Changelog | 2 + apps/jbm8b/add_to_apps.json | 23 ++++++++++ apps/jbm8b/app-icon.js | 1 + apps/jbm8b/app.js | 85 ++++++++++++++++++++++++++++++++++++ apps/jbm8b/app.json | 6 +++ apps/jbm8b/app.png | Bin 0 -> 2635 bytes 6 files changed, 117 insertions(+) create mode 100644 apps/jbm8b/Changelog create mode 100644 apps/jbm8b/add_to_apps.json create mode 100644 apps/jbm8b/app-icon.js create mode 100644 apps/jbm8b/app.js create mode 100644 apps/jbm8b/app.json create mode 100644 apps/jbm8b/app.png diff --git a/apps/jbm8b/Changelog b/apps/jbm8b/Changelog new file mode 100644 index 000000000..bd71ffcd5 --- /dev/null +++ b/apps/jbm8b/Changelog @@ -0,0 +1,2 @@ +0.01: First working version +0.02: Added delay in replying for dramatic effect \ No newline at end of file diff --git a/apps/jbm8b/add_to_apps.json b/apps/jbm8b/add_to_apps.json new file mode 100644 index 000000000..ffa033f75 --- /dev/null +++ b/apps/jbm8b/add_to_apps.json @@ -0,0 +1,23 @@ +{ + "id": "jbm8b", + "name": "Magic 8 Ball", + "icon": "app.png", + "description": "A simple fortune telling app", + "tags": "game", + "storage": [ + { + "name": "+jbm8b", + "url": "app.json" + }, + { + "name": "-jbm8b", + "url": "app.js" + }, + { + "name": "*jbm8b", + "url": "app-icon.js", + "evaluate": true + } + ], + "version": "1.1.0" +} \ No newline at end of file diff --git a/apps/jbm8b/app-icon.js b/apps/jbm8b/app-icon.js new file mode 100644 index 000000000..b2da211af --- /dev/null +++ b/apps/jbm8b/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("slkgRC/AF1a1WpoAWSgO//4AB/1QDCNvC4QZCGaELC4gAB/BITAAmAGCoyQGBAABMpkHC5P/8AYLl4YK/pJWPxkDC5ZLLj4YM/gYJv4YM/4YJC5v/4BiVMhUPDBz8IYpbJMPZx9JC559HPZ4AB6AYFg4YQ+CUVSxEfDCCWGn4YQSwytH/2V34YHoCtMRYMBBQ+AC4YNHLAcvZBcCBg30gFZgELZBbfH8DPB8ALHZAjfH4C2B/hWHDAg+HwC2B/yIHKwL4KoCsCDA76EDBYDDAAf8DAZaBDCy7HwF/JRLTDgBzBSox8KBAIYK6CuCdg4YM+DQBAQQAGDBZwBtVARA4YMSQILBSgwYFRgSWGgEBBQ4YMUQa6HDBnwSQPQPhgYH4CuKPhlAfJQYMCgeAHw4YK/ySD4AlIDBP8gYEC6CWG/wYP8D6GDAgkGDBjTDgALGDBn8DAcPBYzDDMY4YLSpn4DAcLUI+/cgoAD+gYDg75HIwJzBBY3wDAZ0DAAfAEIPgJwYYIOgYMFig9I6AYDEo67DVow9BDAZXH/+QEZH/wAYERIwAB1SXCUIwAEXYwAK/wYFLA4AJfAj6IABT4EcJIAJYwjIJABLGEV5QAIVoqvKVpoABl4XO/oYHhYYO+gYHgYYO8AYHPp57HAAM/C5n+C5D7Oe4ziRMRIAB34YLoAYKj7FTWB5JLAAN/JKr8LexB+PGBoABg4wWAAMvSSIAGt4XC/xIPAAkV1WVCyYA/AH4A/AH4Ai")) \ No newline at end of file diff --git a/apps/jbm8b/app.js b/apps/jbm8b/app.js new file mode 100644 index 000000000..0fd5a177c --- /dev/null +++ b/apps/jbm8b/app.js @@ -0,0 +1,85 @@ +const affirmative = [ + 'It is\ncertain.', + 'It is\ndicededly\nso.', + 'Without\na doubt.', + 'Yes\ndefinitely.', + 'You may\nrely\non it.', + 'As I see,\nit yes.', + 'Most\nlikely.', + 'Outlook\ngood.', + 'Yes.', + 'Signs point\nto yes.' +]; +const nonCommittal = [ + 'Reply hazy,\ntry again.', + 'Ask again\nlater.', + 'Better not\ntell you\nnow.', + 'Cannot\npredict\nnow.', + 'Concentrate\nand\nask again.' +]; +const negative = [ + 'Don\'t\ncount on it.', + 'My reply\nis no.', + 'My sources\nsay no.', + 'Outlook\nis not\nso\ngood.', + 'Very\ndoubtful.' +]; + +const title = 'Magic 8 Ball'; + +const answers = [affirmative, nonCommittal, negative]; + +function getRandomArbitrary(min, max) { + return Math.random() * (max - min) + min; +} + +function predict() { + // affirmative, negative or non-committal + let max = answers.length; + const a = Math.floor(getRandomArbitrary(0, max)); + // sets max compared to answer category + max = answers[a].length; + const b = Math.floor(getRandomArbitrary(0, max)); + // get the answer + const response = answers[a][b]; + return response; +} + +function draw(msg) { + // console.log(msg); + g.clear(); + E.showMessage(msg, title); +} + +function reply(button) { + const theButton = (typeof button === 'undefined' || isNaN(button)) ? 1 : button; + const timer = Math.floor(getRandomArbitrary(0, theButton) * 1000); + // Thinking... + draw('...'); + setTimeout('draw(predict());', timer); +} + +function ask() { + draw('Ask me a\nYes or No\nquestion\nand\ntouch the\nscreen'); +} + +g.clear(); + +Bangle.loadWidgets(); + +// Event Handlers + +Bangle.on('touch', (button) => reply(button)); + +setWatch(ask, BTN1, {repeat:true, edge:"falling"}); +setWatch(reply, BTN3, {repeat:true, edge:"falling"}); + +// Back to launcher +setWatch(Bangle.showLauncher, BTN2, {repeat:false, edge:"falling"}); + +Bangle.on('lcdPower', (on) => { + if (on) { + Bangle.drawWidgets(); + ask(); + } +}); \ No newline at end of file diff --git a/apps/jbm8b/app.json b/apps/jbm8b/app.json new file mode 100644 index 000000000..a378c4916 --- /dev/null +++ b/apps/jbm8b/app.json @@ -0,0 +1,6 @@ +{ + "name": "Magic 8 Ball", + "icon": "*jbm8b", + "src": "-jbm8b", + "version": "1.1.0" +} \ No newline at end of file diff --git a/apps/jbm8b/app.png b/apps/jbm8b/app.png new file mode 100644 index 0000000000000000000000000000000000000000..78128d47e33ce69755e21a155ee77979fa35f776 GIT binary patch literal 2635 zcmc&#_ct4gAB|bD#SV>!P$RL5SS_j8YDCoDjXh)bSv4C)?M*$Slv+V3+LEf#KBGmg zs{QO)wbxhwitp!~`?=?H&;9X!&P^~f&|;tk(*ghh1|4k_`i39>0S(2?)>6Sb-w>HU zTI&IzZisjN=Ad*zK12clgcQ092Py!70$`+%(fDH`BO@m#r=Xyqq@<*xqN1jzzIE#s z4Gj$t2&AQ@rK6*xr>AFNU|?iqWMX1sW@ct#VF7_atgNhTY;5f8>>L~%oSd9oTwL7T z++Z-6hlhukmlpzo@bmKv2nYxY3PPb!At51QVc|P>?udwph>3}bi;KfxFgP48DJdx> zB_$&xbNB9DIXO9bd3gi^p`f6ksHmu0K743sXlP_)ghr!HOiVBsjH#*VqeqX-%*@Qq%`Ge}EG;dq ztgNi9t!->B>fm$$dKpPwHNhx7OM z4-5ub93|Z^78ZZ3knK~ zii(Phi%UvMN=r-2%F4>i%PT7@U%!4`RaI48UH#_Go0^)M+S=N>y1M%M`i6!E0)f!j z*x1z6)ZE-mBobR%T3TCM-@bj@*4EbE-u~|0yUxzeuC6W;iPYWQ{pr)Eo}QlG-rl~x zzW)CH&!0bk`SN98U|?`?aA;^~czF2h*RNw^W8c4jA0Ho|n3$NHoSd4Pnx3Bi@#DwL z%*^cU?A+Yk{QUgF!ouR>;?mO6^78V^%F62M>e|}c`uh6D#>VF6=GNBM_V)J9&d%=c z?%v+s{{H^2U%w6x4u1dseRz0ybaZrle0*|pa(a4tc6N4tetvOrad~-pb#--peSH(c z|JRs*Uism17h=eohsy<|H=Xd!Y>QK2gjN-W!MCX z4Y08X`{_ZW-p;lMXid$8l8ShmswjlS=F7aP&dT7aDw`=q{~?E};u95>4tkfB%a_3` zMaq_Z*SFP}|N1B9MBRt{scNcxMDK{)Cc@088fJ%)RRZ=frwK+pJ%PYZmxD8md%KM? z&J4ZsivJT5(6a_G-{Y^ZmVT^=4+x*5F54tvea*VqU`cp z^MyZ8eg9c$A4-Zt6zaxG4?o1M(?PxDxLJFONUrCO2ok;29#_+IOOJsr&Ef`ox}(mm z(bCMCrp)fUyn!Aw5 z;RN{#1ezkCKBTOdA;L?#=tz%!bzkrOSulm@L?*lu zBx}PL4DC|rAV@H9l0KMJr)6#nrqjldYmDv9V+)giU;I!wSfbSS*dbLsu@uEA+Xy!z z7ie4x2-;`ZG>VM^grWB}FI*sHz0+_&4a4c4&SBuSOd>7EaO(;ZOhXZ?WfL zk|3OUT>~#!kf>c^ zf{+wyLs=?MltI9*NUB@Mt5TN(^)j;%&Jmx$%4C#Oh;VO4+6HZ}7-N9tZ9j&0{)g@kO^G{8n*m0#JEFcR$_v;RyxfHV=U=`5nM;7O3WlvK-pg8~!k zL-RER20|539AX*}juyc#lj=Qp((PM?Yzb0A<~B_jFPvT@3#7(!n!sYN=uygZKQ%_+ z4Mu>N9!F^mM=NS_e)dkxk6@ZV8a**Cf4s*a!}6W?lLtL{dFIt9_bJgh7gAL@gWRb^0UC&>X34ixSt&WuYucX$RUE~7HOeXy*Mck zPOBPCN}R1LlwO-lpvRFT#5JGir9s(v8}b&+bR5MgMVm$YEq)Fma^727wjEawen@L! zBrubVP2tfFap%+*gnNqRS@CiB3U*N!3C?C`+C-4bvn|_iEQMKCXHm5>EoBJIr5G7&s#rwzu>H>AuAKBYf@f`oFyUe z>~AOPmCrayM*9^;%#a3?cp>JyTYKC_JGu$CZARS literal 0 HcmV?d00001 From 67b2b08e0967e7c2a0523a855c6cb64f73b5e182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Bov=C3=A9?= Date: Tue, 4 Feb 2020 22:55:32 +0100 Subject: [PATCH 002/878] Added jbm8b to apps.json --- apps.json | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/apps.json b/apps.json index 76151a627..e02bc3d43 100644 --- a/apps.json +++ b/apps.json @@ -751,5 +751,31 @@ {"name":"*demoapp","url":"app-icon.js","evaluate":true} ], "sortorder" : -9 + }, + { + "id": "jbm8b", + "name": "Magic 8 Ball", + "icon": "app.png", + "description": "A simple fortune telling app", + "tags": "game", + "storage": [ + { + "name": "+jbm8b", + "url": "app.json" + }, + { + "name": "-jbm8b", + "url": "app.js" + }, + { + "name": "*jbm8b", + "url": "app-icon.js", + "evaluate": true + } + ], + "allow_emulator":true, + "type":"app", + "version": "0.01", + "sortorder" : -9 } ] From bfe298f615c819c19426a2d779434c7eb4c863fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Bov=C3=A9?= Date: Tue, 4 Feb 2020 23:02:54 +0100 Subject: [PATCH 003/878] Updated jbm8b --- apps.json | 2 +- apps/jbm8b/add_to_apps.json | 2 +- apps/jbm8b/app.js | 15 +++++---------- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/apps.json b/apps.json index e02bc3d43..a9c40569a 100644 --- a/apps.json +++ b/apps.json @@ -775,7 +775,7 @@ ], "allow_emulator":true, "type":"app", - "version": "0.01", + "version": "0.02", "sortorder" : -9 } ] diff --git a/apps/jbm8b/add_to_apps.json b/apps/jbm8b/add_to_apps.json index ffa033f75..200ea5f65 100644 --- a/apps/jbm8b/add_to_apps.json +++ b/apps/jbm8b/add_to_apps.json @@ -19,5 +19,5 @@ "evaluate": true } ], - "version": "1.1.0" + "version": "0.02" } \ No newline at end of file diff --git a/apps/jbm8b/app.js b/apps/jbm8b/app.js index 0fd5a177c..53baa32e3 100644 --- a/apps/jbm8b/app.js +++ b/apps/jbm8b/app.js @@ -66,20 +66,15 @@ function ask() { g.clear(); Bangle.loadWidgets(); +Bangle.drawWidgets(); +ask(); // Event Handlers Bangle.on('touch', (button) => reply(button)); -setWatch(ask, BTN1, {repeat:true, edge:"falling"}); -setWatch(reply, BTN3, {repeat:true, edge:"falling"}); +setWatch(ask, BTN1, { repeat: true, edge: "falling" }); +setWatch(reply, BTN3, { repeat: true, edge: "falling" }); // Back to launcher -setWatch(Bangle.showLauncher, BTN2, {repeat:false, edge:"falling"}); - -Bangle.on('lcdPower', (on) => { - if (on) { - Bangle.drawWidgets(); - ask(); - } -}); \ No newline at end of file +setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); \ No newline at end of file From 0c3b38a4c2825f35348acc79912009f591b0b5cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Bov=C3=A9?= Date: Wed, 5 Feb 2020 21:17:31 +0100 Subject: [PATCH 004/878] Fixed app.png for jbm8b --- apps/jbm8b/app-icon.js | 2 +- apps/jbm8b/app.png | Bin 2635 -> 1548 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/jbm8b/app-icon.js b/apps/jbm8b/app-icon.js index b2da211af..09bf032a6 100644 --- a/apps/jbm8b/app-icon.js +++ b/apps/jbm8b/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("slkgRC/AF1a1WpoAWSgO//4AB/1QDCNvC4QZCGaELC4gAB/BITAAmAGCoyQGBAABMpkHC5P/8AYLl4YK/pJWPxkDC5ZLLj4YM/gYJv4YM/4YJC5v/4BiVMhUPDBz8IYpbJMPZx9JC559HPZ4AB6AYFg4YQ+CUVSxEfDCCWGn4YQSwytH/2V34YHoCtMRYMBBQ+AC4YNHLAcvZBcCBg30gFZgELZBbfH8DPB8ALHZAjfH4C2B/hWHDAg+HwC2B/yIHKwL4KoCsCDA76EDBYDDAAf8DAZaBDCy7HwF/JRLTDgBzBSox8KBAIYK6CuCdg4YM+DQBAQQAGDBZwBtVARA4YMSQILBSgwYFRgSWGgEBBQ4YMUQa6HDBnwSQPQPhgYH4CuKPhlAfJQYMCgeAHw4YK/ySD4AlIDBP8gYEC6CWG/wYP8D6GDAgkGDBjTDgALGDBn8DAcPBYzDDMY4YLSpn4DAcLUI+/cgoAD+gYDg75HIwJzBBY3wDAZ0DAAfAEIPgJwYYIOgYMFig9I6AYDEo67DVow9BDAZXH/+QEZH/wAYERIwAB1SXCUIwAEXYwAK/wYFLA4AJfAj6IABT4EcJIAJYwjIJABLGEV5QAIVoqvKVpoABl4XO/oYHhYYO+gYHgYYO8AYHPp57HAAM/C5n+C5D7Oe4ziRMRIAB34YLoAYKj7FTWB5JLAAN/JKr8LexB+PGBoABg4wWAAMvSSIAGt4XC/xIPAAkV1WVCyYA/AH4A/AH4Ai")) \ No newline at end of file +require("heatshrink").decompress(atob("mEwhBC/AGMrq2B1gAEwNWlYthq2s64AKGYIydFpoAEGLUrFqIADqxcXFqhiDFymBFy7GCF1owTRjCSVlYudeiGsF7/XlaNqSKBeP1mBwJxQMBReO1gaEleBMDBLN1hAC1hhBAoIwNCwQAGlZINqxvFGAIXOSBAXQN4hPBC5yQIVBxfBCAgvQSBC+NFAYRDMwJHOF654DqxkBYooALF6+sbIhkEF8Z3CRIWBR6AvXFAzvQF6wnIYQJgNd5AWNdoLoGBBAvPO5pfYH4IvUUwS/GVBzXBYCpHCq2s1mBDwKOWDwRgNPAwVVMCRLCwIABCZ6OJJSAATLxZgRACJeLAAMrFz9WFxiRgRpoADwIub1guQGDmsXhqSfRiL0G1jqkMRYxRwKLUGK2sFryVEq2B1gAEwNWFkIA/AH4A/AH4AQ")) \ No newline at end of file diff --git a/apps/jbm8b/app.png b/apps/jbm8b/app.png index 78128d47e33ce69755e21a155ee77979fa35f776..24c3013de011db9c1517ed544e9d383f5c60378c 100644 GIT binary patch delta 1166 zcmV;91abSz6pRcZiBL{Q4GJ0x0000DNk~Le0000m0000m2m=5B0ASn+wUHrVe-#xK z7Z(>87#JBD85$ZI8yg!P9UUJZA0i?mBO@auBqSvzB_<{&D=RB3EG#W8EiW%GGBPqV zGczQb8~ZabaZ%lczJnwfPjF3fq{mG zhKGlTi;IhljEs$qjgF3vkdTm(k&%*;l9ZH`m6es5nVFoNoSmJWo}QkcpP!?nqot*# zrlzK+r>Ci@sj8}~tE;Q5tgNlAt*@`Iu&}VPv9YtWv$eIgx3{;sxw*T$f4jWAyuH1> zzP`S{zrVo1z{0}9!^6YH#l^dCU$jHda$;ryf%FD~k&CSiw(9qG*(bCe=)6>({ z)z#M4*4WtC+1c6J+S=UQ+}+*X-rnBg;^O1uFMg~>g((4?Ck9A?d|UF z?(gsK@bK{Q@$vKX^Yrxe4E6Q(_V)Jo_xJet_>;K;jg#O4W|QCoNPp6yd3yi=010qN zS#tmY79;=w79;_i6~+_*00NasL_t(YOWl>(U(-Mog=d;3l+e-^(Mm;BP!!x3R8&B~ z9T2IYsHiCJyTw9LDzbw)`4u7o8t=)C{Z{zV}z=orTuDO~IA} zn{O?G!GzQtXE2E*2g_g)kh_*)u#g&F3sVkKhs|;f*lRy*Sx)55uaUZ8uA}w`hVqbX z68EZP6a#sg+W;$v9wZJxu-&i|vP)c1J-Men zXVl6CE*OMhC*%wi9d?Lb)ao5|Ze7w9@WR+9$`fXJ$-K0;FLmAl2{p z>^TrnPm2?*EPuEWphTenHeTF^Sz2q-cIjQYG?-oQ0xui|o}Ge~C8nr$J_0O$YZ_ z+Rjfnb(EarfKtf#_xT)3{YKG@Sm z>=V|M><&;#arm3X&o<|J6aN%M9rop6cjxVoVq1vUz|3hBrm$ro_Y);<(_veguYwiq z$m!X3Bu|=JGHounC^l$m$Wq93Hw7Z))}Aki@-|Brsj&LfbF}`1!Nl^AO@0kpH)dDJ zT#EvO6-$5njHwc~*jHtr9;`bS$^M7fuZi;oe~KK}#)DVGV!Z delta 2407 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 Z25u9%h&7af?>ztj002ovPDHLkV1l1vck=)M From b78c056b867ef205dd757c9d1ba7390cd1dd5039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Bov=C3=A9?= Date: Fri, 7 Feb 2020 22:22:50 +0100 Subject: [PATCH 005/878] adds icon for jbb --- apps.json | 26 +++++++++++++++++++ apps/jbb/ChangeLog | 2 ++ apps/jbb/add_to_apps.json | 23 +++++++++++++++++ apps/jbb/app-icon.js | 1 + apps/jbb/app.js | 53 ++++++++++++++++++++++++++++++++++++++ apps/jbb/app.json | 5 ++++ apps/jbb/app.png | Bin 0 -> 1673 bytes 7 files changed, 110 insertions(+) create mode 100644 apps/jbb/ChangeLog create mode 100644 apps/jbb/add_to_apps.json create mode 100644 apps/jbb/app-icon.js create mode 100644 apps/jbb/app.js create mode 100644 apps/jbb/app.json create mode 100644 apps/jbb/app.png diff --git a/apps.json b/apps.json index a9c40569a..6ca702fe7 100644 --- a/apps.json +++ b/apps.json @@ -778,4 +778,30 @@ "version": "0.02", "sortorder" : -9 } + { + "id": "jbb", + "name": "Battery Level", + "icon": "app.png", + "description": "Battery status and charging indicator", + "tags": "tool", + "storage": [ + { + "name": "+jbb", + "url": "app.json" + }, + { + "name": "-jbb", + "url": "app.js" + }, + { + "name": "*jbb", + "url": "app-icon.js", + "evaluate": true + } + ], + "allow_emulator":true, + "type":"app", + "version": "0.02", + "sortorder" : -9 + } ] diff --git a/apps/jbb/ChangeLog b/apps/jbb/ChangeLog new file mode 100644 index 000000000..b7359ee0e --- /dev/null +++ b/apps/jbb/ChangeLog @@ -0,0 +1,2 @@ +0.01: First version trying out stuff +0.02: First usable version \ No newline at end of file diff --git a/apps/jbb/add_to_apps.json b/apps/jbb/add_to_apps.json new file mode 100644 index 000000000..cc6483ac1 --- /dev/null +++ b/apps/jbb/add_to_apps.json @@ -0,0 +1,23 @@ +{ + "id": "jbb", + "name": "Battery Power", + "icon": "app.png", + "description": "Showing battery level and charging status", + "tags": "tool", + "storage": [ + { + "name": "+jbb", + "url": "app.json" + }, + { + "name": "-jbb", + "url": "app.js" + }, + { + "name": "*jbb", + "url": "app-icon.js", + "evaluate": true + } + ], + "version": "0.02" +} \ No newline at end of file diff --git a/apps/jbb/app-icon.js b/apps/jbb/app-icon.js new file mode 100644 index 000000000..8fbebe9df --- /dev/null +++ b/apps/jbb/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4AvlYAVF7NVABdPAggublfVAAfU5gAKFzReCF4guL0RehFxZedF6Iu/F/hezF1AvB1YvOFzxevF54u/F6Qupqxe/FzovBLxougLxoOBACIvNwAuB6YvbXroANqqdQF4YuYLqBedDgNWdqYuZFp/+qwuC6i6nLzi6RF4nPF1peXFqgvCqouUXSheEABhrHRaovSFw9WFyo8O6vUXTb6SFodPF0xeCXTheVF1AvBwC6pLwjsBqoupF4SLqF2AvCFtYuvF4YurF4NWF1otsAH4AXA==")) \ No newline at end of file diff --git a/apps/jbb/app.js b/apps/jbb/app.js new file mode 100644 index 000000000..f39d06280 --- /dev/null +++ b/apps/jbb/app.js @@ -0,0 +1,53 @@ +/** + * draw the current level value + */ +function draw(level) { + console.log('draw', level); + // Clear the screen + g.clear(); + g.setFontAlign(0, 0); // center font + g.setFont("6x8", 8); // bitmap font, 8x magnified + g.drawString(level + "%", 120, 80); + g.setFont("6x8", 4); + g.drawString("power", 120, 130); +} + +function getBatteryLevel() { + level = E.getBattery(); + console.log('getBatteryLevel', level); + + draw(level); + + checkCharging(Bangle.isCharging()); + + // again, 10 secs later + setTimeout(getBatteryLevel, 10E3); +} + +function checkCharging(charging) { + console.log('checkCharging', charging); + // Green LED + //LED2.write(charging); + if (charging) { + g.setFontAlign(0, 0); // center font + g.setFont("6x8", 3); // bitmap font, 3x magnifier + g.drawString("charging", 120, 160); + } +} + +function main() { + console.log('starting jbb version 0.0.1'); + getBatteryLevel(); +} + +g.clear(); +g.flip(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +Bangle.on('charging', checkCharging); + +main(); + +// Show launcher when middle button pressed +setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); diff --git a/apps/jbb/app.json b/apps/jbb/app.json new file mode 100644 index 000000000..9e4eb893c --- /dev/null +++ b/apps/jbb/app.json @@ -0,0 +1,5 @@ +{ + "name": "Battery Power", + "icon": "*jbb", + "src": "-jbb" +} \ No newline at end of file diff --git a/apps/jbb/app.png b/apps/jbb/app.png new file mode 100644 index 0000000000000000000000000000000000000000..6f58711b57c4be035b8368e4adbba1a5741e9532 GIT binary patch literal 1673 zcmV;426p+0P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1|CU7K~!i%)md9i z9Yq-a_j0b3mIMINK(MNr%4rG$tUw}>;CI)Rcch}=*!W8dih0DHfr39mRxN(i z7A>y9wG~tJrPFCgR`H~OZTIYIP1m~#2Z&JuZ%h@K-b={HWZFpJ( zME-$$?vPR*$jW<=CzK<0O8UQqO`?6ts`PlBQ`DHXxc z02Yg$=|OmGpb4^!I}RNiu025H4Ff{~`Q(F{)K{K7*@`a}84Noc2On}pp5RJ>j*bqF z^TF&`H~O&9`s!MjY?Z=X#IMsI<{^%j4;x`upp@Lfl>)TTrbb?sQXV$ZBYQxZmkk>@^W%e$h!pD9`hh; z6y|b6b`*lsG&1KC7-*0fh@l}WOPS^1$^-Ac^Q3H9;EI9#tPQ9HNKaWPjQi%nCUN&- zc^efe(AL%_n6w_hPslcu@1T!MuhM}q~S z{X!$CsD&S)W5clr48y=3H-oL*+oeTPo94m!wieQsVU#d6AoO&?d|Q{G!2*> z?Ey`-zRRz77kHxp^Jo(~$RLtKF;PO$98@ZcbyQR?(=)rz=0Y-E46~gbb|ja}TnBo9 z26?5oU6MD!$b7gbc`?5vzeS4}3pZNiG>Mtbind6>c~^cP$G8(0&O`GO=uV-xSK8gz z1ES{FvXK7zB|*$&nAb6FRt55$U?BaTk6PjKADZyUL8Zol9>}btg3_wmzttgctl$S7 zaX` zBl%7F#2dtM_!od3Q-##I77;!~d~9sYHF-jb0+hZQ9=r>g<8HWeO7?n(Hm|_RPmaP9 zZ#9TH{3heew%6W5Cg+emB&%wqCX)Lmt8 z>;i@iDoy#_@1kzsQo;#n!~1Te3jz$2`ue-F7s;=xz;K664a6{hyuCWv4`s8EQ`oOq z0=f=-Ek~YodA9#3q=wq6N}k|J0m7G`pT_d~4DJ~ypgIiGWMZfh{@SY9%{10Gs{_{x zko6TsgZkPHj6=Cg{~AQA<6`9@@t(h0hnReL^1w4s-w$x@MPYekQHA*VHq1IqSbcna zyz1l$t`;$EcFfcueeqs^8=peY>#gwfk}6J5)j0R=2Ui{-rMEXYu+7gP{#;y;r@os_ zo=~v@WPQ4S|J4uBaiSSFCk{0=HJ)G6x<$nyL<(4cLpwG*G~zZY@<3;2rzDTXnQ0t4 zc|t`B(0^tKl;3A(XAhk`q2e`AS66pa^1EYDNI1Fd*uT{-&&Awf!__`;>j2 Date: Fri, 7 Feb 2020 22:24:39 +0100 Subject: [PATCH 006/878] fixes apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 6ca702fe7..c9c59d34b 100644 --- a/apps.json +++ b/apps.json @@ -777,7 +777,7 @@ "type":"app", "version": "0.02", "sortorder" : -9 - } + }, { "id": "jbb", "name": "Battery Level", From fc356c31d7021bf6b71552128d54b741f3d9727a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Bov=C3=A9?= Date: Tue, 7 Apr 2020 22:20:15 +0200 Subject: [PATCH 007/878] Fixes corrupted app list --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index d8cdde0fc..c14fda261 100644 --- a/apps.json +++ b/apps.json @@ -1481,7 +1481,7 @@ "allow_emulator": true, "type": "app", "version": "0.02", - "sortorder": -9, + "sortorder": -9 }, { "id": "flagrse", From 86ad563bc2f4d8ec23aa3e8e3c8ac25590f3bda1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Bov=C3=A9?= Date: Fri, 10 Apr 2020 23:03:59 +0200 Subject: [PATCH 008/878] Fixes jbmb8 apps entry --- apps.json | 47 +++--------------------------- apps/_example_app/add_to_apps.json | 1 - apps/jbm8b/Changelog | 3 +- apps/jbm8b/add_to_apps.json | 18 +++--------- 4 files changed, 10 insertions(+), 59 deletions(-) diff --git a/apps.json b/apps.json index c14fda261..a82da04d2 100644 --- a/apps.json +++ b/apps.json @@ -1434,54 +1434,15 @@ { "id": "jbm8b", "name": "Magic 8 Ball", + "shortName": "Magic 8 Ball", "icon": "app.png", "description": "A simple fortune telling app", "tags": "game", "storage": [ - { - "name": "+jbm8b", - "url": "app.json" - }, - { - "name": "-jbm8b", - "url": "app.js" - }, - { - "name": "*jbm8b", - "url": "app-icon.js", - "evaluate": true - } + { "name": "jbm8b.app.js", "url": "app.js" }, + { "name": "jbm8b.img", "url": "app-icon.js", "evaluate": true } ], - "allow_emulator": true, - "type": "app", - "version": "0.02", - "sortorder": -9 - }, - { - "id": "jbb", - "name": "Battery Level", - "icon": "app.png", - "description": "Battery status and charging indicator", - "tags": "tool", - "storage": [ - { - "name": "+jbb", - "url": "app.json" - }, - { - "name": "-jbb", - "url": "app.js" - }, - { - "name": "*jbb", - "url": "app-icon.js", - "evaluate": true - } - ], - "allow_emulator": true, - "type": "app", - "version": "0.02", - "sortorder": -9 + "version": "0.03" }, { "id": "flagrse", diff --git a/apps/_example_app/add_to_apps.json b/apps/_example_app/add_to_apps.json index ca75a7bd8..dd66030b6 100644 --- a/apps/_example_app/add_to_apps.json +++ b/apps/_example_app/add_to_apps.json @@ -1,4 +1,3 @@ -// Create an entry in apps.json as follows: { "id": "7chname", "name": "My app's human readable name", "shortName":"Short Name", diff --git a/apps/jbm8b/Changelog b/apps/jbm8b/Changelog index bd71ffcd5..80d7de1d6 100644 --- a/apps/jbm8b/Changelog +++ b/apps/jbm8b/Changelog @@ -1,2 +1,3 @@ 0.01: First working version -0.02: Added delay in replying for dramatic effect \ No newline at end of file +0.02: Added delay in replying for dramatic effect +0.03: Fixed apps.json entry diff --git a/apps/jbm8b/add_to_apps.json b/apps/jbm8b/add_to_apps.json index 200ea5f65..8e28639e7 100644 --- a/apps/jbm8b/add_to_apps.json +++ b/apps/jbm8b/add_to_apps.json @@ -1,23 +1,13 @@ { "id": "jbm8b", "name": "Magic 8 Ball", + "shortName": "Magic 8 Ball", "icon": "app.png", "description": "A simple fortune telling app", "tags": "game", "storage": [ - { - "name": "+jbm8b", - "url": "app.json" - }, - { - "name": "-jbm8b", - "url": "app.js" - }, - { - "name": "*jbm8b", - "url": "app-icon.js", - "evaluate": true - } + { "name": "jbm8b.app.js", "url": "app.js" }, + { "name": "jbm8b.img", "url": "app-icon.js", "evaluate": true } ], - "version": "0.02" + "version": "0.03" } \ No newline at end of file From 217d19815456966c0fd268e31153d6bf8ac57e63 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Sun, 12 Apr 2020 00:26:08 +0200 Subject: [PATCH 009/878] Add a "data" section to apps.json, with data files to clean on uninstall These are added to `appid.info` as "dataFiles" or "storageFiles", and can contain wildcards. --- README.md | 25 ++++++++++++++++++++----- bin/sanitycheck.js | 33 +++++++++++++++++++++++++++++++++ js/appinfo.js | 13 +++++++++++++ js/comms.js | 24 +++++++++++++++++++++--- js/index.js | 13 +++++++++++++ js/utils.js | 12 ++++++++++++ 6 files changed, 112 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ca874ad2f..7a96ad335 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,13 @@ and which gives information about the app for the Launcher. "files:"file1,file2,file3", // added by BangleApps loader on upload - lists all files // that belong to the app so it can be deleted + "dataFiles":"appid.data.json,appid.data?.json" + // added by BangleApps loader on upload - lists files that + // the app might write, so they can be deleted on uninstall + // typically these files are not uploaded, but created by the app + // these can include '*' or '?' wildcards + "storageFiles":" + // same as "dataFiles", except the app handles these as storageFile } ``` @@ -240,16 +247,27 @@ and which gives information about the app for the Launcher. "evaluate":true // if supplied, data isn't quoted into a String before upload // (eg it's evaluated as JS) }, + ] + "data": [ // list of files the app writes to + {"name":"appid.data.json", // filename used in storage + "storageFile":true // if supplied, file is treated as storageFile + }, + {"wildcard":"appid.data.*" // wildcard of filenames used in storage + }, // this is mutually exclusive with using "name" + ], "sortorder" : 0, // optional - choose where in the list this goes. // this should only really be used to put system // stuff at the top - ] } ``` * name, icon and description present the app in the app loader. * tags is used for grouping apps in the library, separate multiple entries by comma. Known tags are `tool`, `system`, `clock`, `game`, `sound`, `gps`, `widget`, `launcher` or empty. * storage is used to identify the app files and how to handle them +* data is used to clean up files when the app is uninstalled + (If the app has settings but no data section, it is assumed settings are + stored in `appid.settings.json`, so there is no need to add a data section + containing only that file) ### `apps.json`: `custom` element @@ -351,19 +369,16 @@ Example `settings.js` E.showMenu(appMenu) }) ``` -In this example the app needs to add both `app.settings.js` and -`app.settings.json` to `apps.json`: +In this example the app needs to add `app.settings.js` to `apps.json`: ```json { "id": "app", ... "storage": [ ... {"name":"app.settings.js","url":"settings.js"}, - {"name":"app.settings.json","content":"{}"} ] }, ``` -That way removing the app also cleans up `app.settings.json`. ## Coding hints diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index 62b111ae0..fdf15a26b 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -74,6 +74,8 @@ apps.forEach((app,appIdx) => { var fileNames = []; app.storage.forEach((file) => { if (!file.name) ERROR(`App ${app.id} has a file with no name`); + if (file.name.includes('?') || file.name.includes('*')) + ERROR(`App ${app.id} storage file ${file.name} contains wildcards`); if (fileNames.includes(file.name)) ERROR(`App ${app.id} file ${file.name} is a duplicate`); fileNames.push(file.name); @@ -115,6 +117,37 @@ apps.forEach((app,appIdx) => { if (!STORAGE_KEYS.includes(key)) ERROR(`App ${app.id}'s ${file.name} has unknown key ${key}`); } }); + let dataNames = []; + (app.data||[]).forEach((data)=>{ + if (!data.name && !data.wildcard) ERROR(`App ${app.id} has a data file with no name`); + if (dataNames.includes(data.name||data.wildcard)) + ERROR(`App ${app.id} data file ${data.name||data.wildcard} is a duplicate`); + dataNames.push(data.name||data.wildcard) + if ('name' in data && 'wildcard' in data) + ERROR(`App ${app.id} data file ${data.name} has both name and wildcard`); + if (data.name) { + if (data.name.includes('?') || data.name.includes('*')) + ERROR(`App ${app.id} data file name ${data.name} contains wildcards`); + } + if (data.wildcard) { + if (!data.wildcard.includes('?') && !data.wildcard.includes('*')) + ERROR(`App ${app.id} data file wildcard ${data.wildcard} does not actually contains wildcard`); + if (data.wildcard.replace(/\?|\*/g,'') === '') + ERROR(`App ${app.id} data file wildcard ${data.wildcard} does not contain regular characters`); + else if (data.wildcard.replace(/\?|\*/g,'').length < 3) + WARN(`App ${app.id} data file wildcard ${data.wildcard} is very broad`); + else if (!data.wildcard.includes(app.id)) + WARN(`App ${app.id} data file wildcard ${data.wildcard} does not include app ID`); + } + if ('storageFile' in data && typeof data.storageFile !== 'boolean') + ERROR(`App ${app.id} data file ${data.name||data.wildcard} has non-boolean value for "storageFile"`); + for (const key in data) { + if (!['name','wildcard','storageFile'].includes(key)) + ERROR(`App ${app.id} data file ${data.name||data.wildcard} has unknown property "${key}"`); + } + }); + if (fileNames.includes(app.id+".settings.js") && dataNames.length===1 && dataNames[0] === app.id+'.settings.json') + WARN(`App ${app.id} has settings, so does not need to declare data file ${app.id+'.settings.json'}`) //console.log(fileNames); if (isApp && !fileNames.includes(app.id+".app.js")) ERROR(`App ${app.id} has no entrypoint`); if (isApp && !fileNames.includes(app.id+".img")) ERROR(`App ${app.id} has no JS icon`); diff --git a/js/appinfo.js b/js/appinfo.js index f4ab498b1..04c5da893 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -69,6 +69,19 @@ var AppInfo = { var fileList = fileContents.map(storageFile=>storageFile.name); fileList.unshift(appJSONName); // do we want this? makes life easier! json.files = fileList.join(","); + let dataFileList = [], storageFileList = []; + if ('data' in app) { + // add "data" files to appropriate list + app.data.forEach(d=>{ + if (d.storageFile) storageFileList.push(d.name||d.wildcard) + else dataFileList.push(d.name||d.wildcard) + }) + } else if (json.settings) { + // settings but no data files: assume app uses .settings.json file + dataFileList.push(app.id + '.settings.json') + } + if (dataFileList.length) json.dataFiles = dataFileList.join(","); + if (storageFileList.length) json.storageFiles = storageFileList.join(","); fileContents.push({ name : appJSONName, content : JSON.stringify(json) diff --git a/js/comms.js b/js/comms.js index 1f840ada7..1e8250305 100644 --- a/js/comms.js +++ b/js/comms.js @@ -94,10 +94,28 @@ getInstalledApps : () => { }); }, removeApp : app => { // expects an appid.info structure (i.e. with `files`) - if (app.files === '') return Promise.resolve(); // nothing to erase + if (!app.files && !app.dataFiles && !app.storageFiles) return Promise.resolve(); // nothing to erase Progress.show({title:`Removing ${app.name}`,sticky:true}); - var cmds = app.files.split(',').map(file=>{ - return `\x10require("Storage").erase(${toJS(file)});\n`; + let cmds = '\x10const s=require("Storage");\n'; + // remove App files (regular files, exact names only) + cmds += app.files.split(',').map(file => `\x10s.erase(${toJS(file)});\n`).join(""); + // remove Data files (regular files, can use wildcards) + cmds += (app.dataFiles||[]).split(',').map(file => { + const isGlob = (file.includes('*') || file.includes('?')) + if (!isGlob) return `\x10s.erase(${toJS(file)});\n`; + const regex = new RegExp(globToRegex(file)) + return `\x10s.list(${regex}).forEach(f=>s.erase(f));\n`; + }).join(""); + // remove Storage files (storageFiles, can use wildcards) + cmds += (app.storageFiles||[]).split(',').map(file => { + const isGlob = (file.includes('*') || file.includes('?')) + if (!isGlob) return `\x10s.open(${toJS(file)},'r').erase();\n`; + // storageFiles have a chunk number appended to their real name + const regex = globToRegex(file+'\u0001') + // open() doesn't want the chunk number though + let cmd = `\x10s.list(${regex}).forEach(f=>s.open(f.substring(0,f.length-1),'r').erase());\n` + // using a literal \u0001 char fails (not sure why), so escape it + return cmd.replace('\u0001', '\\x01') }).join(""); console.log("removeApp", cmds); return Comms.reset().then(new Promise((resolve,reject) => { diff --git a/js/index.js b/js/index.js index ef9bcb4f1..c48920315 100644 --- a/js/index.js +++ b/js/index.js @@ -349,6 +349,19 @@ function updateApp(app) { .filter(f => f !== app.id + '.info') .filter(f => !app.storage.some(s => s.name === f)) .join(','); + let dataFiles = (remove.dataFiles||'').split(','), + storageFiles = (remove.storageFiles||'').split(',') + if ('data' in app) { + // keep declared (in new version) data files + dataFiles = dataFiles.filter(f => app.data.some(d => (d.name||d.wildcard) === f)) + storageFiles = storageFiles.filter(f => app.data.some(d => (d.name||d.wildcard) === f)) + } + else if (remove.settings || app.settings) { + // app with settings but no data files declared: keep .settings.json + dataFiles = dataFiles.filter(f => f !== (app.id + '.settings.json')) + } + if (dataFiles.length) remove.dataFiles = dataFiles.join(','); + if (storageFiles.length) remove.storageFiles = storageFiles.join(',') return Comms.removeApp(remove); }).then(()=>{ showToast(`Updating ${app.name}...`); diff --git a/js/utils.js b/js/utils.js index d8c1b8063..50d319338 100644 --- a/js/utils.js +++ b/js/utils.js @@ -8,6 +8,18 @@ function escapeHtml(text) { }; return text.replace(/[&<>"']/g, function(m) { return map[m]; }); } +// simple glob to regex conversion, only supports "*" and "?" wildcards +function globToRegex(pattern) { + const ESCAPE = '.*+-?^${}()|[]\\'; + const regex = pattern.replace(/./g, c => { + switch (c) { + case '?': return '.'; + case '*': return '.*'; + default: return ESCAPE.includes(c) ? ('\\' + c) : c; + } + }); + return new RegExp('^'+regex+'$'); +} function htmlToArray(collection) { return [].slice.call(collection); } From 9e0fd91339dc48acd38c4c0687000f199ddb5c23 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Wed, 15 Apr 2020 21:30:44 +0200 Subject: [PATCH 010/878] Data files: save all data files as a single string Separate regular and storage files by a semicolon --- README.md | 4 +--- bin/sanitycheck.js | 5 +++-- js/appinfo.js | 39 ++++++++++++++++++++++++++++++++------- js/comms.js | 14 ++++++++------ js/index.js | 18 ++++++++---------- 5 files changed, 52 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 7a96ad335..a04ee95b2 100644 --- a/README.md +++ b/README.md @@ -202,13 +202,11 @@ and which gives information about the app for the Launcher. "files:"file1,file2,file3", // added by BangleApps loader on upload - lists all files // that belong to the app so it can be deleted - "dataFiles":"appid.data.json,appid.data?.json" + "data":"appid.data.json,appid.data?.json;appidStorageFile,appidStorageFile*" // added by BangleApps loader on upload - lists files that // the app might write, so they can be deleted on uninstall // typically these files are not uploaded, but created by the app // these can include '*' or '?' wildcards - "storageFiles":" - // same as "dataFiles", except the app handles these as storageFile } ``` diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index fdf15a26b..197ebf57e 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -39,9 +39,10 @@ try{ const APP_KEYS = [ 'id', 'name', 'shortName', 'version', 'icon', 'description', 'tags', 'type', - 'sortorder', 'readme', 'custom', 'interface', 'storage', 'allow_emulator', + 'sortorder', 'readme', 'custom', 'interface', 'storage', 'data', 'allow_emulator', ]; const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate']; +const DATA_KEYS = ['name', 'wildcard', 'storageFile']; apps.forEach((app,appIdx) => { if (!app.id) ERROR(`App ${appIdx} has no id`); @@ -142,7 +143,7 @@ apps.forEach((app,appIdx) => { if ('storageFile' in data && typeof data.storageFile !== 'boolean') ERROR(`App ${app.id} data file ${data.name||data.wildcard} has non-boolean value for "storageFile"`); for (const key in data) { - if (!['name','wildcard','storageFile'].includes(key)) + if (!DATA_KEYS.includes(key)) ERROR(`App ${app.id} data file ${data.name||data.wildcard} has unknown property "${key}"`); } }); diff --git a/js/appinfo.js b/js/appinfo.js index 04c5da893..413098bc4 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -69,26 +69,51 @@ var AppInfo = { var fileList = fileContents.map(storageFile=>storageFile.name); fileList.unshift(appJSONName); // do we want this? makes life easier! json.files = fileList.join(","); - let dataFileList = [], storageFileList = []; + let data = {dataFiles: [], storageFiles: []}; if ('data' in app) { // add "data" files to appropriate list app.data.forEach(d=>{ - if (d.storageFile) storageFileList.push(d.name||d.wildcard) - else dataFileList.push(d.name||d.wildcard) + if (d.storageFile) data.storageFiles.push(d.name||d.wildcard) + else data.dataFiles.push(d.name||d.wildcard) }) } else if (json.settings) { // settings but no data files: assume app uses .settings.json file - dataFileList.push(app.id + '.settings.json') + data.dataFiles.push(app.id + '.settings.json') } - if (dataFileList.length) json.dataFiles = dataFileList.join(","); - if (storageFileList.length) json.storageFiles = storageFileList.join(","); + const dataString = AppInfo.makeDataString(data) + if (dataString) json.data = dataString fileContents.push({ name : appJSONName, content : JSON.stringify(json) }); resolve(fileContents); }); - } + }, + // (.info).data holds filenames of data: both regular and storageFiles + // These are stored as: (note comma vs semicolons) + // "fil1,file2", "file1,file2;storageFileA,storageFileB" or ";storageFileA" + /** + * Convert appid.info "data" to object with file names/patterns + * Passing in undefined works + * @param data "data" as stored in appid.info + * @returns {{storageFiles:[], dataFiles:[]}} + */ + parseDataString(data) { + data = data || ''; + let [files = [], storage = []] = data.split(';').map(d => d.split(',')) + return {dataFiles: files, storageFiles: storage} + }, + /** + * Convert object with file names/patterns to appid.info "data" string + * Passing in an incomplete object will not work + * @param data {{storageFiles:[], dataFiles:[]}} + * @returns {string} "data" to store in appid.info + */ + makeDataString(data) { + if (!data.dataFiles.length && !data.storageFiles.length) { return '' } + if (!data.storageFiles.length) { return data.dataFiles.join(',') } + return [data.dataFiles.join(','),data.storageFiles.join(',')].join(';') + }, }; if ("undefined"!=typeof module) diff --git a/js/comms.js b/js/comms.js index 1e8250305..736a2b7c7 100644 --- a/js/comms.js +++ b/js/comms.js @@ -94,20 +94,22 @@ getInstalledApps : () => { }); }, removeApp : app => { // expects an appid.info structure (i.e. with `files`) - if (!app.files && !app.dataFiles && !app.storageFiles) return Promise.resolve(); // nothing to erase + if (!app.files && !app.data) return Promise.resolve(); // nothing to erase Progress.show({title:`Removing ${app.name}`,sticky:true}); let cmds = '\x10const s=require("Storage");\n'; - // remove App files (regular files, exact names only) + // remove App files: regular files, exact names only cmds += app.files.split(',').map(file => `\x10s.erase(${toJS(file)});\n`).join(""); - // remove Data files (regular files, can use wildcards) - cmds += (app.dataFiles||[]).split(',').map(file => { + // remove app Data: (dataFiles and storageFiles) + const data = AppInfo.parseDataString(app.data) + // regular files, can use wildcards + cmds += data.dataFiles.map(file => { const isGlob = (file.includes('*') || file.includes('?')) if (!isGlob) return `\x10s.erase(${toJS(file)});\n`; const regex = new RegExp(globToRegex(file)) return `\x10s.list(${regex}).forEach(f=>s.erase(f));\n`; }).join(""); - // remove Storage files (storageFiles, can use wildcards) - cmds += (app.storageFiles||[]).split(',').map(file => { + // storageFiles, can use wildcards + cmds += data.storageFiles.map(file => { const isGlob = (file.includes('*') || file.includes('?')) if (!isGlob) return `\x10s.open(${toJS(file)},'r').erase();\n`; // storageFiles have a chunk number appended to their real name diff --git a/js/index.js b/js/index.js index c48920315..41a43730e 100644 --- a/js/index.js +++ b/js/index.js @@ -349,19 +349,17 @@ function updateApp(app) { .filter(f => f !== app.id + '.info') .filter(f => !app.storage.some(s => s.name === f)) .join(','); - let dataFiles = (remove.dataFiles||'').split(','), - storageFiles = (remove.storageFiles||'').split(',') + let data = AppInfo.parseDataString(remove.data) if ('data' in app) { - // keep declared (in new version) data files - dataFiles = dataFiles.filter(f => app.data.some(d => (d.name||d.wildcard) === f)) - storageFiles = storageFiles.filter(f => app.data.some(d => (d.name||d.wildcard) === f)) - } - else if (remove.settings || app.settings) { + // only remove data files which are no longer declared in new app version + const removeData = (f) => !app.data.some(d => (d.name || d.wildcard)===f) + data.dataFiles = data.dataFiles.filter(removeData) + data.storageFiles = data.storageFiles.filter(removeData) + } else if (remove.settings || app.settings) { // app with settings but no data files declared: keep .settings.json - dataFiles = dataFiles.filter(f => f !== (app.id + '.settings.json')) + data.dataFiles = data.dataFiles.filter(f => f!==(app.id+'.settings.json')) } - if (dataFiles.length) remove.dataFiles = dataFiles.join(','); - if (storageFiles.length) remove.storageFiles = storageFiles.join(',') + remove.data = AppInfo.makeDataString(data) return Comms.removeApp(remove); }).then(()=>{ showToast(`Updating ${app.name}...`); From 3e5cfcdc12cdaadbf5f761ea2883905ca8ad4583 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Thu, 16 Apr 2020 14:32:42 +0200 Subject: [PATCH 011/878] Fixed home button and added readme for WOHRM --- apps.json | 1 + apps/wohrm/ChangeLog | 1 + apps/wohrm/README.md | 29 +++++++++++++++++++++++++++++ apps/wohrm/app.js | 7 ++----- 4 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 apps/wohrm/README.md diff --git a/apps.json b/apps.json index 899eed03e..459ecb3ab 100644 --- a/apps.json +++ b/apps.json @@ -891,6 +891,7 @@ "name": "Workout HRM", "icon": "app.png", "version":"0.06", + "readme": "README.md", "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", "tags": "hrm,workout", "type": "app", diff --git a/apps/wohrm/ChangeLog b/apps/wohrm/ChangeLog index f5c64dbee..53c451bcd 100644 --- a/apps/wohrm/ChangeLog +++ b/apps/wohrm/ChangeLog @@ -4,3 +4,4 @@ 0.04: Only buzz on high confidence (>85%) 0.05: Improved buzz timing and rendering 0.06: Removed debug outputs, fixed rendering for upper limit, improved rendering for +/- icons, changelog version order fixed +0.07: Home button fixed and README added \ No newline at end of file diff --git a/apps/wohrm/README.md b/apps/wohrm/README.md new file mode 100644 index 000000000..ad9e82525 --- /dev/null +++ b/apps/wohrm/README.md @@ -0,0 +1,29 @@ +# Summary +Workout heart rate monitor that buzzes when your heart rate hits the limits. + +This app is for the [Bangle.js watch](https://banglejs.com/). While active it monitors your heart rate +and will notify you with a buzz whenever your heart rate falls below or jumps above the set limits. + +# How it works +[Try it out](https://www.espruino.com/ide/emulator.html?codeurl=https://raw.githubusercontent.com/msdeibel/BangleApps/master/apps/wohrm/app.js&upload) using the [online Espruino emulator](https://www.espruino.com/ide/emulator.html). + +## Setting the limits +For setting the lower limit press button 4 (left part of the watch's touch screen). +Then adjust the value with the buttons 1 (top) and 3 (bottom) of the watch. + +For setting the upper limit act accordingly after pressing button 5 (the right part of the watch's screen). + +## Reading Reliability +As per the specs of the watch the HR monitor is not 100% reliable all the time. +That's why the WOHRM displays a confidence value for each reading of the current heart rate. + +To the left and right of the "Current" value two colored bars indicate the confidence in +the received value: For 85% and above the bars are green, between 84% and 50% the bars are yellow +and below 50% they turn red. + +## Closing the app +Pressing button 2 (middle) will switch off the HRM of the watch and return you to the launcher. + +# HRM usage +The HRM is switched on when the app is started. It stays switch on while the app is running, even +when the watch screen goes to stand-by. diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index 7e0af4219..b3ce8acc8 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -287,13 +287,11 @@ function resetHighlightTimeout() { setterHighlightTimeout = setTimeout(setLimitSetterToNone, 2000); } -// Show launcher when middle button pressed function switchOffApp(){ Bangle.setHRMPower(0); Bangle.showLauncher(); } -// special function to handle display switch on Bangle.on('lcdPower', (on) => { g.clear(); if (on) { @@ -312,19 +310,18 @@ Bangle.setHRMPower(1); Bangle.on('HRM', onHrm); setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); -setWatch(switchOffApp, BTN2, {edge:"rising", debounce:50, repeat:true}); setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); +setWatch(switchOffApp, BTN2, {edge:"falling", debounce:50, repeat:true}); + g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); -//drawTrainingHeartRate(); renderHomeIcon(); renderLowerLimitBackground(); renderUpperLimitBackground(); -// refesh every sec setInterval(drawTrainingHeartRate, 1000); From 9f0adf190019b5dd0bcef5f713c34dabd8ca1c3d Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Thu, 16 Apr 2020 17:06:25 +0200 Subject: [PATCH 012/878] Data files: remove settings magic, some more sanitychecks --- README.md | 13 +++++---- bin/sanitycheck.js | 69 ++++++++++++++++++++++++++++++++++++++++------ js/appinfo.js | 9 ++---- js/comms.js | 7 ++--- js/index.js | 3 -- 5 files changed, 73 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index a04ee95b2..a45647daf 100644 --- a/README.md +++ b/README.md @@ -263,9 +263,6 @@ and which gives information about the app for the Launcher. * tags is used for grouping apps in the library, separate multiple entries by comma. Known tags are `tool`, `system`, `clock`, `game`, `sound`, `gps`, `widget`, `launcher` or empty. * storage is used to identify the app files and how to handle them * data is used to clean up files when the app is uninstalled - (If the app has settings but no data section, it is assumed settings are - stored in `appid.settings.json`, so there is no need to add a data section - containing only that file) ### `apps.json`: `custom` element @@ -351,10 +348,10 @@ Example `settings.js` ```js // make sure to enclose the function in parentheses (function(back) { - let settings = require('Storage').readJSON('app.settings.json',1)||{}; + let settings = require('Storage').readJSON('app.json',1)||{}; function save(key, value) { settings[key] = value; - require('Storage').write('app.settings.json',settings); + require('Storage').write('app.json',settings); } const appMenu = { '': {'title': 'App Settings'}, @@ -367,13 +364,17 @@ Example `settings.js` E.showMenu(appMenu) }) ``` -In this example the app needs to add `app.settings.js` to `apps.json`: +In this example the app needs to add `app.settings.js` to `storage` in `apps.json`. +It should also add `app.json` to `data`, to make sure it is cleaned up when the app is uninstalled. ```json { "id": "app", ... "storage": [ ... {"name":"app.settings.js","url":"settings.js"}, + ], + "data": [ + {"name":"app.json"} ] }, ``` diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index 197ebf57e..51230f6fa 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -43,7 +43,22 @@ const APP_KEYS = [ ]; const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate']; const DATA_KEYS = ['name', 'wildcard', 'storageFile']; +const FORBIDDEN_FILE_NAME_CHARS = /[,;]/; // used as separators in appid.info +function globToRegex(pattern) { + const ESCAPE = '.*+-?^${}()|[]\\'; + const regex = pattern.replace(/./g, c => { + switch (c) { + case '?': return '.'; + case '*': return '.*'; + default: return ESCAPE.includes(c) ? ('\\' + c) : c; + } + }); + return new RegExp('^'+regex+'$'); +} +const isGlob = f => /[?*]/.test(f) +// All storage+data files in all apps: {app:,[file: | data:]} +let allFiles = []; apps.forEach((app,appIdx) => { if (!app.id) ERROR(`App ${appIdx} has no id`); //console.log(`Checking ${app.id}...`); @@ -75,11 +90,13 @@ apps.forEach((app,appIdx) => { var fileNames = []; app.storage.forEach((file) => { if (!file.name) ERROR(`App ${app.id} has a file with no name`); - if (file.name.includes('?') || file.name.includes('*')) - ERROR(`App ${app.id} storage file ${file.name} contains wildcards`); + if (isGlob(file.name)) ERROR(`App ${app.id} storage file ${file.name} contains wildcards`); + let char = file.name.match(FORBIDDEN_FILE_NAME_CHARS) + if (char) ERROR(`App ${app.id} storage file ${file.name} contains invalid character "${char[0]}"`) if (fileNames.includes(file.name)) ERROR(`App ${app.id} file ${file.name} is a duplicate`); fileNames.push(file.name); + allFiles.push({app: app.id, file: file.name}); if (file.url) if (!fs.existsSync(appDir+file.url)) ERROR(`App ${app.id} file ${file.url} doesn't exist`); if (!file.url && !file.content && !app.custom) ERROR(`App ${app.id} file ${file.name} has no contents`); var fileContents = ""; @@ -124,14 +141,13 @@ apps.forEach((app,appIdx) => { if (dataNames.includes(data.name||data.wildcard)) ERROR(`App ${app.id} data file ${data.name||data.wildcard} is a duplicate`); dataNames.push(data.name||data.wildcard) + allFiles.push({app: app.id, data: (data.name||data.wildcard)}); if ('name' in data && 'wildcard' in data) ERROR(`App ${app.id} data file ${data.name} has both name and wildcard`); - if (data.name) { - if (data.name.includes('?') || data.name.includes('*')) - ERROR(`App ${app.id} data file name ${data.name} contains wildcards`); - } + if (isGlob(data.name)) + ERROR(`App ${app.id} data file name ${data.name} contains wildcards`); if (data.wildcard) { - if (!data.wildcard.includes('?') && !data.wildcard.includes('*')) + if (!isGlob(data.wildcard)) ERROR(`App ${app.id} data file wildcard ${data.wildcard} does not actually contains wildcard`); if (data.wildcard.replace(/\?|\*/g,'') === '') ERROR(`App ${app.id} data file wildcard ${data.wildcard} does not contain regular characters`); @@ -140,6 +156,8 @@ apps.forEach((app,appIdx) => { else if (!data.wildcard.includes(app.id)) WARN(`App ${app.id} data file wildcard ${data.wildcard} does not include app ID`); } + let char = (data.name||data.wildcard).match(FORBIDDEN_FILE_NAME_CHARS) + if (char) ERROR(`App ${app.id} data file ${data.name||data.wildcard} contains invalid character "${char[0]}"`) if ('storageFile' in data && typeof data.storageFile !== 'boolean') ERROR(`App ${app.id} data file ${data.name||data.wildcard} has non-boolean value for "storageFile"`); for (const key in data) { @@ -147,8 +165,24 @@ apps.forEach((app,appIdx) => { ERROR(`App ${app.id} data file ${data.name||data.wildcard} has unknown property "${key}"`); } }); - if (fileNames.includes(app.id+".settings.js") && dataNames.length===1 && dataNames[0] === app.id+'.settings.json') - WARN(`App ${app.id} has settings, so does not need to declare data file ${app.id+'.settings.json'}`) + // prefer "appid.json" over "appid.settings.json" (TODO: change to ERROR once all apps comply?) + if (dataNames.includes(app.id+".settings.json") && !dataNames.includes(app.id+".json")) + WARN(`App ${app.id} uses data file ${app.id+'.settings.json'} instead of ${app.id+'.json'}`) + // settings files should be listed under data, not storage (TODO: change to ERROR once all apps comply?) + if (fileNames.includes(app.id+".settings.json")) + WARN(`App ${app.id} uses storage file ${app.id+'.settings.json'} instead of data file`) + if (fileNames.includes(app.id+".json")) + WARN(`App ${app.id} uses storage file ${app.id+'.json'} instead of data file`) + // warn if storage file matches data file of same app + dataNames.forEach(dataName=>{ + const glob = globToRegex(dataName) + fileNames.forEach(fileName=>{ + if (glob.test(fileName)) { + if (isGlob(dataName)) WARN(`App ${app.id} storage file ${fileName} matches data wildcard ${dataName}`) + else WARN(`App ${app.id} storage file ${fileName} is also listed in data`) + } + }) + }) //console.log(fileNames); if (isApp && !fileNames.includes(app.id+".app.js")) ERROR(`App ${app.id} has no entrypoint`); if (isApp && !fileNames.includes(app.id+".img")) ERROR(`App ${app.id} has no JS icon`); @@ -157,3 +191,20 @@ apps.forEach((app,appIdx) => { if (!APP_KEYS.includes(key)) ERROR(`App ${app.id} has unknown key ${key}`); } }); +// Do not allow files from different apps to collide +let fileA +while(fileA=allFiles.pop()) { + const nameA = (fileA.file||fileA.data), + globA = globToRegex(nameA), + typeA = fileA.file?'storage':'data' + allFiles.forEach(fileB => { + const nameB = (fileB.file||fileB.data), + globB = globToRegex(nameB), + typeB = fileB.file?'storage':'data' + if (globA.test(nameB)||globB.test(nameA)) { + if (isGlob(nameA)||isGlob(nameB)) + ERROR(`App ${fileB.app} ${typeB} file ${nameB} matches app ${fileA.app} ${typeB} file ${nameA}`) + else ERROR(`App ${fileB.app} ${typeB} file ${nameB} is also listed as ${typeA} file for app ${fileA.app}`) + } + }) +} diff --git a/js/appinfo.js b/js/appinfo.js index 413098bc4..56b6ff2f8 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -69,19 +69,16 @@ var AppInfo = { var fileList = fileContents.map(storageFile=>storageFile.name); fileList.unshift(appJSONName); // do we want this? makes life easier! json.files = fileList.join(","); - let data = {dataFiles: [], storageFiles: []}; if ('data' in app) { + let data = {dataFiles: [], storageFiles: []}; // add "data" files to appropriate list app.data.forEach(d=>{ if (d.storageFile) data.storageFiles.push(d.name||d.wildcard) else data.dataFiles.push(d.name||d.wildcard) }) - } else if (json.settings) { - // settings but no data files: assume app uses .settings.json file - data.dataFiles.push(app.id + '.settings.json') + const dataString = AppInfo.makeDataString(data) + if (dataString) json.data = dataString } - const dataString = AppInfo.makeDataString(data) - if (dataString) json.data = dataString fileContents.push({ name : appJSONName, content : JSON.stringify(json) diff --git a/js/comms.js b/js/comms.js index 736a2b7c7..b825a06ad 100644 --- a/js/comms.js +++ b/js/comms.js @@ -101,17 +101,16 @@ removeApp : app => { // expects an appid.info structure (i.e. with `files`) cmds += app.files.split(',').map(file => `\x10s.erase(${toJS(file)});\n`).join(""); // remove app Data: (dataFiles and storageFiles) const data = AppInfo.parseDataString(app.data) + const isGlob = f => /[?*]/.test(f) // regular files, can use wildcards cmds += data.dataFiles.map(file => { - const isGlob = (file.includes('*') || file.includes('?')) - if (!isGlob) return `\x10s.erase(${toJS(file)});\n`; + if (!isGlob(file)) return `\x10s.erase(${toJS(file)});\n`; const regex = new RegExp(globToRegex(file)) return `\x10s.list(${regex}).forEach(f=>s.erase(f));\n`; }).join(""); // storageFiles, can use wildcards cmds += data.storageFiles.map(file => { - const isGlob = (file.includes('*') || file.includes('?')) - if (!isGlob) return `\x10s.open(${toJS(file)},'r').erase();\n`; + if (!isGlob(file)) return `\x10s.open(${toJS(file)},'r').erase();\n`; // storageFiles have a chunk number appended to their real name const regex = globToRegex(file+'\u0001') // open() doesn't want the chunk number though diff --git a/js/index.js b/js/index.js index 41a43730e..483dc09c7 100644 --- a/js/index.js +++ b/js/index.js @@ -355,9 +355,6 @@ function updateApp(app) { const removeData = (f) => !app.data.some(d => (d.name || d.wildcard)===f) data.dataFiles = data.dataFiles.filter(removeData) data.storageFiles = data.storageFiles.filter(removeData) - } else if (remove.settings || app.settings) { - // app with settings but no data files declared: keep .settings.json - data.dataFiles = data.dataFiles.filter(f => f!==(app.id+'.settings.json')) } remove.data = AppInfo.makeDataString(data) return Comms.removeApp(remove); From 28d3a6eb1d8e5c19c489380eeae3f3310d9b11c6 Mon Sep 17 00:00:00 2001 From: Markus Date: Fri, 17 Apr 2020 12:29:40 +0200 Subject: [PATCH 013/878] Fix failing dismissal of Gadgetbridge messages --- apps/batchart/widget.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/apps/batchart/widget.js b/apps/batchart/widget.js index 1b8ce79ba..aa81c2c5b 100644 --- a/apps/batchart/widget.js +++ b/apps/batchart/widget.js @@ -71,8 +71,9 @@ enabledConsumers = enabledConsumers | switchableConsumers.gps; if (hrmEventReceived) enabledConsumers = enabledConsumers | switchableConsumers.hrm; - //if (Bangle.isBluetoothOn()) - // enabledConsumers = enabledConsumers | switchableConsumers.bluetooth; + // First, coarse indication if the bluetooth device is enabled + if (NodeFilter.getSecuritystatus().connected) + enabledConsumers = enabledConsumers | switchableConsumers.bluetooth; // Reset the event registration vars compassEventReceived = false; @@ -110,19 +111,14 @@ } function reload() { - WIDGETS.batchart.width = 24; + WIDGETS["batchart"].width = 24; recordingInterval = setInterval(logBatteryData, recordingInterval10Min); - - logBatteryData(); } // add the widget - WIDGETS.batchart = { - area: "tl", width: 24, draw: draw, reload: function () { - reload(); - Bangle.drawWidgets(); - } + WIDGETS["batchart"] = { + area: "tl", width: 24, draw: draw, reload: reload }; reload(); From 933ce770950524599a28fc5ce93009c697d3577a Mon Sep 17 00:00:00 2001 From: Markus Date: Fri, 17 Apr 2020 12:33:26 +0200 Subject: [PATCH 014/878] Enable graphing of the bluetooth state, update version info --- apps.json | 2 +- apps/batchart/ChangeLog | 3 ++- apps/batchart/app.js | 16 ++++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/apps.json b/apps.json index bbe0bbfcd..80c771c08 100644 --- a/apps.json +++ b/apps.json @@ -1194,7 +1194,7 @@ "name": "Battery Chart", "shortName":"Battery Chart", "icon": "app.png", - "version":"0.08", + "version":"0.09", "readme": "README.md", "description": "A widget and an app for recording and visualizing battery percentage over time.", "tags": "app,widget,battery,time,record,chart,tool", diff --git a/apps/batchart/ChangeLog b/apps/batchart/ChangeLog index 439d877be..66b40fbbf 100644 --- a/apps/batchart/ChangeLog +++ b/apps/batchart/ChangeLog @@ -5,4 +5,5 @@ 0.05: Display temperature and LCD state in chart 0.06: Fixes widget events and charting of component states 0.07: Improve logging and charting of component states and add widget icon -0.08: Fix for Home button in the app and README added. \ No newline at end of file +0.08: Fix for Home button in the app and README added. +0.09: Fix failing dismissal of Gadgetbridge notifications, record (coarse) bluetooth state \ No newline at end of file diff --git a/apps/batchart/app.js b/apps/batchart/app.js index 2d0d8e585..472fb3a8a 100644 --- a/apps/batchart/app.js +++ b/apps/batchart/app.js @@ -8,7 +8,7 @@ const GraphXMax = GraphXZero + MaxValueCount; const GraphLcdY = GraphYZero + 10; const GraphCompassY = GraphYZero + 16; -// const GraphBluetoothY = GraphYZero + 22; +const GraphBluetoothY = GraphYZero + 22; const GraphGpsY = GraphYZero + 28; const GraphHrmY = GraphYZero + 34; @@ -175,13 +175,13 @@ function renderData(dataArray) { g.drawLine(GraphXZero + i, GraphCompassY, GraphXZero + i, GraphCompassY + 1); } - // // Bluetooth state - // if (switchables & switchableConsumers.lcd == switchableConsumers.lcd) { - // g.setColor(0, 0, 1); - // g.setFontAlign(1, -1, 0); - // g.drawString("BLE", GraphXZero - GraphMarkerOffset, GraphBluetoothY - 2, true); - // g.drawLine(GraphXZero + i, GraphBluetoothY, GraphXZero + i, GraphBluetoothY + 1); - // } + // Bluetooth state + if (parseInt(dataInfo[switchabelsIndex]) & switchableConsumers.bluetooth) { + g.setColor(0, 0, 1); + g.setFontAlign(1, -1, 0); + g.drawString("BLE", GraphXZero - GraphMarkerOffset, GraphBluetoothY - 2, true); + g.drawLine(GraphXZero + i, GraphBluetoothY, GraphXZero + i, GraphBluetoothY + 1); + } // Gps state if (parseInt(dataInfo[switchabelsIndex]) & switchableConsumers.gps) { From 5782fa143957eee7714ca3212d1b2338b9d04b2b Mon Sep 17 00:00:00 2001 From: Markus Date: Fri, 17 Apr 2020 12:43:21 +0200 Subject: [PATCH 015/878] Use correct casing for getSecurityStatusMethod --- apps/batchart/widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/batchart/widget.js b/apps/batchart/widget.js index aa81c2c5b..2b00a83e2 100644 --- a/apps/batchart/widget.js +++ b/apps/batchart/widget.js @@ -72,7 +72,7 @@ if (hrmEventReceived) enabledConsumers = enabledConsumers | switchableConsumers.hrm; // First, coarse indication if the bluetooth device is enabled - if (NodeFilter.getSecuritystatus().connected) + if (NRF.getSecurityStatus().connected)) enabledConsumers = enabledConsumers | switchableConsumers.bluetooth; // Reset the event registration vars From 0c129bb10adc80db9d5cd791e0757356524360d0 Mon Sep 17 00:00:00 2001 From: Markus Date: Fri, 17 Apr 2020 12:45:13 +0200 Subject: [PATCH 016/878] Fix wrong ) --- apps/batchart/widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/batchart/widget.js b/apps/batchart/widget.js index 2b00a83e2..808c7781c 100644 --- a/apps/batchart/widget.js +++ b/apps/batchart/widget.js @@ -72,7 +72,7 @@ if (hrmEventReceived) enabledConsumers = enabledConsumers | switchableConsumers.hrm; // First, coarse indication if the bluetooth device is enabled - if (NRF.getSecurityStatus().connected)) + if (NRF.getSecurityStatus().connected) enabledConsumers = enabledConsumers | switchableConsumers.bluetooth; // Reset the event registration vars From 372f5123f4fe611284d0f6f5fc5a09d30a585ae8 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Fri, 17 Apr 2020 15:55:41 +0200 Subject: [PATCH 017/878] chronowid 0.02 --- apps/chronowid/ChangeLog | 3 ++- apps/chronowid/README.md | 9 ++++++--- apps/chronowid/app.js | 11 +++++++++-- apps/chronowid/widget.js | 18 +++++++++--------- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/apps/chronowid/ChangeLog b/apps/chronowid/ChangeLog index a6f342f01..263145407 100644 --- a/apps/chronowid/ChangeLog +++ b/apps/chronowid/ChangeLog @@ -1 +1,2 @@ -0.01: New widget and app! +0.01: New widget and app! +0.02: Setting to reset values, timer buzzes at 00:00 and not later (see readme) \ No newline at end of file diff --git a/apps/chronowid/README.md b/apps/chronowid/README.md index f31c24c7b..f422dd956 100644 --- a/apps/chronowid/README.md +++ b/apps/chronowid/README.md @@ -5,6 +5,8 @@ The advantage is, that you can still see your normal watchface and other widgets The widget is always active, but only shown when the timer is on. Hours, minutes, seconds and timer status can be set with an app. +Depending on when you start the timer, it may alert up to 0,999 seconds early. This is because it checks only for full seconds. When there is less than one seconds left, it buzzes. This cannot be avoided without checking more than every second, which I would like to avoid. + ## Screenshots TBD @@ -18,18 +20,19 @@ TBD There are no settings section in the settings app, timer can be set using an app. +* Reset values: Reset hours, minutes, seconds to 0; set timer on to false; write to settings file * Hours: Set the hours for the timer * Minutes: Set the minutes for the timer * Seconds: Set the seconds for the timer -* Timer on: Starts the timer and displays the widget when set to 'On'. You have to leave the app. The widget is always there, but only visible when timer is on. +* Timer on: Starts the timer and displays the widget when set to 'On'. You have to leave the app to load the widget which starts the timer. The widget is always there, but only visible when timer is on. ## Releases -* Offifical app loader: Not yet published. +* Offifical app loader: https://github.com/espruino/BangleApps/tree/master/apps/chronowid (https://banglejs.com/apps/) * Forked app loader: https://github.com/Purple-Tentacle/BangleApps/tree/master/apps/chronowid (https://purple-tentacle.github.io/BangleApps/index.html#) * Development: https://github.com/Purple-Tentacle/BangleAppsDev/tree/master/apps/chronowid ## Requests -If you have any feature requests, please contact me on the Espruino forum: http://forum.espruino.com/profiles/155005/ \ No newline at end of file +If you have any feature requests, please write here: http://forum.espruino.com/conversations/345972/ \ No newline at end of file diff --git a/apps/chronowid/app.js b/apps/chronowid/app.js index 48401a7bb..dd9531233 100644 --- a/apps/chronowid/app.js +++ b/apps/chronowid/app.js @@ -30,7 +30,6 @@ settingsChronowid = storage.readJSON('chronowid.json',1); if (!settingsChronowid) resetSettings(); E.on('kill', () => { - print("-KILL-"); updateSettings(); }); @@ -45,6 +44,14 @@ function showMenu() { timerMenu.started.value = settingsChronowid.started; } }, + 'Reset values': function() { + settingsChronowid.hours = 0; + settingsChronowid.minutes = 0; + settingsChronowid.seconds = 0; + settingsChronowid.started = false; + updateSettings(); + showMenu(); + }, 'Hours': { value: settingsChronowid.hours, min: 0, @@ -88,4 +95,4 @@ function showMenu() { return E.showMenu(timerMenu); } -showMenu(); +showMenu(); \ No newline at end of file diff --git a/apps/chronowid/widget.js b/apps/chronowid/widget.js index 708bc6345..557104d92 100644 --- a/apps/chronowid/widget.js +++ b/apps/chronowid/widget.js @@ -36,19 +36,18 @@ //counts down, calculates and displays function countDown() { - //printDebug(); now = new Date(); diff = settingsChronowid.goal - now; //calculate difference WIDGETS["chronowid"].draw(); //time is up - if (settingsChronowid.started && diff <= 0) { + if (settingsChronowid.started && diff < 1000) { Bangle.buzz(1500); //write timer off to file settingsChronowid.started = false; storage.writeJSON('chronowid.json', settingsChronowid); clearInterval(interval); //stop interval - //printDebug(); } + //printDebug(); } // draw your widget @@ -72,12 +71,13 @@ g.drawString(getTime(diff), this.x+1, this.y+((height/2)-4)); //display hour 00:00:00 } } - else { - width = 58; - g.clearRect(this.x,this.y,this.x+width,this.y+height); - g.setFont("6x8", 2); - g.drawString("END", this.x+15, this.y+5); - } + // not needed anymoe, because we check if diff < 1000 now, so 00:00 is displayed. + // else { + // width = 58; + // g.clearRect(this.x,this.y,this.x+width,this.y+height); + // g.setFont("6x8", 2); + // g.drawString("END", this.x+15, this.y+5); + // } } if (settingsChronowid.started) interval = setInterval(countDown, 1000); //start countdown each second From dcb2a6c2d9b4f327796a3aaec53a43e33e4d715d Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Fri, 17 Apr 2020 15:56:55 +0200 Subject: [PATCH 018/878] chronowid 0.02 --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 447d45154..e2b20cca4 100644 --- a/apps.json +++ b/apps.json @@ -1142,7 +1142,7 @@ "name": "Chrono Widget", "shortName":"Chrono Widget", "icon": "app.png", - "version":"0.01", + "version":"0.02", "description": "Chronometer (timer) which runs as widget.", "tags": "tools,widget", "readme": "README.md", From 9a664ecae4b9b64a7f9e773ff43adbd62c0ab3fa Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Fri, 17 Apr 2020 16:38:33 +0200 Subject: [PATCH 019/878] Compass: 0.02 --- apps/compass/ChangeLog | 2 ++ apps/compass/compass.js | 77 +++++++++++++++++++++++------------------ 2 files changed, 45 insertions(+), 34 deletions(-) create mode 100644 apps/compass/ChangeLog diff --git a/apps/compass/ChangeLog b/apps/compass/ChangeLog new file mode 100644 index 000000000..efd778c72 --- /dev/null +++ b/apps/compass/ChangeLog @@ -0,0 +1,2 @@ +0.01: New App! +0.02: Show text if uncalibrated \ No newline at end of file diff --git a/apps/compass/compass.js b/apps/compass/compass.js index 10895e3cd..a014d79ff 100644 --- a/apps/compass/compass.js +++ b/apps/compass/compass.js @@ -1,34 +1,43 @@ -g.clear(); -g.setColor(0,0.5,1); -g.fillCircle(120,130,80,80); -g.setColor(0,0,0); -g.fillCircle(120,130,70,70); - -function arrow(r,c) { - r=r*Math.PI/180; - var p = Math.PI/2; - g.setColor(c); - g.fillPoly([ - 120+60*Math.sin(r), 130-60*Math.cos(r), - 120+10*Math.sin(r+p), 130-10*Math.cos(r+p), - 120+10*Math.sin(r+-p), 130-10*Math.cos(r-p), - ]); -} - -var oldHeading = 0; -Bangle.on('mag', function(m) { - if (!Bangle.isLCDOn()) return; - g.setFont("6x8",3); - g.setColor(0); - g.fillRect(70,0,170,24); - g.setColor(0xffff); - g.setFontAlign(0,0); - g.drawString(isNaN(m.heading)?"---":Math.round(m.heading),120,12); - g.setColor(0,0,0); - arrow(oldHeading,0); - arrow(oldHeading+180,0); - arrow(m.heading,0xF800); - arrow(m.heading+180,0x001F); - oldHeading = m.heading; -}); -Bangle.setCompassPower(1); +g.clear(); +g.setColor(0,0.5,1); +g.fillCircle(120,130,80,80); +g.setColor(0,0,0); +g.fillCircle(120,130,70,70); + +function arrow(r,c) { + r=r*Math.PI/180; + var p = Math.PI/2; + g.setColor(c); + g.fillPoly([ + 120+60*Math.sin(r), 130-60*Math.cos(r), + 120+10*Math.sin(r+p), 130-10*Math.cos(r+p), + 120+10*Math.sin(r+-p), 130-10*Math.cos(r-p), + ]); +} + +var oldHeading = 0; +Bangle.on('mag', function(m) { + if (!Bangle.isLCDOn()) return; + g.setFont("6x8",3); + g.setColor(0); + g.fillRect(0,0,230,40); + g.setColor(0xffff); + if (isNaN(m.heading)) { + g.setFontAlign(-1,-1); + g.setFont("6x8",2); + g.drawString("Uncalibrated",50,12); + g.drawString("turn 360° around",25,26); + } + else { + g.setFontAlign(0,0); + g.setFont("6x8",3); + g.drawString(Math.round(m.heading),120,12); + } + g.setColor(0,0,0); + arrow(oldHeading,0); + arrow(oldHeading+180,0); + arrow(m.heading,0xF800); + arrow(m.heading+180,0x001F); + oldHeading = m.heading; +}); +Bangle.setCompassPower(1); From 1017090cbe5fc6fb42101a0544fdd6e8ada983d0 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Fri, 17 Apr 2020 16:40:25 +0200 Subject: [PATCH 020/878] compass 0.02 --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index e2b20cca4..d7bd6a7a1 100644 --- a/apps.json +++ b/apps.json @@ -235,7 +235,7 @@ { "id": "compass", "name": "Compass", "icon": "compass.png", - "version":"0.01", + "version":"0.02", "description": "Simple compass that points North", "tags": "tool,outdoors", "storage": [ From 1fff62e48da25d2455294643ac66321033088c76 Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 17 Apr 2020 16:55:35 +0200 Subject: [PATCH 021/878] init hid camera app --- apps/hidcam/ChangeLog | 1 + apps/hidcam/add_to_apps.json | 13 +++++++++++++ apps/hidcam/app-icon.js | 1 + apps/hidcam/app.js | 12 ++++++++++++ apps/hidcam/app.png | Bin 0 -> 1620 bytes 5 files changed, 27 insertions(+) create mode 100644 apps/hidcam/ChangeLog create mode 100644 apps/hidcam/add_to_apps.json create mode 100644 apps/hidcam/app-icon.js create mode 100644 apps/hidcam/app.js create mode 100644 apps/hidcam/app.png diff --git a/apps/hidcam/ChangeLog b/apps/hidcam/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/hidcam/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/hidcam/add_to_apps.json b/apps/hidcam/add_to_apps.json new file mode 100644 index 000000000..ca75a7bd8 --- /dev/null +++ b/apps/hidcam/add_to_apps.json @@ -0,0 +1,13 @@ +// Create an entry in apps.json as follows: +{ "id": "7chname", + "name": "My app's human readable name", + "shortName":"Short Name", + "icon": "app.png", + "version":"0.01", + "description": "A detailed description of my great app", + "tags": "", + "storage": [ + {"name":"7chname.app.js","url":"app.js"}, + {"name":"7chname.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/hidcam/app-icon.js b/apps/hidcam/app-icon.js new file mode 100644 index 000000000..49232b838 --- /dev/null +++ b/apps/hidcam/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA==")) diff --git a/apps/hidcam/app.js b/apps/hidcam/app.js new file mode 100644 index 000000000..af367779a --- /dev/null +++ b/apps/hidcam/app.js @@ -0,0 +1,12 @@ +// place your const, vars, functions or classes here + +// special function to handle display switch on +Bangle.on('lcdPower', (on) => { + if (on) { + // call your app function here + // If you clear the screen, do Bangle.drawWidgets(); + } +}); + +g.clear(); +// call your app function here diff --git a/apps/hidcam/app.png b/apps/hidcam/app.png new file mode 100644 index 0000000000000000000000000000000000000000..582cb2e0853a5a2899a3afbd7eb19cde2ee7f6a0 GIT binary patch literal 1620 zcmV-a2CMmrP)1gXjloC|3_d8m;N2OpV(|i0q4YwBna<2! zK9thw%-*|urnNbV{Gax^?eD+#{x0kLJ~)lj_;W+1>qV*k8akT^^dvctZccUyj4}H~#M%Wwee_v` zHMv7o%BM8@dBrLshn{wGD9BDl?^eV5vSM3T96;NnHvtc6La=(qzq)xrX1d8bK-TN- zrd_f$_O`9nEmS+_S7HTXK<&u;LDIW|qlN&KJvM}tt6TVVqL-AvNv`B*{NzNpBfSQwQP5~Sf(Dp@Vq1+3Q`N9wBQN2`J_?M^u0FIMlt?p^8 z%U3%80kIwg!T{E9<8J18S&$k1`eO)@HP+=TZKo(z3_A3VFYJB=sn`2^Q$mRE>02(+W)np;)L1!GUvU2{O{<&F_nE6Qe#D~Xf|dD z+?d3-D1(IUiL`C2;PPv4CKw8H)v7h8^obJ&Z6D0CjVUe8Xq_NAymxUyPAMU^CCrIu z%1M71EC`5o2if_~7E&h??0jeQ1Y3N6p?}G72FmS*)xQD)%wBE=2tW6@(+MTi!fk9H1pWKew2(jTXVu4%vk26QvSQCbGmk`Z)Y! zBIhh)6vG2)h6mF8wC^|l$M(Eo9D?JiW}=_T2jUA>LC80foTera{^p)Wi`>}Gf;(|ZwEZQ zS^k|*9wyt=f4ZOo!xty7{%}HKD9tBZ50g$=%v&&vMa!#@Nsf>EkEEDA*ST6fiC+An zsNK1#>!x0obq@j$QqYU-ad3ZvbjqUU+%iw(0WahgmHV6yeLWqoYkSl4pzFQ(_Vp&I ztO{WI-48rGLwQb?#vgVvduyd9_6W)rFRoQJq3I(J?{Xmin45#=3l9BmL6Bp<*MZej zrsWN7oRPUr7IvrHoIHOjS=gPTCw>d)^LQK+B|=f2qbGjrWaOd5D<<9Dv>MTW0X3z> zyPy}9`<>1~?NCx@m8G$_@rRTy5zH12YM&P)=tU+L^fgY z^0Z&_6^qdVuwgN3wt_Ze(10?J@%{C2grBk42hsu74qEo^nd&v`X`IHN9lrxzS~GeF S(*#!l0000 Date: Fri, 17 Apr 2020 18:56:38 +0200 Subject: [PATCH 022/878] app code and config --- apps/hidcam/ChangeLog | 2 +- apps/hidcam/add_to_apps.json | 13 ------------- apps/hidcam/app-icon.js | 2 +- apps/hidcam/app.js | 12 ------------ apps/hidcam/app.png | Bin 1620 -> 1425 bytes apps/hidcam/hidcam.app.js | 28 ++++++++++++++++++++++++++++ apps/hidcam/hidcam.app.json | 13 +++++++++++++ 7 files changed, 43 insertions(+), 27 deletions(-) delete mode 100644 apps/hidcam/add_to_apps.json delete mode 100644 apps/hidcam/app.js create mode 100644 apps/hidcam/hidcam.app.js create mode 100644 apps/hidcam/hidcam.app.json diff --git a/apps/hidcam/ChangeLog b/apps/hidcam/ChangeLog index 5560f00bc..665c0df6e 100644 --- a/apps/hidcam/ChangeLog +++ b/apps/hidcam/ChangeLog @@ -1 +1 @@ -0.01: New App! +0.01: Init diff --git a/apps/hidcam/add_to_apps.json b/apps/hidcam/add_to_apps.json deleted file mode 100644 index ca75a7bd8..000000000 --- a/apps/hidcam/add_to_apps.json +++ /dev/null @@ -1,13 +0,0 @@ -// Create an entry in apps.json as follows: -{ "id": "7chname", - "name": "My app's human readable name", - "shortName":"Short Name", - "icon": "app.png", - "version":"0.01", - "description": "A detailed description of my great app", - "tags": "", - "storage": [ - {"name":"7chname.app.js","url":"app.js"}, - {"name":"7chname.img","url":"app-icon.js","evaluate":true} - ] -} diff --git a/apps/hidcam/app-icon.js b/apps/hidcam/app-icon.js index 49232b838..aa9d5e194 100644 --- a/apps/hidcam/app-icon.js +++ b/apps/hidcam/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA==")) +E.toArrayBuffer(atob("MDCEAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERERERETMzMzMzMzMzMzMzMzMzMzMzMRERERERERMzMzMzMzMzMzMzMzMzMzMzMREREREREREzMzMzMzMzMzMzMzMAAAAzEREREREREREzMzMzMzMzMzMzMzMAAAAxERERERERERETMzMzMzMzMzMzMxERERERERERERERERERERERETMzMzMzMRERERERERERERERERERERERERMzMzMzEREREREREREAAAAAEREREREREREzMzMzEREREREREQAAAAAAABERESIiIREzMzMzEREREREREAAAAAAAAAERESIiIREzMzMzEREREREQAAAKqqqgAAABESIiIREzMzMzEREREREQAAqqqqqqoAABESIiIREzMzMzEREREREAAKqqqqqqqgAAEREREREzMzMzERERERAACqqqqqqqqqAAAREREREzMzMzERERERAAqqqiIiIqqqoAAREREREzMzMzqqqqqgAAqqoiIiIiKqoAAKqqqqozMzMzqqqqqgAKqqIiIiIiKqqgAKqqqqozMzMzqqqqqgAKqqIiqqqiKqqgAKqqqqozMzMzqqqqqgAKqqqqqqqqqqqgAKqqqqozMzMzqqqqqgAKqqqqqqqqqqqgAKqqqqozMzMzqqqqqgAKqqqqqqqqqqqgAKqqqqozMzMzqqqqqgAKqqqqqqqqqqqgAKqqqqozMzMzqqqqqgAAqqqqqqqqqqoAAKqqqqozMzMzqqqqqqAAqqqqqqqqqqoACqqqqqozMzMzqqqqqqAACqqqqqqqqqAACqqqqqozMzMzqqqqqqoAAKqqqqqqqgAAqqqqqqozMzMzqqqqqqoAAAqqqqqqoAAAqqqqqqozMzMzqqqqqqqgAAAKqqqgAAAKqqqqqqozMzMzqqqqqqqqAAAAAAAAAACqqqqqqqozMzMzqqqqqqqqqgAAAAAAAKqqqqqqqqozMzMzqqqqqqqqqqoAAAAAqqqqqqqqqqozMzMzOqqqqqqqqqqqqqqqqqqqqqqqqqMzMzMzM6qqqqqqqqqqqqqqqqqqqqqqqjMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMw==")) diff --git a/apps/hidcam/app.js b/apps/hidcam/app.js deleted file mode 100644 index af367779a..000000000 --- a/apps/hidcam/app.js +++ /dev/null @@ -1,12 +0,0 @@ -// place your const, vars, functions or classes here - -// special function to handle display switch on -Bangle.on('lcdPower', (on) => { - if (on) { - // call your app function here - // If you clear the screen, do Bangle.drawWidgets(); - } -}); - -g.clear(); -// call your app function here diff --git a/apps/hidcam/app.png b/apps/hidcam/app.png index 582cb2e0853a5a2899a3afbd7eb19cde2ee7f6a0..3f631a0d8c2c9a2f82ad03564f6e503e97ec3b74 100644 GIT binary patch delta 1389 zcmV-z1(N#I43P_vHGc(0Nkl2XW^HHNnRPdH7YVh3 zAi4-C0tqZh0&gNIp^K!1F0{>?F8ZK?L=!~R#889`D}{vAtGp@*QYh5@80TYmE$3rD zXXnhv+r_N&?d+VhW?jr54xID6@AEwW|9PMDejI3`i6)w8Vt*MB_an&A!4sV_lRgYQ z(U60bA)%^oee%v5e=Ilm@&!mKhW3ATK_WL9^bF=wV%=wZcFZg%y|Nrf4_+Hu9Ce*+^R zc(KwX1zV6(7k9~?h!Hyfbl2<$#^#4n_>Pe{25aG9oee=sBAVos>< zeZK4Uo0W}K0(Kub;#YIxcL|;c!>=(2h$%VihL7Ie9x1h3sya$#pG2A>uj?sd(I~Ss z(fP@7oD9euxgs&*b+QBp??8vTYo};@fk(eQ-ni7;;|S=S+iZ& zQ%oh|M8YB59uK{}eKm#b*!n`1?bz81c@c`J;#MU9gEb$E-r?5R7`a@wF$XD$N25$9 z;`H^e#@*T3crrpoc}d^j=`$FZd*5QTQ}=G&k&it!R5#a z5~;sHN+RJ9nx^6DT=C!p=z5AY=&?+XoiY$ z0cl;&&o+yA*7s@|d7*&A4IY2~>ga(^KeTm$wPd}uTO2&!yS?xnk48!Bx?urTB{Y8O zp}Gz;soP|d`93RsYw&MaTMTA}HgEpTmqCEmlE3B>kete!eU3qVk*5icj{q=sO~q-e zpMSp+hDSipOcn0eKC-^7&AFmTK9h#|DVU2xY93ges2m+&u@!v=RuyBUGRAk-hCkwT zHd(mu>FzIU%Vt2;Ai4OKOP92ymMNh=r@|E=O@~DvjMJ4404)_dY^MYJZcj2U)uHs1y5MFf2e3*24Yl+_d3@l_-s& zD%LtZ@4?5YgGDLMg^}9mAF27tr*+VQKx5Z z7#3i+xVd`{3XYEuniw^l^e(~^VJCsEUR|D=s!a{d|_>g7N8ZA(iCfm4ELF z&rVwxsxW@gF|`+JYw@Fq{E9U_6X*QpQ!J#COL!HrkVtXhxX+mFkcUw@=#W~T_>4sc`SYWX)K1a5mj_QiwG0~G+^w0W_p zHez$bVew zFhhQ-(okyzE&*GOL{)@^c6%>Q%}X*JXCa*+BNxbK^Lrar)vzjd>=rk6t!Bg2Yy*Jc zVx_5CfXEIZ)s29G-vxQ7iiXqX#cA`JBUl$AmdnVYN^4aKef`VU8(5UbfNwBZPX7|7 v5qz7=%BN2Lwq^LgCeuU{O*GNO{|o;Bs>Z}7R{Rfy00000NkvXXu0mjfd2ysS delta 1586 zcmV-22F>}A3)BpdHGc*PNklVsi@IIDWLJF z<-tS+MbQVNMvWngMiMVMF($}~PbV60iJqKGq6sl-z#5IgNDvG@D81m_8L(pU0#u>& zLWh~o%w9f}(&^0JyL+a!If?wA_PXuwzxMtv>-#=9jnnvZLw~00MXDHdHZ-F~E6@xy zAk0IFoNQ?rJ?=L3M zHi1NI%W6w_1%Iftvl|hOhaVrR!sN{2xw@hkSSKyk8akT z^^R7(Pu73-SLjz9%wK^oEKM9^v2d+uZBzb_ElWR@^923y?MQ5Sh3y}H359v|8R9g6# zr~d$slVYvzX{^gvI{yK&9t6Sw)^Fo(=6P9=8U6ZW2$40`DO|&}2{l-??t>KM^xP{PQp9J>sMDt1wG0P7(^*|FxpxgxUNu=e>XY@94oX zm34@@sD<7z%UMsx_zdi4z8GAI!3iDJ{-uogg{9 zcYkp~PAMU^CCrIu%1M71EC`5o2if_~7E&h??0jeQ1Y3N6p?}G72FSn>E+sATQ)Q)70!M+WViTAl9FdlI^_bw) zg$_FC{~s`6^Y4_v-WecL8bso`qEiB0GeD&@Sajx!_6dmf;f#FXiqAg!jge#)(`PVmVSj|$`UsHZGo<5&Mq0i(4E(oP@&iXk=-U1(Bgrgt{}SSg8|!FVQpN1*ApW3%X$qBd z0$g%sHPPlXP=%gv2Ryu4{+&-ACfn41x}XBX7bma&a6)1z%_mzAlTKO8TYoT%Ma!#@ zNsf>EkEEDA*ST6fiC+AnsNK1#>!x0obq@j$QqYU-ad3ZvbjqUU+%iw(0WahgmHV6y zeLWqoYkSl4pzFQ(_Vp&ItO{WI-48rGLwQb?#vgVvduyd9_6W)rFRoQJq3I(J?{Xmi zn45#=3l9BmL6Bp<*MZejrhnxPZJd$0O%`^i+?+grDp}Z_q9=X}=<|3S6D2}Xo}(vz z>ty7i#49G<-Lx9fe*rb6#JivumHVB}LG4gdXO*R~xABLfz>ADt4^0(GkQeZWqQ#Jh z>AK{zSO Date: Fri, 17 Apr 2020 19:00:45 +0200 Subject: [PATCH 023/878] adding the extra comma as mentioned on bangle js documentation --- apps/hidcam/hidcam.app.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/hidcam/hidcam.app.json b/apps/hidcam/hidcam.app.json index df35404e4..ad3ea89fe 100644 --- a/apps/hidcam/hidcam.app.json +++ b/apps/hidcam/hidcam.app.json @@ -1,4 +1,4 @@ -// Create an entry in apps.json as follows: +}, { "id": "hidcam", "name": "HID camera shutter", "shortName":"HID cam", @@ -11,3 +11,4 @@ {"name":"hidcam.img","url":"app-icon.js","evaluate":true} ], } +] From 15535b0f19c232425c01311e1f1b5c33da50d78f Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 17 Apr 2020 19:06:09 +0200 Subject: [PATCH 024/878] move json info to the good place --- apps.json | 14 +++++++++++++- apps/hidcam/hidcam.app.json | 14 -------------- 2 files changed, 13 insertions(+), 15 deletions(-) delete mode 100644 apps/hidcam/hidcam.app.json diff --git a/apps.json b/apps.json index effa14aa4..d57f218be 100644 --- a/apps.json +++ b/apps.json @@ -1293,5 +1293,17 @@ "evaluate": true } ] - } + }, +{ "id": "hidcam", + "name": "HID camera shutter", + "shortName":"HID cam", + "icon": "app.png", + "version":"0.01", + "description": "Enable HID, connect to your phone, start your camera and trigger the shot on your Bangle", + "tags": "tools", + "storage": [ + {"name":"hidcam.app.js","url":"hidcam.app.js"}, + {"name":"hidcam.img","url":"app-icon.js","evaluate":true} + ], +} ] diff --git a/apps/hidcam/hidcam.app.json b/apps/hidcam/hidcam.app.json deleted file mode 100644 index ad3ea89fe..000000000 --- a/apps/hidcam/hidcam.app.json +++ /dev/null @@ -1,14 +0,0 @@ -}, -{ "id": "hidcam", - "name": "HID camera shutter", - "shortName":"HID cam", - "icon": "app.png", - "version":"0.01", - "description": "Enable HID, connect to your phone, start your camera and trigger the shot on your Bangle", - "tags": "tools", - "storage": [ - {"name":"hidcam.app.js","url":"hidcam.app.js"}, - {"name":"hidcam.img","url":"app-icon.js","evaluate":true} - ], -} -] From 1dc2e3805d0cbbde633669b88c9f36465931ab69 Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 17 Apr 2020 19:12:17 +0200 Subject: [PATCH 025/878] json format --- apps.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/apps.json b/apps.json index d57f218be..d89fe95b0 100644 --- a/apps.json +++ b/apps.json @@ -1294,16 +1294,16 @@ } ] }, -{ "id": "hidcam", - "name": "HID camera shutter", - "shortName":"HID cam", - "icon": "app.png", - "version":"0.01", - "description": "Enable HID, connect to your phone, start your camera and trigger the shot on your Bangle", - "tags": "tools", - "storage": [ - {"name":"hidcam.app.js","url":"hidcam.app.js"}, - {"name":"hidcam.img","url":"app-icon.js","evaluate":true} - ], + { "id": "hidcam", + "name": "HID camera shutter", + "shortName":"HID cam", + "icon": "app.png", + "version":"0.01", + "description": "Enable HID, connect to your phone, start your camera and trigger the shot on your Bangle", + "tags": "tools", + "storage": [ + {"name":"hidcam.app.js","url":"hidcam.app.js"}, + {"name":"hidcam.img","url":"app-icon.js","evaluate":true} + ] } ] From c7f2a18caaff5a472db6f7f3765cd4234f936da1 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 17 Apr 2020 21:08:07 +0200 Subject: [PATCH 026/878] Remove "settings" from appid.info --- apps.json | 2 +- apps/setting/ChangeLog | 1 + apps/setting/settings.js | 22 ++++++++++++++-------- js/appinfo.js | 2 -- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/apps.json b/apps.json index 0c97b9e57..4b8b4a6b3 100644 --- a/apps.json +++ b/apps.json @@ -120,7 +120,7 @@ { "id": "setting", "name": "Settings", "icon": "settings.png", - "version":"0.16", + "version":"0.17", "description": "A menu for setting up Bangle.js", "tags": "tool,system", "storage": [ diff --git a/apps/setting/ChangeLog b/apps/setting/ChangeLog index 3acfb5fb0..81ac1fa81 100644 --- a/apps/setting/ChangeLog +++ b/apps/setting/ChangeLog @@ -18,3 +18,4 @@ 0.14: Reduce memory usage when running app settings page 0.15: Reduce memory usage when running default clock chooser (#294) 0.16: Reduce memory usage further when running app settings page +0.17: Remove need for "settings" in appid.info diff --git a/apps/setting/settings.js b/apps/setting/settings.js index d0d88ce20..97ce464ad 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -416,10 +416,19 @@ function showAppSettingsMenu() { '': { 'title': 'App Settings' }, '< Back': ()=>showMainMenu(), } - const apps = storage.list(/\.info$/) - .map(app => {var a=storage.readJSON(app, 1);return (a&&a.settings)?{sortorder:a.sortorder,name:a.name,settings:a.settings}:undefined}) - .filter(app => app) // filter out any undefined apps - .sort((a, b) => a.sortorder - b.sortorder) + const apps = storage.list(/\.settings\.js$/) + .map(s => s.substr(0, s.length-12)) + .map(id => { + const a=storage.readJSON(id+'.info',1); + return {id:id,name:a.name,sortorder:a.sortorder}; + }) + .sort((a, b) => { + const n = (0|a.sortorder)-(0|b.sortorder); + if (n) return n; // do sortorder first + if (a.nameb.name) return 1; + return 0; + }) if (apps.length === 0) { appmenu['No app has settings'] = () => { }; } @@ -433,10 +442,7 @@ function showAppSettings(app) { E.showMessage(`${app.name}:\n${msg}!\n\nBTN1 to go back`); setWatch(showAppSettingsMenu, BTN1, { repeat: false }); } - let appSettings = storage.read(app.settings); - if (!appSettings) { - return showError('Missing settings'); - } + let appSettings = storage.read(app.id+'.settings.js'); try { appSettings = eval(appSettings); } catch (e) { diff --git a/js/appinfo.js b/js/appinfo.js index 56b6ff2f8..9fff7c92a 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -60,8 +60,6 @@ var AppInfo = { if (app.type && app.type!="app") json.type = app.type; if (fileContents.find(f=>f.name==app.id+".app.js")) json.src = app.id+".app.js"; - if (fileContents.find(f=>f.name==app.id+".settings.js")) - json.settings = app.id+".settings.js"; if (fileContents.find(f=>f.name==app.id+".img")) json.icon = app.id+".img"; if (app.sortorder) json.sortorder = app.sortorder; From 43b0d8897e7a50556b93a58eff19d068d2f43544 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 17 Apr 2020 21:25:56 +0200 Subject: [PATCH 027/878] widbatpc: Save settings in data file --- apps.json | 8 +++++--- apps/widbatpc/ChangeLog | 1 + apps/widbatpc/settings.js | 2 +- apps/widbatpc/widget.js | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps.json b/apps.json index 0c97b9e57..315120cc7 100644 --- a/apps.json +++ b/apps.json @@ -342,14 +342,16 @@ "name": "Battery Level Widget (with percentage)", "shortName": "Battery Widget", "icon": "widget.png", - "version":"0.09", + "version":"0.10", "description": "Show the current battery level and charging status in the top right of the clock, with charge percentage", "tags": "widget,battery", "type":"widget", "storage": [ {"name":"widbatpc.wid.js","url":"widget.js"}, - {"name":"widbatpc.settings.js","url":"settings.js"}, - {"name":"widbatpc.settings.json","content": "{}"} + {"name":"widbatpc.settings.js","url":"settings.js"} + ], + "data": [ + {"name":"widbatpc.json"} ] }, { "id": "widbt", diff --git a/apps/widbatpc/ChangeLog b/apps/widbatpc/ChangeLog index 129707320..138c1adc8 100644 --- a/apps/widbatpc/ChangeLog +++ b/apps/widbatpc/ChangeLog @@ -6,3 +6,4 @@ 0.07: Add settings: percentage/color/charger icon 0.08: Draw percentage as inverted on monochrome battery 0.09: Fix regression stopping correct widget updates +0.10: Don't overwrite existing settings on app update diff --git a/apps/widbatpc/settings.js b/apps/widbatpc/settings.js index 5c0bdbcae..88988cf22 100644 --- a/apps/widbatpc/settings.js +++ b/apps/widbatpc/settings.js @@ -3,7 +3,7 @@ * @param {function} back Use back() to return to settings menu */ (function(back) { - const SETTINGS_FILE = 'widbatpc.settings.json' + const SETTINGS_FILE = 'widbatpc.json' const COLORS = ['By Level', 'Green', 'Monochrome'] // initialize with default settings... diff --git a/apps/widbatpc/widget.js b/apps/widbatpc/widget.js index aca690ce0..189ca215f 100644 --- a/apps/widbatpc/widget.js +++ b/apps/widbatpc/widget.js @@ -11,7 +11,7 @@ const COLORS = { 'ok': 0xFD20, // "Orange" 'low':0xF800, // "Red" } -const SETTINGS_FILE = 'widbatpc.settings.json' +const SETTINGS_FILE = 'widbatpc.json' let settings function loadSettings() { From b691f783aa7cb956c0644658907a93e27ce836c9 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 17 Apr 2020 21:29:56 +0200 Subject: [PATCH 028/878] welcome: Save settings in data file fwelcom --- apps.json | 6 ++++-- apps/welcome/ChangeLog | 1 + apps/welcome/boot.js | 4 ++-- apps/welcome/settings-default.json | 3 --- apps/welcome/settings.js | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 apps/welcome/settings-default.json diff --git a/apps.json b/apps.json index 315120cc7..a8b29b685 100644 --- a/apps.json +++ b/apps.json @@ -78,7 +78,7 @@ { "id": "welcome", "name": "Welcome", "icon": "app.png", - "version":"0.07", + "version":"0.08", "description": "Appears at first boot and explains how to use Bangle.js", "tags": "start,welcome", "allow_emulator":true, @@ -86,8 +86,10 @@ {"name":"welcome.boot.js","url":"boot.js"}, {"name":"welcome.app.js","url":"app.js"}, {"name":"welcome.settings.js","url":"settings.js"}, - {"name":"welcome.settings.json","url":"settings-default.json","evaluate":true}, {"name":"welcome.img","url":"app-icon.js","evaluate":true} + ], + "data": [ + {"name":"welcome.json"} ] }, { "id": "gbridge", diff --git a/apps/welcome/ChangeLog b/apps/welcome/ChangeLog index b8786af6a..a377fc81e 100644 --- a/apps/welcome/ChangeLog +++ b/apps/welcome/ChangeLog @@ -7,3 +7,4 @@ 0.07: Run again when updated Don't run again when settings app is updated (or absent) Add "Run Now" option to settings +0.08: Don't overwrite existing settings on app update diff --git a/apps/welcome/boot.js b/apps/welcome/boot.js index bc5afcc66..f6ba6d2d6 100644 --- a/apps/welcome/boot.js +++ b/apps/welcome/boot.js @@ -1,11 +1,11 @@ (function() { - let s = require('Storage').readJSON('welcome.settings.json', 1) + let s = require('Storage').readJSON('welcome.json', 1) || require('Storage').readJSON('setting.json', 1) || {welcomed: true} // do NOT run if global settings are also absent if (!s.welcomed && require('Storage').read('welcome.app.js')) { setTimeout(() => { s.welcomed = true - require('Storage').write('welcome.settings.json', {welcomed: "yes"}) + require('Storage').write('welcome.json', {welcomed: "yes"}) load('welcome.app.js') }) } diff --git a/apps/welcome/settings-default.json b/apps/welcome/settings-default.json deleted file mode 100644 index d250efff5..000000000 --- a/apps/welcome/settings-default.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "welcomed": false -} diff --git a/apps/welcome/settings.js b/apps/welcome/settings.js index b11921646..e873c2785 100644 --- a/apps/welcome/settings.js +++ b/apps/welcome/settings.js @@ -1,13 +1,13 @@ // The welcome app is special, and gets to use global settings (function(back) { - let settings = require('Storage').readJSON('welcome.settings.json', 1) + let settings = require('Storage').readJSON('welcome.sjson', 1) || require('Storage').readJSON('setting.json', 1) || {} E.showMenu({ '': { 'title': 'Welcome App' }, 'Run on Next Boot': { value: !settings.welcomed, format: v => v ? 'OK' : 'No', - onchange: v => require('Storage').write('welcome.settings.json', {welcomed: !v}), + onchange: v => require('Storage').write('welcome.json', {welcomed: !v}), }, 'Run Now': () => load('welcome.app.js'), '< Back': back, From b047f14d4ada97c510edc7a773a3e1f08982bc5d Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 17 Apr 2020 21:35:59 +0200 Subject: [PATCH 029/878] setting: Save settings in data file --- apps.json | 6 ++++-- apps/setting/ChangeLog | 1 + apps/setting/settings-default.json | 25 ------------------------- 3 files changed, 5 insertions(+), 27 deletions(-) delete mode 100644 apps/setting/settings-default.json diff --git a/apps.json b/apps.json index a8b29b685..4d5493e49 100644 --- a/apps.json +++ b/apps.json @@ -122,15 +122,17 @@ { "id": "setting", "name": "Settings", "icon": "settings.png", - "version":"0.16", + "version":"0.17", "description": "A menu for setting up Bangle.js", "tags": "tool,system", "storage": [ {"name":"setting.app.js","url":"settings.js"}, {"name":"setting.boot.js","url":"boot.js"}, - {"name":"setting.json","url":"settings-default.json","evaluate":true}, {"name":"setting.img","url":"settings-icon.js","evaluate":true} ], + "data": [ + {"name":"setting.json"} + ], "sortorder" : -2 }, { "id": "alarm", diff --git a/apps/setting/ChangeLog b/apps/setting/ChangeLog index 3acfb5fb0..773b510f0 100644 --- a/apps/setting/ChangeLog +++ b/apps/setting/ChangeLog @@ -18,3 +18,4 @@ 0.14: Reduce memory usage when running app settings page 0.15: Reduce memory usage when running default clock chooser (#294) 0.16: Reduce memory usage further when running app settings page +0.17: Don't overwrite existing settings on app update diff --git a/apps/setting/settings-default.json b/apps/setting/settings-default.json deleted file mode 100644 index c61fd6109..000000000 --- a/apps/setting/settings-default.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - ble: true, // Bluetooth enabled by default - blerepl: true, // Is REPL on Bluetooth - can Espruino IDE be used? - log: false, // Do log messages appear on screen? - timeout: 10, // Default LCD timeout in seconds - vibrate: true, // Vibration enabled by default. App must support - beep: "vib", // Beep enabled by default. App must support - timezone: 0, // Set the timezone for the device - HID : false, // BLE HID mode, off by default - clock: null, // a string for the default clock's name - "12hour" : false, // 12 or 24 hour clock? - // welcomed : undefined/true (whether welcome app should show) - brightness: 1, // LCD brightness from 0 to 1 - options: { - wakeOnBTN1: true, - wakeOnBTN2: true, - wakeOnBTN3: true, - wakeOnFaceUp: false, - wakeOnTouch: false, - wakeOnTwist: true, - twistThreshold: 819.2, - twistMaxY: -800, - twistTimeout: 1000 - } -} From 9358b4b5995e2efa6a49a1ca7865a0484f0c2c3f Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 17 Apr 2020 21:39:27 +0200 Subject: [PATCH 030/878] alarm: Save settings in data file --- apps.json | 6 ++++-- apps/alarm/ChangeLog | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 4d5493e49..30fb669d2 100644 --- a/apps.json +++ b/apps.json @@ -139,16 +139,18 @@ "name": "Default Alarm", "shortName":"Alarms", "icon": "app.png", - "version":"0.06", + "version":"0.07", "description": "Set and respond to alarms", "tags": "tool,alarm,widget", "storage": [ {"name":"alarm.app.js","url":"app.js"}, {"name":"alarm.boot.js","url":"boot.js"}, {"name":"alarm.js","url":"alarm.js"}, - {"name":"alarm.json","content":"[]"}, {"name":"alarm.img","url":"app-icon.js","evaluate":true}, {"name":"alarm.wid.js","url":"widget.js"} + ], + "data": [ + {"name":"alarm.json"} ] }, { "id": "wclock", diff --git a/apps/alarm/ChangeLog b/apps/alarm/ChangeLog index 2ff60e658..ca92a0d97 100644 --- a/apps/alarm/ChangeLog +++ b/apps/alarm/ChangeLog @@ -4,3 +4,4 @@ 0.04: Tweaks for variable size widget system 0.05: Add alarm.boot.js and move code from the bootloader 0.06: Change 'New Alarm' to 'Save', allow Deletion of Alarms +0.07: Don't overwrite existing settings on app update From e4c0574ab77ad2b8064e3c50dd1e900f5a2fe7fb Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 17 Apr 2020 21:45:48 +0200 Subject: [PATCH 031/878] heart: Save settings in data file, add recording files to data --- apps.json | 7 +++++-- apps/heart/ChangeLog | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 30fb669d2..6509458bf 100644 --- a/apps.json +++ b/apps.json @@ -300,15 +300,18 @@ { "id": "heart", "name": "Heart Rate Recorder", "icon": "app.png", - "version":"0.01", + "version":"0.02", "interface": "interface.html", "description": "Application that allows you to record your heart rate. Can run in background", "tags": "tool,health,widget", "storage": [ {"name":"heart.app.js","url":"app.js"}, - {"name":"heart.json","url":"app-settings.json","evaluate":true}, {"name":"heart.img","url":"app-icon.js","evaluate":true}, {"name":"heart.wid.js","url":"widget.js"} + ], + "data": [ + {"name":"heart.json"}, + {"wildcard":".heart?","storageFile": true} ] }, { "id": "slevel", diff --git a/apps/heart/ChangeLog b/apps/heart/ChangeLog index 4c4db83bc..70134af27 100644 --- a/apps/heart/ChangeLog +++ b/apps/heart/ChangeLog @@ -1,2 +1,3 @@ 0.01: New App! - +0.02: Don't overwrite existing settings on app update + Clean up recordings on app removal From db35edede6527b4613ed147298be6497def457ee Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 17 Apr 2020 21:49:57 +0200 Subject: [PATCH 032/878] ncstart: Save settings in data file --- apps.json | 6 ++++-- apps/ncstart/ChangeLog | 1 + apps/ncstart/boot.js | 4 ++-- apps/ncstart/settings-default.json | 3 --- apps/ncstart/settings.js | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 apps/ncstart/settings-default.json diff --git a/apps.json b/apps.json index 6509458bf..c3544abee 100644 --- a/apps.json +++ b/apps.json @@ -528,20 +528,22 @@ "id": "ncstart", "name": "NCEU Startup", "icon": "start.png", - "version":"0.04", + "version":"0.05", "description": "NodeConfEU 2019 'First Start' Sequence", "tags": "start,welcome", "storage": [ {"name":"ncstart.app.js","url":"start.js"}, {"name":"ncstart.boot.js","url":"boot.js"}, {"name":"ncstart.settings.js","url":"settings.js"}, - {"name":"ncstart.settings.json","url":"settings-default.json","evaluate":true}, {"name":"ncstart.img","url":"start-icon.js","evaluate":true}, {"name":"nc-bangle.img","url":"start-bangle.js","evaluate":true}, {"name":"nc-nceu.img","url":"start-nceu.js","evaluate":true}, {"name":"nc-nfr.img","url":"start-nfr.js","evaluate":true}, {"name":"nc-nodew.img","url":"start-nodew.js","evaluate":true}, {"name":"nc-tf.img","url":"start-tf.js","evaluate":true} + ], + "data": [ + {"name":"ncstart.json"} ] }, { "id": "ncfrun", diff --git a/apps/ncstart/ChangeLog b/apps/ncstart/ChangeLog index f4418827e..522633f7b 100644 --- a/apps/ncstart/ChangeLog +++ b/apps/ncstart/ChangeLog @@ -5,3 +5,4 @@ 0.04: Run again when updated Don't run again when settings app is updated (or absent) Add "Run Now" option to settings +0.05: Don't overwrite existing settings on app update diff --git a/apps/ncstart/boot.js b/apps/ncstart/boot.js index e3f514f5b..094033094 100644 --- a/apps/ncstart/boot.js +++ b/apps/ncstart/boot.js @@ -1,11 +1,11 @@ (function() { - let s = require('Storage').readJSON('ncstart.settings.json', 1) + let s = require('Storage').readJSON('ncstart.json', 1) || require('Storage').readJSON('setting.json', 1) || {welcomed: true} // do NOT run if global settings are also absent if (!s.welcomed && require('Storage').read('ncstart.app.js')) { setTimeout(() => { s.welcomed = true - require('Storage').write('ncstart.settings.json', s) + require('Storage').write('ncstart.json', s) load('ncstart.app.js') }) } diff --git a/apps/ncstart/settings-default.json b/apps/ncstart/settings-default.json deleted file mode 100644 index d250efff5..000000000 --- a/apps/ncstart/settings-default.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "welcomed": false -} diff --git a/apps/ncstart/settings.js b/apps/ncstart/settings.js index 2b24095cf..6780264a7 100644 --- a/apps/ncstart/settings.js +++ b/apps/ncstart/settings.js @@ -1,13 +1,13 @@ // The welcome app is special, and gets to use global settings (function(back) { - let settings = require('Storage').readJSON('ncstart.settings.json', 1) + let settings = require('Storage').readJSON('ncstart.json', 1) || require('Storage').readJSON('setting.json', 1) || {} E.showMenu({ '': { 'title': 'NCEU Startup' }, 'Run on Next Boot': { value: !settings.welcomed, format: v => v ? 'OK' : 'No', - onchange: v => require('Storage').write('ncstart.settings.json', {welcomed: !v}), + onchange: v => require('Storage').write('ncstart.json', {welcomed: !v}), }, 'Run Now': () => load('ncstart.app.js'), '< Back': back, From 595de45e348799bb38d0728dd8a82aecc5c09287 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 17 Apr 2020 21:52:42 +0200 Subject: [PATCH 033/878] numerals: Save settings in data file --- apps.json | 8 +++++--- apps/numerals/ChangeLog | 3 ++- apps/numerals/numerals-default.json | 5 ----- 3 files changed, 7 insertions(+), 9 deletions(-) delete mode 100644 apps/numerals/numerals-default.json diff --git a/apps.json b/apps.json index c3544abee..18fad4cfe 100644 --- a/apps.json +++ b/apps.json @@ -1235,7 +1235,7 @@ "name": "Numerals Clock", "shortName": "Numerals Clock", "icon": "numerals.png", - "version":"0.03", + "version":"0.04", "description": "A simple big numerals clock", "tags": "numerals,clock", "type":"clock", @@ -1243,8 +1243,10 @@ "storage": [ {"name":"numerals.app.js","url":"numerals.app.js"}, {"name":"numerals.img","url":"numerals-icon.js","evaluate":true}, - {"name":"numerals.settings.js","url":"numerals.settings.js"}, - {"name":"numerals.json","url":"numerals-default.json","evaluate":true} + {"name":"numerals.settings.js","url":"numerals.settings.js"} + ], + "data":[ + {"name":"numerals.json"} ] }, { "id": "bledetect", diff --git a/apps/numerals/ChangeLog b/apps/numerals/ChangeLog index ec465a83f..927c4ff5f 100644 --- a/apps/numerals/ChangeLog +++ b/apps/numerals/ChangeLog @@ -1,3 +1,4 @@ 0.01: New App! 0.02: Use BTN2 for settings menu like other clocks -0.03: maximize numerals, make menu button configurable, change icon to mac palette, add default settings file, respect 12hour setting \ No newline at end of file +0.03: maximize numerals, make menu button configurable, change icon to mac palette, add default settings file, respect 12hour setting +0.04: Don't overwrite existing settings on app update diff --git a/apps/numerals/numerals-default.json b/apps/numerals/numerals-default.json deleted file mode 100644 index aa6a25047..000000000 --- a/apps/numerals/numerals-default.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - color:0, - drawMode:"fill", - menuButton:22 -} \ No newline at end of file From a8d1ef3e53b35732bb8871956d1b2d1d13875d5e Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 17 Apr 2020 21:42:29 +0200 Subject: [PATCH 034/878] gpsrec: Save settings in data file, add track files to data --- apps.json | 7 +++++-- apps/gpsrec/ChangeLog | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 18fad4cfe..a18029abc 100644 --- a/apps.json +++ b/apps.json @@ -286,15 +286,18 @@ { "id": "gpsrec", "name": "GPS Recorder", "icon": "app.png", - "version":"0.07", + "version":"0.08", "interface": "interface.html", "description": "Application that allows you to record a GPS track. Can run in background", "tags": "tool,outdoors,gps,widget", "storage": [ {"name":"gpsrec.app.js","url":"app.js"}, - {"name":"gpsrec.json","url":"app-settings.json","evaluate":true}, {"name":"gpsrec.img","url":"app-icon.js","evaluate":true}, {"name":"gpsrec.wid.js","url":"widget.js"} + ], + "data": [ + {"name":"gpsrec.json"}, + {"wildcard":".gpsrc?","storageFile": true} ] }, { "id": "heart", diff --git a/apps/gpsrec/ChangeLog b/apps/gpsrec/ChangeLog index 8f1c575a1..17678bf3a 100644 --- a/apps/gpsrec/ChangeLog +++ b/apps/gpsrec/ChangeLog @@ -5,3 +5,5 @@ 0.05: Tweaks for variable size widget system 0.06: Ensure widget update itself (fix #118) and change to using icons 0.07: Added @jeffmer's awesome track viewer +0.08: Don't overwrite existing settings on app update + Clean up recorded tracks on app removal From e615b49cd027976ca9bceb869d18cab3e30d9d7f Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 17 Apr 2020 22:17:36 +0200 Subject: [PATCH 035/878] wohrm: fix `apps.json` version --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 0c97b9e57..7499b352c 100644 --- a/apps.json +++ b/apps.json @@ -890,7 +890,7 @@ { "id": "wohrm", "name": "Workout HRM", "icon": "app.png", - "version":"0.06", + "version":"0.07", "readme": "README.md", "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", "tags": "hrm,workout", From 2278947b3d4b7a2ff0cea136bfa16d7bbb0a9497 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Sat, 18 Apr 2020 00:51:22 +0200 Subject: [PATCH 036/878] App Manager: Add support for data files --- apps.json | 2 +- apps/files/ChangeLog | 1 + apps/files/files.js | 94 +++++++++++++++++++++++++++++++++----------- 3 files changed, 74 insertions(+), 23 deletions(-) diff --git a/apps.json b/apps.json index 0c97b9e57..bac885598 100644 --- a/apps.json +++ b/apps.json @@ -319,7 +319,7 @@ { "id": "files", "name": "App Manager", "icon": "files.png", - "version":"0.02", + "version":"0.03", "description": "Show currently installed apps, free space, and allow their deletion from the watch", "tags": "tool,system,files", "storage": [ diff --git a/apps/files/ChangeLog b/apps/files/ChangeLog index 8b7be7640..1140000fe 100644 --- a/apps/files/ChangeLog +++ b/apps/files/ChangeLog @@ -1 +1,2 @@ 0.02: Fix deletion of apps - now use files list in app.info (fix #262) +0.03: Add support for data files diff --git a/apps/files/files.js b/apps/files/files.js index 4775d35d0..ef0481f0c 100644 --- a/apps/files/files.js +++ b/apps/files/files.js @@ -30,29 +30,80 @@ function showMainMenu() { return E.showMenu(mainmenu); } -function eraseApp(app) { - E.showMessage('Erasing\n' + app.name + '...'); +function isGlob(f) {return /[?*]/.test(f)} +function globToRegex(pattern) { + const ESCAPE = '.*+-?^${}()|[]\\'; + const regex = pattern.replace(/./g, c => { + switch (c) { + case '?': return '.'; + case '*': return '.*'; + default: return ESCAPE.includes(c) ? ('\\' + c) : c; + } + }); + return new RegExp('^'+regex+'$'); +} + +function eraseFiles(app) { app.files.split(",").forEach(f=>storage.erase(f)); } +function eraseData(app) { + if(!app.data) return; + const d=app.data.split(';'), + files=d[0].split(','), + sFiles=(d[1]||'').split(','); + let erase = f=>storage.erase(f); + files.forEach(f=>{ + if (!isGlob(f)) erase(f); + else storage.list(globToRegex(f)).forEach(erase); + }) + erase = sf=>storage.open(sf,'r').erase(); + sFiles.forEach(sf=>{ + if (!isGlob(sf)) erase(sf); + else storage.list(globToRegex(sf+'\u0001')) + .forEach(fs=>erase(fs.substring(0,fs.length-1))); + }) +} +function eraseApp(app, files,data) { + E.showMessage('Erasing\n' + app.name + '...'); + if (files) eraseFiles(app) + if (data) eraseData(app) +} +function eraseOne(app, files,data){ + E.showPrompt('Erase\n'+app.name+'?').then((v) => { + if (v) { + Bangle.buzz(100, 1); + eraseApp(app, files,data) + showApps(); + } else { + showAppMenu(app) + } + }) +} +function eraseAll(apps, files,data) { + E.showPrompt('Erase all?').then((v) => { + if (v) { + Bangle.buzz(100, 1); + for(var n = 0; n m = showApps(), - 'Erase': () => { - E.showPrompt('Erase\n' + app.name + '?').then((v) => { - if (v) { - Bangle.buzz(100, 1); - eraseApp(app); - m = showApps(); - } else { - m = showAppMenu(app) - } - }); - } - }; + } + if (app.data) { + appmenu['Erase Completely'] = () => eraseOne(app, true, true) + appmenu['Erase App,Keep Data'] = () => eraseOne(app,true, false) + appmenu['Only Erase Data'] = () => eraseOne(app,false, true) + } else { + appmenu['Erase'] = () => eraseOne(app,true, false) + } return E.showMenu(appmenu); } @@ -78,13 +129,12 @@ function showApps() { return menu; }, appsmenu); appsmenu['Erase All'] = () => { - E.showPrompt('Erase all?').then((v) => { - if (v) { - Bangle.buzz(100, 1); - for (var n = 0; n < list.length; n++) - eraseApp(list[n]); - } - m = showApps(); + E.showMenu({ + '': {'title': 'Erase All'}, + 'Erase Everything': () => eraseAll(list, true, true), + 'Erase Apps,Keep Data': () => eraseAll(list, true, false), + 'Only Erase Data': () => eraseAll(list, false, true), + '< Back': () => showApps(), }); }; } else { From c0f9c8b3e28b56680037a74f1666f0bac59c3cd9 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Sat, 18 Apr 2020 00:38:12 +0100 Subject: [PATCH 037/878] Store GPS coords, for use on next start if user desires --- apps.json | 2 +- apps/astrocalc/ChangeLog | 2 ++ apps/astrocalc/astrocalc-app.js | 51 +++++++++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/apps.json b/apps.json index bbe0bbfcd..60b47dbd8 100644 --- a/apps.json +++ b/apps.json @@ -1018,7 +1018,7 @@ { "id": "astrocalc", "name": "Astrocalc", "icon": "astrocalc.png", - "version":"0.01", + "version":"0.02", "description": "Calculates interesting information on the sun and moon cycles for the current day based on your location.", "tags": "app,sun,moon,cycles,tool,outdoors", "allow_emulator":true, diff --git a/apps/astrocalc/ChangeLog b/apps/astrocalc/ChangeLog index 0c8adeb61..188fc287b 100644 --- a/apps/astrocalc/ChangeLog +++ b/apps/astrocalc/ChangeLog @@ -1 +1,3 @@ 0.01: Create astrocalc app +0.02: Store last GPS lock, can be used instead of waiting for new GPS on +start. diff --git a/apps/astrocalc/astrocalc-app.js b/apps/astrocalc/astrocalc-app.js index 318147b13..0b0c63658 100644 --- a/apps/astrocalc/astrocalc-app.js +++ b/apps/astrocalc/astrocalc-app.js @@ -1,8 +1,18 @@ /** + * BangleJS ASTROCALC + * * Inspired by: https://www.timeanddate.com + * + * Original Author: Paul Cockrell https://github.com/paulcockrell + * Created: April 2020 + * + * Calculate the Sun and Moon positions based on watch GPS and display graphically */ const SunCalc = require("suncalc.js"); +const storage = require("Storage"); +const LAST_GPS_FILE = "astrocalc.gps.json"; +let lastGPS = (storage.readJSON(LAST_GPS_FILE, 1) || null); function drawMoon(phase, x, y) { const moonImgFiles = [ @@ -296,22 +306,50 @@ function indexPageMenu(gps) { return E.showMenu(menu); } +function getCenterStringX(str) { + return (g.getWidth() - g.stringWidth(str)) / 2; +} + /** * GPS wait page, shows GPS locating animation until it gets a lock, then moves to the Sun page */ function drawGPSWaitPage() { - const img = require("heatshrink").decompress(atob("mEwxH+AH4A/AH4AW43GF1wwsFwYwqFwowoFw4wmFxIwdE5YAPF/4vM5nN6YAE5vMF8YtHGIgvhFpQxKF7AuOGA4vXFyAwGF63MFyIABF6xeWMC4UDLwvNGpAJG5gwSdhIIDRBLyWCIgcJHAgJJDoouQF4vMQoICBBJoeGFx6GGACIfHL6YvaX6gvZeCIdFc4gAFXogvGFxgwFDwovQCAguOGAnMMBxeG5guTGAggGGAwNKFySREcA3N5vM5gDBdpQvXEY4AKXqovGGCKbFF7AwPZQwvZGJgtGF7vGdQItG5gSIF7gASF/44WEzgwRF0wwHF1AwFF1QwDF1gvwAH4A/AFAA==")) - + const img = require("heatshrink").decompress(atob("mEwxH+AH4A/AH4AW43GF1wwsFwYwqFwowoFw4wmFxIwdE5YAPF/4vM5nN6YAE5vMF8YtHGIgvhFpQxKF7AuOGA4vXFyAwGF63MFyIABF6xeWMC4UDLwvNGpAJG5gwSdhIIDRBLyWCIgcJHAgJJDoouQF4vMQoICBBJoeGFx6GGACIfHL6YvaX6gvZeCIdFc4gAFXogvGFxgwFDwovQCAguOGAnMMBxeG5guTGAggGGAwNKFySREcA3N5vM5gDBdpQvXEY4AKXqovGGCKbFF7AwPZQwvZGJgtGF7vGdQItG5gSIF7gASF/44WEzgwRF0wwHF1AwFF1QwDF1gvwAH4A/AFAA==")); + const str1 = "Astrocalc v0.02"; + const str2 = "Locating GPS"; + const str3 = "Please wait..."; + g.clear(); g.drawImage(img, 100, 50); g.setFont("6x8", 1); - g.drawString("Astrocalc v0.01", 80, 105); - g.drawString("Locating GPS", 85, 140); - g.drawString("Please wait...", 80, 155); + g.drawString(str1, getCenterStringX(str1), 105); + g.drawString(str2, getCenterStringX(str2), 140); + g.drawString(str3, getCenterStringX(str3), 155); + + if (lastGPS) { + lastGPS = JSON.parse(lastGPS); + lastGPS.time = new Date(); + + const str4 = "Press Button 3 to use last GPS"; + g.setColor("#d32e29"); + g.fillRect(0, 190, g.getWidth(), 215); + g.setColor("#ffffff"); + g.drawString(str4, getCenterStringX(str4), 200); + + setWatch(() => { + clearWatch(); + Bangle.setGPSPower(0); + lastGPS.time = new Date(); + m = indexPageMenu(lastGPS); + }, BTN3, {repeat: false}); + } + g.flip(); const DEBUG = false; if (DEBUG) { + clearWatch(); + const gps = { "lat": 56.45783133333, "lon": -3.02188583333, @@ -330,7 +368,10 @@ function drawGPSWaitPage() { Bangle.on('GPS', (gps) => { if (gps.fix === 0) return; + clearWatch(); + if (isNaN(gps.course)) gps.course = 0; + require("Storage").writeJSON(LAST_GPS_FILE, JSON.stringify(gps)); Bangle.setGPSPower(0); Bangle.buzz(); Bangle.setLCDPower(true); From 173969839e0a80e96b2d55065dc82382ce536cc7 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Sat, 18 Apr 2020 00:39:32 +0100 Subject: [PATCH 038/878] Fix Changelog --- apps/astrocalc/ChangeLog | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/astrocalc/ChangeLog b/apps/astrocalc/ChangeLog index 188fc287b..60ef5da0a 100644 --- a/apps/astrocalc/ChangeLog +++ b/apps/astrocalc/ChangeLog @@ -1,3 +1,2 @@ 0.01: Create astrocalc app -0.02: Store last GPS lock, can be used instead of waiting for new GPS on -start. +0.02: Store last GPS lock, can be used instead of waiting for new GPS on start From e052a6e65fdaad4c14c99798ea7dd316cadf7345 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Sat, 18 Apr 2020 00:41:15 +0100 Subject: [PATCH 039/878] Remove repeated assignment of date to gps object --- apps/astrocalc/astrocalc-app.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/astrocalc/astrocalc-app.js b/apps/astrocalc/astrocalc-app.js index 0b0c63658..6b848abda 100644 --- a/apps/astrocalc/astrocalc-app.js +++ b/apps/astrocalc/astrocalc-app.js @@ -339,7 +339,6 @@ function drawGPSWaitPage() { setWatch(() => { clearWatch(); Bangle.setGPSPower(0); - lastGPS.time = new Date(); m = indexPageMenu(lastGPS); }, BTN3, {repeat: false}); } From bf4a3e0321abc7007a1fc1acede9616ff4a9cd49 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 09:01:15 +0200 Subject: [PATCH 040/878] Added rclock app --- apps.json | 12 +++ apps/rclock/ChangeLog | 1 + apps/rclock/app-icon.js | 1 + apps/rclock/app.png | Bin 0 -> 1620 bytes apps/rclock/rclock.app.js | 163 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 177 insertions(+) create mode 100644 apps/rclock/ChangeLog create mode 100644 apps/rclock/app-icon.js create mode 100644 apps/rclock/app.png create mode 100644 apps/rclock/rclock.app.js diff --git a/apps.json b/apps.json index bbe0bbfcd..ac7181bb4 100644 --- a/apps.json +++ b/apps.json @@ -1291,6 +1291,18 @@ "name": "dane.img", "url": "app-icon.js", "evaluate": true + }, + { "id": "rclock", + "name": "Round clock with seconds, minutes and date", + "shortName":"Round Clock", + "icon": "app.png", + "version":"0.01", + "description": "Designed round clock with ticks for minutes and seconds", + "tags": "", + "storage": [ + {"name":"rclock.app.js","url":"app.js"}, + {"name":"rclock.img","url":"app-icon.js","evaluate":true} + ] } ] } diff --git a/apps/rclock/ChangeLog b/apps/rclock/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/rclock/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/rclock/app-icon.js b/apps/rclock/app-icon.js new file mode 100644 index 000000000..49232b838 --- /dev/null +++ b/apps/rclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA==")) diff --git a/apps/rclock/app.png b/apps/rclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..582cb2e0853a5a2899a3afbd7eb19cde2ee7f6a0 GIT binary patch literal 1620 zcmV-a2CMmrP)1gXjloC|3_d8m;N2OpV(|i0q4YwBna<2! zK9thw%-*|urnNbV{Gax^?eD+#{x0kLJ~)lj_;W+1>qV*k8akT^^dvctZccUyj4}H~#M%Wwee_v` zHMv7o%BM8@dBrLshn{wGD9BDl?^eV5vSM3T96;NnHvtc6La=(qzq)xrX1d8bK-TN- zrd_f$_O`9nEmS+_S7HTXK<&u;LDIW|qlN&KJvM}tt6TVVqL-AvNv`B*{NzNpBfSQwQP5~Sf(Dp@Vq1+3Q`N9wBQN2`J_?M^u0FIMlt?p^8 z%U3%80kIwg!T{E9<8J18S&$k1`eO)@HP+=TZKo(z3_A3VFYJB=sn`2^Q$mRE>02(+W)np;)L1!GUvU2{O{<&F_nE6Qe#D~Xf|dD z+?d3-D1(IUiL`C2;PPv4CKw8H)v7h8^obJ&Z6D0CjVUe8Xq_NAymxUyPAMU^CCrIu z%1M71EC`5o2if_~7E&h??0jeQ1Y3N6p?}G72FmS*)xQD)%wBE=2tW6@(+MTi!fk9H1pWKew2(jTXVu4%vk26QvSQCbGmk`Z)Y! zBIhh)6vG2)h6mF8wC^|l$M(Eo9D?JiW}=_T2jUA>LC80foTera{^p)Wi`>}Gf;(|ZwEZQ zS^k|*9wyt=f4ZOo!xty7{%}HKD9tBZ50g$=%v&&vMa!#@Nsf>EkEEDA*ST6fiC+An zsNK1#>!x0obq@j$QqYU-ad3ZvbjqUU+%iw(0WahgmHV6yeLWqoYkSl4pzFQ(_Vp&I ztO{WI-48rGLwQb?#vgVvduyd9_6W)rFRoQJq3I(J?{Xmin45#=3l9BmL6Bp<*MZej zrsWN7oRPUr7IvrHoIHOjS=gPTCw>d)^LQK+B|=f2qbGjrWaOd5D<<9Dv>MTW0X3z> zyPy}9`<>1~?NCx@m8G$_@rRTy5zH12YM&P)=tU+L^fgY z^0Z&_6^qdVuwgN3wt_Ze(10?J@%{C2grBk42hsu74qEo^nd&v`X`IHN9lrxzS~GeF S(*#!l0000 Date: Sat, 18 Apr 2020 11:17:50 +0200 Subject: [PATCH 041/878] Fix error in app.json --- apps.json | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/apps.json b/apps.json index ac7181bb4..89fd1a0a3 100644 --- a/apps.json +++ b/apps.json @@ -1291,19 +1291,18 @@ "name": "dane.img", "url": "app-icon.js", "evaluate": true - }, - { "id": "rclock", - "name": "Round clock with seconds, minutes and date", - "shortName":"Round Clock", - "icon": "app.png", - "version":"0.01", - "description": "Designed round clock with ticks for minutes and seconds", - "tags": "", - "storage": [ - {"name":"rclock.app.js","url":"app.js"}, - {"name":"rclock.img","url":"app-icon.js","evaluate":true} - ] } ] - } + }, + { "id": "rclock", + "name": "Round clock with seconds, minutes and date", + "shortName":"Round Clock", + "icon": "app.png", + "version":"0.01", + "description": "Designed round clock with ticks for minutes and seconds", + "tags": "", + "storage": [ + {"name":"rclock.app.js","url":"app.js"}, + {"name":"rclock.img","url":"app-icon.js","evaluate":true} + ] ] From 8f562d817782203bdf250c7d60803b9ac3102b40 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 11:21:14 +0200 Subject: [PATCH 042/878] Fix error in app.json --- apps.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps.json b/apps.json index 89fd1a0a3..d7e857066 100644 --- a/apps.json +++ b/apps.json @@ -1305,4 +1305,5 @@ {"name":"rclock.app.js","url":"app.js"}, {"name":"rclock.img","url":"app-icon.js","evaluate":true} ] + } ] From 06705a6e5d0a3de5db7131c6a56684a917b6a710 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 11:28:08 +0200 Subject: [PATCH 043/878] Fixes --- apps.json | 6 ++++-- apps/rclock/ChangeLog | 2 +- apps/rclock/rclock.app.js | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index d7e857066..dc768218b 100644 --- a/apps.json +++ b/apps.json @@ -1294,13 +1294,15 @@ } ] }, - { "id": "rclock", + { + "id": "rclock", "name": "Round clock with seconds, minutes and date", "shortName":"Round Clock", "icon": "app.png", "version":"0.01", "description": "Designed round clock with ticks for minutes and seconds", - "tags": "", + "tags": "clock", + "type": "clock", "storage": [ {"name":"rclock.app.js","url":"app.js"}, {"name":"rclock.img","url":"app-icon.js","evaluate":true} diff --git a/apps/rclock/ChangeLog b/apps/rclock/ChangeLog index 5560f00bc..a8f708a0a 100644 --- a/apps/rclock/ChangeLog +++ b/apps/rclock/ChangeLog @@ -1 +1 @@ -0.01: New App! +0.01: First published version of app diff --git a/apps/rclock/rclock.app.js b/apps/rclock/rclock.app.js index 27fbda772..c681e0588 100644 --- a/apps/rclock/rclock.app.js +++ b/apps/rclock/rclock.app.js @@ -104,6 +104,7 @@ } first = false; } + // Reset seconds if (seconds == 59) { g.setColor('#000000'); From 7216b188672dfe4f5141c3a0470c38128f089cae Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 11:48:22 +0200 Subject: [PATCH 044/878] Fix error in reference to files --- apps.json | 2 +- package.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index dc768218b..bf771882a 100644 --- a/apps.json +++ b/apps.json @@ -1304,7 +1304,7 @@ "tags": "clock", "type": "clock", "storage": [ - {"name":"rclock.app.js","url":"app.js"}, + {"name":"rclock.app.js","url":"rclock.app.js"}, {"name":"rclock.img","url":"app-icon.js","evaluate":true} ] } diff --git a/package.json b/package.json index 400385139..24793d86a 100644 --- a/package.json +++ b/package.json @@ -9,5 +9,8 @@ "scripts": { "test": "node bin/sanitycheck.js", "start": "npx http-server" + }, + "dependencies": { + "acorn": "^7.1.1" } } From a1f1da0341f4a8985e4f5baafcbdf1b1a1469f6a Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 11:52:30 +0200 Subject: [PATCH 045/878] Updated grey colors --- apps/rclock/rclock.app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/rclock/rclock.app.js b/apps/rclock/rclock.app.js index c681e0588..405da7052 100644 --- a/apps/rclock/rclock.app.js +++ b/apps/rclock/rclock.app.js @@ -31,8 +31,8 @@ center: screen.center, }, circle: { - colormin: '#777777', - colorsec: '#444444', + colormin: '#999999', + colorsec: '#777777', width: 10, middle: screen.middle, center: screen.center, From afeff2c5761ed15d7164b1b3e338b7113ddee2b3 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 11:55:40 +0200 Subject: [PATCH 046/878] Updated grey colors --- apps/rclock/rclock.app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/rclock/rclock.app.js b/apps/rclock/rclock.app.js index 405da7052..25ca757cd 100644 --- a/apps/rclock/rclock.app.js +++ b/apps/rclock/rclock.app.js @@ -31,8 +31,8 @@ center: screen.center, }, circle: { - colormin: '#999999', - colorsec: '#777777', + colormin: '#bbbbbb', + colorsec: '#999999', width: 10, middle: screen.middle, center: screen.center, From 0a7a9e0b97652f96738c1a39e4bb6132c2aa9424 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 12:02:01 +0200 Subject: [PATCH 047/878] Align fonts --- apps/rclock/rclock.app.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/rclock/rclock.app.js b/apps/rclock/rclock.app.js index 25ca757cd..bd8395116 100644 --- a/apps/rclock/rclock.app.js +++ b/apps/rclock/rclock.app.js @@ -20,7 +20,7 @@ font: 'Vector', size: 60, middle: screen.middle - 30, - center: screen.center + 5 , + center: screen.center, }, date: { color: '#f0af00', @@ -31,8 +31,8 @@ center: screen.center, }, circle: { - colormin: '#bbbbbb', - colorsec: '#999999', + colormin: '#eeeeee', + colorsec: '#bbbbbb', width: 10, middle: screen.middle, center: screen.center, @@ -149,6 +149,7 @@ // clean app screen g.clear(); + g.setFontAlign( 0, 0, 0); Bangle.loadWidgets(); Bangle.drawWidgets(); From 6d1e87a765de9a48dee5939d66aeff0a97f3760b Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 12:39:13 +0200 Subject: [PATCH 048/878] Added icons --- .DS_Store | Bin 0 -> 6148 bytes apps/.DS_Store | Bin 0 -> 6148 bytes apps/rclock/.DS_Store | Bin 0 -> 6148 bytes apps/rclock/app-icon.js | 2 +- apps/rclock/app.png | Bin 1620 -> 0 bytes apps/rclock/appp.png | Bin 0 -> 10357 bytes 6 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 .DS_Store create mode 100644 apps/.DS_Store create mode 100644 apps/rclock/.DS_Store delete mode 100644 apps/rclock/app.png create mode 100644 apps/rclock/appp.png diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e9892b6bcf444f36764922b8e4fcf88ecca916a8 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4I%_5-~#-K2??Z%JxAx+@j_rm6?#VYi=A4u-_X<| zqMPSsEi#Bm4>y&Sg~k+lCr5eUH(oE}`EJ);>!>lNF#jv{Xd}rZGKew5pFG zR`+&jitBP{sao4bWBAbcXSFE?rnOx(A%SUjVITn#Xb8+}KG^xcgMXX3Z5S>vG!N$@uSMUZw^aNf&RBRL$6#K0_mq+u>r%+ZqEtEGfdC6p6LSC`6 zBO*G#>}Dbp5gEY^}dS)lX)N&paQ?HfPEhd+^{CLf&S^h;4J`ffUq0p-b(H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T01gXjloC|3_d8m;N2OpV(|i0q4YwBna<2! zK9thw%-*|urnNbV{Gax^?eD+#{x0kLJ~)lj_;W+1>qV*k8akT^^dvctZccUyj4}H~#M%Wwee_v` zHMv7o%BM8@dBrLshn{wGD9BDl?^eV5vSM3T96;NnHvtc6La=(qzq)xrX1d8bK-TN- zrd_f$_O`9nEmS+_S7HTXK<&u;LDIW|qlN&KJvM}tt6TVVqL-AvNv`B*{NzNpBfSQwQP5~Sf(Dp@Vq1+3Q`N9wBQN2`J_?M^u0FIMlt?p^8 z%U3%80kIwg!T{E9<8J18S&$k1`eO)@HP+=TZKo(z3_A3VFYJB=sn`2^Q$mRE>02(+W)np;)L1!GUvU2{O{<&F_nE6Qe#D~Xf|dD z+?d3-D1(IUiL`C2;PPv4CKw8H)v7h8^obJ&Z6D0CjVUe8Xq_NAymxUyPAMU^CCrIu z%1M71EC`5o2if_~7E&h??0jeQ1Y3N6p?}G72FmS*)xQD)%wBE=2tW6@(+MTi!fk9H1pWKew2(jTXVu4%vk26QvSQCbGmk`Z)Y! zBIhh)6vG2)h6mF8wC^|l$M(Eo9D?JiW}=_T2jUA>LC80foTera{^p)Wi`>}Gf;(|ZwEZQ zS^k|*9wyt=f4ZOo!xty7{%}HKD9tBZ50g$=%v&&vMa!#@Nsf>EkEEDA*ST6fiC+An zsNK1#>!x0obq@j$QqYU-ad3ZvbjqUU+%iw(0WahgmHV6yeLWqoYkSl4pzFQ(_Vp&I ztO{WI-48rGLwQb?#vgVvduyd9_6W)rFRoQJq3I(J?{Xmin45#=3l9BmL6Bp<*MZej zrsWN7oRPUr7IvrHoIHOjS=gPTCw>d)^LQK+B|=f2qbGjrWaOd5D<<9Dv>MTW0X3z> zyPy}9`<>1~?NCx@m8G$_@rRTy5zH12YM&P)=tU+L^fgY z^0Z&_6^qdVuwgN3wt_Ze(10?J@%{C2grBk42hsu74qEo^nd&v`X`IHN9lrxzS~GeF S(*#!l0000 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 TkibuO00000NkvXXu0mjfp7a2c literal 0 HcmV?d00001 From cdba3a32c22bc330ba64fd3ba7088349b49ad78f Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 12:42:03 +0200 Subject: [PATCH 049/878] FIx name error --- apps/rclock/{appp.png => app.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/rclock/{appp.png => app.png} (100%) diff --git a/apps/rclock/appp.png b/apps/rclock/app.png similarity index 100% rename from apps/rclock/appp.png rename to apps/rclock/app.png From 2f834a585632acdd4f0ea5fc78effcb86a4e0fb2 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 13:00:59 +0200 Subject: [PATCH 050/878] Changes to permissions on file --- apps/rclock/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/rclock/.DS_Store diff --git a/apps/rclock/.DS_Store b/apps/rclock/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Sat, 18 Apr 2020 13:06:12 +0200 Subject: [PATCH 051/878] Updated .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b83632eaa..f1811806d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .htaccess node_modules package-lock.json +.DS_Store From 3ed6448596080caa7ade69163e9482c8c45ad910 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Sat, 18 Apr 2020 13:08:23 +0200 Subject: [PATCH 052/878] Delete .DS_Store --- apps/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/.DS_Store diff --git a/apps/.DS_Store b/apps/.DS_Store deleted file mode 100644 index f1e36c314ed1b52c7092fec1d7f2c0441196819d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKI|>3Z5S>vG!N$@uSMUZw^aNf&RBRL$6#K0_mq+u>r%+ZqEtEGfdC6p6LSC`6 zBO*G#>}Dbp5gEY^}dS)lX)N&paQ?HfPEhd+^{CLf&S^h;4J`ffUq0p-b( Date: Sat, 18 Apr 2020 13:09:31 +0200 Subject: [PATCH 053/878] Delete .DS_Store --- .DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index e9892b6bcf444f36764922b8e4fcf88ecca916a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4I%_5-~#-K2??Z%JxAx+@j_rm6?#VYi=A4u-_X<| zqMPSsEi#Bm4>y&Sg~k+lCr5eUH(oE}`EJ);>!>lNF#jv{Xd}rZGKew5pFG zR`+&jitBP{sao4bWBAbcXSFE?rnOx(A%SUjVITn#Xb8+}KG^xcgMXX Date: Sat, 18 Apr 2020 15:34:35 +0200 Subject: [PATCH 054/878] shorter JS file name --- apps.json | 6 +++--- apps/hidcam/{hidcam.app.js => app.js} | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename apps/hidcam/{hidcam.app.js => app.js} (100%) diff --git a/apps.json b/apps.json index 1e6b5e945..0546d6f65 100644 --- a/apps.json +++ b/apps.json @@ -1295,14 +1295,14 @@ ] }, { "id": "hidcam", - "name": "HID camera shutter", - "shortName":"HID cam", + "name": "Camera shutter", + "shortName":"Cam shutter", "icon": "app.png", "version":"0.01", "description": "Enable HID, connect to your phone, start your camera and trigger the shot on your Bangle", "tags": "tools", "storage": [ - {"name":"hidcam.app.js","url":"hidcam.app.js"}, + {"name":"hidcam.app.js","url":"app.js"}, {"name":"hidcam.img","url":"app-icon.js","evaluate":true} ] } diff --git a/apps/hidcam/hidcam.app.js b/apps/hidcam/app.js similarity index 100% rename from apps/hidcam/hidcam.app.js rename to apps/hidcam/app.js From 37e26d6139782852411b61328006860a38034c47 Mon Sep 17 00:00:00 2001 From: jeffmer Date: Sat, 18 Apr 2020 14:38:32 +0100 Subject: [PATCH 055/878] Create ChangeLog --- apps/gpsnav/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/gpsnav/ChangeLog diff --git a/apps/gpsnav/ChangeLog b/apps/gpsnav/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/gpsnav/ChangeLog @@ -0,0 +1 @@ +0.01: New App! From ed51586dd0afdf9dd2df5c315e031c41ed62b162 Mon Sep 17 00:00:00 2001 From: jeffmer Date: Sat, 18 Apr 2020 14:39:36 +0100 Subject: [PATCH 056/878] Add files via upload --- apps/gpsnav/README.md | 66 ++++++++++ apps/gpsnav/app-icon.js | 1 + apps/gpsnav/app.js | 224 ++++++++++++++++++++++++++++++++ apps/gpsnav/first_screen.jpg | Bin 0 -> 65452 bytes apps/gpsnav/gpsnav.jpg | Bin 0 -> 47970 bytes apps/gpsnav/icon.png | Bin 0 -> 1887 bytes apps/gpsnav/marked_screen.jpg | Bin 0 -> 65895 bytes apps/gpsnav/select_screen.jpg | Bin 0 -> 64877 bytes apps/gpsnav/waypoint_screen.jpg | Bin 0 -> 67409 bytes apps/gpsnav/waypoints.json | 23 ++++ 10 files changed, 314 insertions(+) create mode 100644 apps/gpsnav/README.md create mode 100644 apps/gpsnav/app-icon.js create mode 100644 apps/gpsnav/app.js create mode 100644 apps/gpsnav/first_screen.jpg create mode 100644 apps/gpsnav/gpsnav.jpg create mode 100644 apps/gpsnav/icon.png create mode 100644 apps/gpsnav/marked_screen.jpg create mode 100644 apps/gpsnav/select_screen.jpg create mode 100644 apps/gpsnav/waypoint_screen.jpg create mode 100644 apps/gpsnav/waypoints.json diff --git a/apps/gpsnav/README.md b/apps/gpsnav/README.md new file mode 100644 index 000000000..80c6c1d00 --- /dev/null +++ b/apps/gpsnav/README.md @@ -0,0 +1,66 @@ +## gpsnav - navigate to waypoints + +The app is aimed at small boat navigation although it can also be used to mark the location of your car, bicycle etc and then get directions back to it. Please note that it would be foolish in the extreme to rely on this as your only boat navigation aid! + +The app displays direction of travel (course), speed, direction to waypoint (bearing) and distance to waypoint. The screen shot below is before the app has got a GPS fix. + +![](first_screen.jpg) + +The large digits are the course and speed. The top of the display is a linear compass which displays the direction of travel when a fix is received and you are moving. The blue text is the name of the current waypoint. NONE means that there is no waypoint set and so bearing and distance will remain at 0. To select a waypoint, press BTN2 (middle) and wait for the blue text to turn white. Then use BTN1 and BTN3 to select a waypoint. The waypoint choice is fixed by pressing BTN2 again. In the screen shot below a waypoint giving the location of Stone Henge has been selected. + +![](waypoint_screen.jpg) + +The display shows that Stone Henge is 108.75Km from the location where I made the screenshot and the direction is 255 degrees - approximately west. The display shows that I am currently moving approximately north - albeit slowly!. The position of the blue circle indicates that I need to turn left to get on course to Stone Henge. When the circle and red triangle line up you are on course and course will equal bearing. + +### Marking Waypoints + +The app lets you mark your current location as follows. There are vacant slots in the waypoint file which can be allocated a location. In the distributed waypoint file these are labelled WP0 to WP4. Select one of these - WP2 is shown below. + +![](select_screen.jpg) + +Bearing and distance are both zero as WP1 has currently no GPS location associated with it. To mark the location, press BTN2. + +![](marked_screen.jpg) + +The app indicates that WP2 is now marked by adding the prefix @ to it's name. The distance should be small as shown in the screen shot as you have just marked your current location. + +### Waypoint JSON file + +When the app is loaded from the app loader, a file named waypoints.json is loaded along with the javascript etc. The file has the following contents: + +~~~ +[ + { + "mark":0, + "name":"NONE" + }, + { + "mark":1, + "name":"No10", + "lat":51.5032, + "lon":-0.1269 + }, + { + "mark":1, + "name":"Stone", + "lat":51.1788, + "lon":-1.8260 + }, + { "name":"WP0" }, + { "name":"WP1" }, + { "name":"WP2" }, + { "name":"WP3" }, + { "name":"WP4" } +] +~~~ + +The file contains the initial NONE waypoint which is useful if you just want to display course and speed. The next two entries are waypoints to No 10 Downing Street and to Stone Henge - obtained from Google Maps. The last five entries are entries which can be *marked*. + +You add and delete entries using the Web IDE to load and then save the file from and to watch storage. The app itself does not limit the number of entries although it does load the entire file into RAM which will obviously limit this. + +I plan to release an accompanying watch app to edit waypoint files in the near future and a way to download your own waypoint file using the app loader. + + + + + diff --git a/apps/gpsnav/app-icon.js b/apps/gpsnav/app-icon.js new file mode 100644 index 000000000..890981d5a --- /dev/null +++ b/apps/gpsnav/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwhC/AFmACysDC9+IC6szC/8AgUgLwYXBPAgLDAA8kC5MyC5cyogXHmYiDURMkDAMzC4JgBmcyoAXMGANCC4YDBkgXMHwVEC4hQDC5kyF4kjJ4QAMOgMjC4eCohGNMARbCC4ODkilLAAQSBCYJ3EmYVLhAWCCgQaCAAUwCpowCFwYADIRAYHC4wZFRQIAGnAhJXgwAFxAYHwC9JFwiQCFhIZISAQwDX5sCoQTCDYUjUpAAFglElAXDmS9JAAtEoUyC4ckkbvMC4QQBC4YeBC5sEB4IXEkgfBJBkEH4QXCCYMkoQXMHwcIC4ZQCUpYMDC4oiBC5YEDC40AkCRNAAIXBCJ4X2URgAJhAXvCyoA/ACoA=")) \ No newline at end of file diff --git a/apps/gpsnav/app.js b/apps/gpsnav/app.js new file mode 100644 index 000000000..2a480410c --- /dev/null +++ b/apps/gpsnav/app.js @@ -0,0 +1,224 @@ +const Yoff = 40; +var pal2color = new Uint16Array([0x0000,0xffff,0x07ff,0xC618],0,2); +var buf = Graphics.createArrayBuffer(240,50,2,{msb:true}); + +function flip(b,y) { + g.drawImage({width:240,height:50,bpp:2,buffer:b.buffer, palette:pal2color},0,y); + b.clear(); +} + +var brg=0; +var wpindex=0; +const labels = ["N","NE","E","SE","S","SW","W","NW"]; + +function drawCompass(course) { + buf.setColor(1); + buf.setFont("Vector",16); + var start = course-90; + if (start<0) start+=360; + buf.fillRect(28,45,212,49); + var xpos = 30; + var frag = 15 - start%15; + if (frag<15) xpos+=frag; else frag = 0; + for (var i=frag;i<=180-frag;i+=15){ + var res = start + i; + if (res%90==0) { + buf.drawString(labels[Math.floor(res/45)%8],xpos-8,0); + buf.fillRect(xpos-2,25,xpos+2,45); + } else if (res%45==0) { + buf.drawString(labels[Math.floor(res/45)%8],xpos-12,0); + buf.fillRect(xpos-2,30,xpos+2,45); + } else if (res%15==0) { + buf.fillRect(xpos,35,xpos+1,45); + } + xpos+=15; + } + if (wpindex!=0) { + var bpos = brg - course; + if (bpos>180) bpos -=360; + if (bpos<-180) bpos +=360; + bpos+=120; + if (bpos<30) bpos = 14; + if (bpos>210) bpos = 226; + buf.setColor(2); + buf.fillCircle(bpos,40,8); + } + flip(buf,Yoff); +} + +//displayed heading +var heading = 0; +function newHeading(m,h){ + var s = Math.abs(m - h); + var delta = 1; + if (s<2) return h; + if (m > h){ + if (s >= 180) { delta = -1; s = 360 - s;} + } else if (m <= h){ + if (s < 180) delta = -1; + else s = 360 -s; + } + delta = delta * (1 + Math.round(s/15)); + heading+=delta; + if (heading<0) heading += 360; + if (heading>360) heading -= 360; + return heading; +} + +var course =0; +var speed = 0; +var satellites = 0; +var wp; +var dist=0; + +function radians(a) { + return a*Math.PI/180; +} + +function degrees(a) { + var d = a*180/Math.PI; + return (d+360)%360; +} + +function bearing(a,b){ + var delta = radians(b.lon-a.lon); + var alat = radians(a.lat); + var blat = radians(b.lat); + var y = Math.sin(delta) * Math.cos(blat); + var x = Math.cos(alat)*Math.sin(blat) - + Math.sin(alat)*Math.cos(blat)*Math.cos(delta); + return Math.round(degrees(Math.atan2(y, x))); +} + +function distance(a,b){ + var x = radians(a.lon-b.lon) * Math.cos(radians((a.lat+b.lat)/2)); + var y = radians(b.lat-a.lat); + return Math.round(Math.sqrt(x*x + y*y) * 6371000); +} + +var selected = false; + +function drawN(){ + buf.setColor(1); + buf.setFont("6x8",2); + buf.drawString("o",100,0); + buf.setFont("6x8",1); + buf.drawString("kph",220,40); + buf.setFont("Vector",40); + var cs = course.toString(); + cs = course<10?"00"+cs : course<100 ?"0"+cs : cs; + buf.drawString(cs,10,0); + var txt = (speed<10) ? speed.toFixed(1) : Math.round(speed); + buf.drawString(txt,140,4); + flip(buf,Yoff+70); + buf.setColor(1); + buf.setFont("Vector",20); + var bs = brg.toString(); + bs = brg<10?"00"+bs : brg<100 ?"0"+bs : bs; + buf.setColor(3); + buf.drawString("Brg: ",0,0); + buf.drawString("Dist: ",0,30); + buf.setColor(selected?1:2); + buf.drawString(wp.name,140,0); + buf.setColor(1); + buf.drawString(bs,60,0); + if (dist<1000) + buf.drawString(dist.toString()+"m",60,30); + else + buf.drawString((dist/1000).toFixed(2)+"Km",60,30); + flip(buf,Yoff+130); + g.setFont("6x8",1); + g.setColor(0,0,0); + g.fillRect(10,230,60,239); + g.setColor(1,1,1); + g.drawString("Sats " + satellites.toString(),10,230); +} + +var savedfix; + +function onGPS(fix) { + savedfix = fix; + if (fix!==undefined){ + course = isNaN(fix.course) ? course : Math.round(fix.course); + speed = isNaN(fix.speed) ? speed : fix.speed; + satellites = fix.satellites; + } + if (Bangle.isLCDOn()) { + if (fix!==undefined && fix.fix==1){ + dist = distance(fix,wp); + if (isNaN(dist)) dist = 0; + brg = bearing(fix,wp); + if (isNaN(brg)) brg = 0; + } + drawN(); + } +} + +var intervalRef; + +function clearTimers() { + if(intervalRef) {clearInterval(intervalRef);} +} + +function startTimers() { + intervalRefSec = setInterval(function() { + newHeading(course,heading); + if (course!=heading) drawCompass(heading); + },200); +} + +Bangle.on('lcdPower',function(on) { + if (on) { + g.clear(); + Bangle.drawWidgets(); + startTimers(); + drawAll(); + }else { + clearTimers(); + } +}); + +function drawAll(){ + g.setColor(1,0.5,0.5); + g.fillPoly([120,Yoff+50,110,Yoff+70,130,Yoff+70]); + g.setColor(1,1,1); + drawN(); + drawCompass(heading); +} + +var waypoints = require("Storage").readJSON("waypoints.json")||[{name:"NONE"}]; +wp=waypoints[0]; + +function nextwp(inc){ + if (!selected) return; + wpindex+=inc; + if (wpindex>=waypoints.length) wpindex=0; + if (wpindex<0) wpindex = waypoints.length-1; + wp = waypoints[wpindex]; + drawN(); +} + +function doselect(){ + if (selected && waypoints[wpindex].mark===undefined && savedfix.fix) { + waypoints[wpindex] ={mark:1, name:"@"+wp.name, lat:savedfix.lat, lon:savedfix.lon}; + wp = waypoints[wpindex]; + require("Storage").writeJSON("waypoints.json", waypoints); + } + selected=!selected; + drawN(); +} + +g.clear(); +Bangle.setLCDBrightness(1); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +// load widgets can turn off GPS +Bangle.setGPSPower(1); +drawAll(); +startTimers(); +Bangle.on('GPS', onGPS); +// Toggle selected +setWatch(nextwp.bind(null,-1), BTN1, {repeat:true,edge:"falling"}); +setWatch(doselect, BTN2, {repeat:true,edge:"falling"}); +setWatch(nextwp.bind(null,1), BTN3, {repeat:true,edge:"falling"}); + diff --git a/apps/gpsnav/first_screen.jpg b/apps/gpsnav/first_screen.jpg new file mode 100644 index 0000000000000000000000000000000000000000..34fbe1b506bf3b8951abadeac5589b11b202dc0f GIT binary patch literal 65452 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 AZvX%Q literal 0 HcmV?d00001 diff --git a/apps/gpsnav/gpsnav.jpg b/apps/gpsnav/gpsnav.jpg new file mode 100644 index 0000000000000000000000000000000000000000..975fe39032cb28fc755874e231842684fe3a73bb GIT binary patch literal 47970 zcmb??byyW&_wO7I4bmbF3W#(|mnb1hN_T@aNH<6yNkIh!krFA%LpL0dRJ!AUbV?lh z4u0c(?|puM+~+=b4>S97)>?b*wbrhg*~9h3^#VZjR8CP2fIt910X%@~MQo-gUba>M z@ccQz1^@syfD0i6&_ILC8GUnLro&|UwTU-`oFk45$kVzz<4I&{EZnvjQeldp+vGjbTDdY6N!E|bwSTS zypWji#|CsE0bw99@jv*}KYsD@@O(o1C&CcvPtbqyi_drdt_y6b?7!^4=@mc@+TZjW z4E-;R@i(Ri>6rgT=lf$PXdC8K4*wq;z@CG7mLu>7-~G!JP}yItND1cn;EC}+wc!6m zW9Q)&<>3K<|1$@G*hK)K>i{4-ECA4+2>=6d0H_wcsR&Fru7Gs|xR}Q12rMYN;Gdqw zV5_15^1!}M3QFAc>Ki#c(9)as|cxy-1!#+0OfyS`v1ZVf8xjt>dXU}|BHVAzc9-` z{R!F!u>UJR0@enYIosR1z2f0fAw~n90~){!Kp8x>06oA6umEfUXTTHi1!90`;62Du z2UNhTCZG-I0w#bZU=O?kyns+33WxyS0?$CM2A~F()&vYet|edxxB=dPAIMJxQUE2e z?DIb|x_|*-23Ui9Prw7z5Cg;ksemfTQw7Vv0J#Q$DR>xwI@|#tP11!RCPKsTfa;t64dOafxSW3Y}I$OYsU+8wlqfB?V) z`cVf7f^b8YfHctBejo!-hd|ND(U{RV0Zwp|O9ToaI*>!42lUGefP>!+={*QnsgaI-IRDzPi05{+W)I)Y57-+ZA zxIr!tAOSo9trP<-e+aOGO=bXO0pEdNz!|^?9=zZw0CEKXTtxwC&}V(X35>HpND~A( z4?(S>fH-)S0zFm&Tgn`4Cr8j$VesGqXDuy267*XJn|M~@>;s4WHM!=~I9Rm{!Thq$k)Y?tc z!_?m0QumdugQc6fslBD9rL&W{4H1MC0C-ymBgrX9#8STlL;yDN9a6g2>78$jLl@B*-ZzD=5Gzz$+umDI*{&$oWu+S6D_?m`C=J zu+SfAQ1_n^@=yL}1_Eh+^8bC!VK6f_w_`9jb+B|bWdK(j2L}c#ZayvnQ2G`aFL1U5 z(3HUoh;CLuaI9l>fY(2C?HfA!zw{Xp-9-52yjf3gYUg?H@>tFf>7{NdE z7dLd`f9TjZ^TdDX6#vrk0s4RO&B}U{z-91HeN=zt=y_mn0iHMM#tyK>ZgTWaFt-38 z?gd~AR)F{>f!?jyfxP;Eb8tbvpFh8=e2;fAs%*IUf5H4Pcn_M%Q<$|A+Rp834+_ zlDM`1p*;`=J31Z!bk{nYx|;sc2aYHJ%?i9DJ;(+AE+*VmWX;BcG)fELH=7JwKV@&Y0ah1>%t7zmUYa@_$A765_) z`IG)K9Q^(FEQf=O2MSby!w&+5qM<`EFm5_G#Q)}o4xJc-@o41xrX52lHZ}Aq+-6$@_?01K=7fEu!yMa<0o?R3W`rPUTA7*gYKGJ zSXx=z*uHdo1}e#yZ0YbKWFFU=H-7W_*!03Syc_MsjX{k z@96A8boYG!IXp5tHa;;qwYY>_Uir1Uw!X1{@cZ!S_yl!&cHT+>|HCiv zwiSYgjt)h~y73Ew=6T~dF*?RwUQ7}hH7rvX(tCWt*kq3qvdUU<82Q!rZkxIOz$IrA zSY+P6aqW+1|96gs{6Bg2uVer5YZ_eZ|MChA0$PiP1~wHGOz5BsV8Xz}_>(aIPFQ~u z_D#b1H(i5DZghZ!(ZN3)ObpC_dH>hodKR40$*!jWd?+|U5<`i>W%)up5OxdTDOb?b z*((ct%M#G|V7C79< zN6T=&^F7m}QtBQi^JFFrhToa4>>GHc6JIYwI_(NYw;B9;5~am6K3>|TIZeO~TV#tB z`ecbbN))#Oc4gOm%<80;SQo!?>SkU%^4asDmmJ)GMiDRXP|f2^L=!8OwQFFMwGXj) zq;+4X<*o+GQ%DwJyjPmXbq$ygQasA({E7+CkW$bj%+og7CBHkC-@mN1n(}|ds_ZSP z!(^RB*PbUf&X1fC7(I=?1|kEaL(Ap+;7ttrZ#AVEWzvs1R1AEMm$d~MIVR=JG=nJ+ zOxHj{r@x}_Igg)Ag;|DWJ(+U2AcA5MNmJ}RJD$F08x3hOCi{jH8w>3n*3HlghanUFmKo{PWj6y6BQu>Mh zyj!+^PoHhRme|`~DPYaw60$pZ`!_jRg#+~qWRSe<_VoSQ!g1Kv!k{%ySTb|(z2U9r zD~g*4`(?MmgM4;A9?#v-SV@fwVU}i}NFv6b?k->7K<@9kECdv;!Xo0xiMV2mu?Ssj zKE5&$MkZk9z~}07Zrc|YO4D ??VOy~H^j>v-lGF1J`dMTBu4`zK?bGToeaHw1cy&zV)}6Y3O9ONQkTg+YzYGh!`j z9VU(hSzJh$2oft(MmtHfnfL?aL0fq;i=*`5x8q&C-=T5ppR@D7Z^#n4#A8ve(l4s8 zIPN^8aaf00*FaA-dj#?F?#tPS_?jeQUyAIe*1+EtMMpp?PRd{bEaPK|NqlyF*)&W@ zarc%j7lc%<^7rf=Pv|ZLWmb|_kbLDX2W7&C4(6}U6?uPK$xwK)Bh|j);}+acplzny zNs))cCDTR_6B_G-+%JCcgG>9nvojVYG|qH9Nz1R0WSX2W2S$Xwa5#v1v58KnNL=kw zxk^ixZgF)lDT!DMp)hQc;7B#AwCb|pP7~`de^63A$k$C)gYOnUfoMkR8e6_ytV`4v zzFK1(J{v_ba=B9MXi9~Ptd6ByI`mZM*ZVQeUU=LIV;srk z&tY)TOpumthhYv%I7=q)H^O1=X?WeUPD^2nupn0t4D)pJ^h2aznH{q5z2o!c)Jl?~ zvM(mZzi&fXf?HdW0xS4m^>j%Jt=Vn)e;gUVHlnFX-T5U}z(@4RFmN=JBWRK#kWek7 z>fL8Q;h&Ya*j678StX85d3NLyJpSrK;&Z&^qs?f&kEiDA`%#ouS*ZMj2U`S14@2142UD1Yl9qxbAI4MCkTjSO_X1{fv6e$@RU6F_Sc{Q~ouktF-wFhqSMv@IqzBcv;Ul zoX93Mxv_nYI*X(za!c4*(tuUU({`11GrMuGs4ktqIZ;b9UZJG;H+u*+qU4F|n54)! zw?op?hSUey&%B)|WkYh1j4X`fw6$OKJAG!}5g9UeF~i?>KjK>mZlM@tInzkF^PoD) z{~FkPLNhM9&Jy_KO8$E2jAXUtWqOIU{hk;dB6^iuoSIi`2|XC*2!%@(`>tHBq;ufc zb_p*W9rn9upH&j*8W70?uLc_fAIQ~L=O2EJ-tro0BATXCYYUMyuOy${*72kxjd4j- z&H9F^aFx7uhhO(0nS!Kw+_Bq?7VX(|vKvkF*7AXr=vuCk{>*@vSB9Wa_-huMFiS0( z5Pl5;B5rn~b$XtLG?*h9{y;@fs2^iX;o5AI9%V(hOvo8fdwXy5p5qK}qMUG#_^ZwI z=ne7bC7X1N<6K9B#7f6$=cjtUQSy-7_=^tKH9jxOrCR4AS}XB*7lc~EwsE=1-JYip zF5cZyd+Ly-g+Af4Ogw*aQotDF%(p-&?avRRdgA|49{q^6+*z{WXjeJWje?uNHOsTT^0fGhv>`ca9CV{T8v`>zB%5|WL9Pc=Mka^&6ENW2(XoDpAW5u5T7lMgpu zH9J(vVTClnJP{hHaEuYGmq$=1$K^dKJ*2kwPbFf~p8IZp|_cT}+_?EY1Nzsp$jESV-fVK_<8rLQ>L2oLl0h521)k->ZoWBmXG{hsnQFfD(4 zR55Ehgs>IAldwTP$i`|8$slTaaZXnAX5@~vE}nx)wg-!L*>7}D>}Aq} z(20{HN<^+cpIi%DBGn^>K?!V%qtg6l%jOA{W5i{}p%bxJ=&?DUOE5Bi=+ ztU?Y=(Aq+wNk%#ek7B>ItA#sH`Sy&0>6^(lWjP5Sf+|Z7hAE`8Dh`y!H*{L^>Zld5 zWXRo1P|9Q)w@<*2vZ~y!>WIhEP1xh>kW%^5Rc4xW#NYOOMha>lJaB&#P-df_?CUZdIc)cIO#`@!OTy zrS_HG;c>wYEf*$N)_C3lA>!$oz>G@8@|~i9_JH0x?zUZ+BnJQd)Ypw_43k<_%wI@W z1{zcSLx%B@sB=j_A!`-xXL1};VbTn%1*@qSt|}qgQ5eHI|6Psb*T%9mVM8q zN^{CzLSXI~LC?3!m|#3czjYqCXdEYn=_j?XFB`&3US&_GLv8Ep``V#GdX?oCS@63( ztVX|Zceb}HeHjr|LC%R)aRa31LKni;tv_?-P@LtwjO$_zc4C7d4~FaK;LW^W9A zmK7c~|AkU2uIyLVFL!-ZGwGA?T&LF;c7YS{HiG9h-{M}nYfUHm?0516v}d4coolSm zOHp(UXDVYO#+og2P_|BQdhN4WnAlx1P=cQVs3#sm9(f!)^AEnZ!(`-uy7H*5sHGkBuX&TjZ zq3Wwa%th(%FN_~Jh)EEx7cf=IrKd!H(X=pg*}#Qe%D?RNmxNGw%;?a$gbt6D)9a3y zJ^$sg01Krz?#)$wr_o&dp55SU@QA(X{9)&-HgevAhx#?cX6};@nB$%iAj*n9yt1)~ z_kQv=ctE)4=-vm3xmv1^?|3g2ST@&FyRUxi->MAjsd8!QeP=i+{%Y{)c1T&fTKo*k zy*ldl$q6MBQQ+Xqi=Wp($h&zR+e}P>W z5sUSYaB@>q__Ao>7sES1%N5O0v;+o-ormL&FV z;;T>65PBCuvs=p4v}10j|DMZvhnN0jdvyHcO1GlntSF6- zb)$N)rfVl4emUfg*ffO491aU5Em7-`Q2UNzkl)7-jv%N(e=E{65 zNq3c5Y)5&E3U^f)aTo51km^lc=diTGRhW9Q%~B>ZxN6W@)5^xg@BsL-j(EBD>bSiq zfxwlJCQ)T|>TRZ4=CsNMmD4`kN&DQL%bW`qGsP5k`dfD3gP2N&SUnbl`}Z_yl@aar z>LeuhIP$L($P2c8_`ZL{4tyrQLJ$2zBh|sMF$-z zVoa!TP39n&o#*y*y!^&}MR5(ZDm2KRn+0?>F=mLxI9Likr`P7`PUw4{+i-`tu_2gF zpE~XVLV)8=zsd)fdk6+*&M2F!&w&e3*FZ&Sht$OJ`EkkR+Xi1J9vjBJt6Fm}^XXfM zocLpAHVObMy`^R<<8QgsE6hiMu)*n*M~2kL)2QaWr)l^`9F0jftvwkJ9C6k}Pd}cP z?$R$}UEH|_u5beP-z~hQCl266r6LxEI%s{L>PrO5jcl*ZVzdSQe1dV%aj&kLk7Vfk z>u?$#ZTy%E7SM~w4eoo>OP<>w_8FH{TKm-{e5J?Tg&nuu@!ap>ASQ}GCuDVFWD`)K8^#v-eD;1^T!%GS8tYmm?onz`KV8w1@NE||p2$P{{#g45=l4$xWpdD4A-=IbzZ&Zw*H({` zJvfcV=YvyFB15;kJH5&CKg%r9$B;K+4e8N}(lR5fs%jFSuiYCS{CH2{925Cw0}pWJ z=~ybY(SEZOM{mcsUat7??cL@kc;XDJyOPH&36b+1SJFiOA#;hBImuPbh^!;y2$=lK ziV(>Ytoh;bpUt1+P>k@7Yk=SuR>wRBbHw)%jFz#xZ^ekkpT*!ufAP|aN>*}M40YU0 zy)u)eL9GbVa!JVTTM%Iqf8hOC3ilXeEMO0DG5(ZUvD+C(plN!|L`+kvg4v!RJc& zb3>5&cKlZ^@z6o|%2<&siC7uYw{9r2yku1t8BQ3pH$^K8>_tJB+8Ifp_}Nf$^b-M1 zC?T~uEt@GegVQ74@w`CMA(P_!yz zX_kJTl}7Bt;?7tiG%*5Yw{49E?|1}G%h{piHJ}&sN$UFNnbcNA*NVq}tT)!)m#O)1 zX594HkJFpl;=O9WpDG~m#*=o{2FBLjL?CDDkw>M=?@JJeGnLl-obMI+%f9&%5wNo< za3W1I)CNn2)3sF(WZ=EJ0j58qXxS>HDPw8NCg^xK+%DON^66G@E7G|4sb(gsbtx-g zWxRxad!)aMi8qpvuxpq*LPAr)bAV7$$tt=Z$G3(2(ze4YF&@g zVF`yP2tl7kQ~w`~_R}?qZokdv=f8cis15lwiR3H)(xa~J>?n*8F?*GKMnkzbt|F&7 z!+GCQQA;hc_+W*?eL(cw|0RQYxGAGIe+2c1rwIoR!s78SVgoXg1>Bg*D4_PIHJ<06 zFeo8G-&f)JxpEe8Hj~RARt!anK@T%tqlwW69H}{uF`7D<>+4Dl2k3l!A@;b1q~?3_ zW&?DpblOnB_f=u<+v*UHM{_=lvcS`7v>k)Rki#oo?!;`TEdyF7LB3 z+VM!I`_W8_a3)>cpFkfL9G>T<7(CMNnJu3`H}P^`>OI8H?tQwqnc7LpW8{MtnCNl= zErDGG@5Ez(++`*YZLaO{6 ziX9gk)Y#4o9Iiiq+Tyn9Q6@sv6`7B|nxSw~tl(}alTPjmZdQcmuUxqpHb%57=8DvP zATs%ak0;dUC2r!2Ox+R~jHnCv=*kqeV$J5P^gtu@LK^=-%gKwe?6aEvScq@fZzqsPs&W-_ZOv9DT3odIvRl{A4h9Z1X3%5V=#W-EXJ3Hx@iLHh zi4pji!HX~O7AFa(9685H2(>m32UmwvBUF`z#F^~QM(bX~Yu~cps?oBCj=-R>G5fl% ze5TLxAJS-2SS0*KHjP%egBt|OE9s=Clj1(UWAF!G>WgN3?p*`Y>DcBZaxcO#2;`L~ z=~s)n+#PTf_Tl4POo4}=nY)DD(eXV6MPGV&KKx~id^G*duOSq6iR|K?s*i~ae~mvm z>&Zy)=@P;oYnRfnCl$k?j0o+EbTzs^BYb6?EW}erTPZ4WQO5BO!z>}$k|5VP=YW4W z*Z=NbZwD3k1?TF%XXN`S+K1G|>OVfec)>T-RffP#>JVte=bt+ z#XtR>9;Yh*Oslv$%hQSCTnZv{s83DJ@2^Jmlf%ccD}?Wtt*WO~vnA$kimx=CM~i^!Jwfoy<&|L6%hb0-g@X zE2V1y7QpoF`J<8Y!F-Oy#OJ6Fq5J9O-0F%Lnok~Qgo)9Qo?MW`A!WVtpN?GN8E%mB zO*%Dw3)a7Nhrytuol=#eFhmi{1$;qU5UTLO12~Z`lR6kGxH9B7Zjsu$2KL>SJ=a3LOOIMFI@0Pbk`J&J|>%z(@{nom;hce`X@-Otfd*C`66_3pW_X*T_mN~ey7Mot|oeB0^) zy4^2+-qqmg(^p?{IBZEOzGI3a8((tHR@%ru`$Rm0ELI{mqpkNW!B(5jsJe?L^&aLy zx1i~sI>`2TK7ovRE}8N3;|=}S=~pJ&5w=lJ)@OgXDaz8$Z~bm=HYeOb1uH;Gj&&z-H~k37bhA*6M+>kJUS z(BBJe2}JK%nkTBOEXj3nfYW?maGMV^Dhe$2%p|%nw%i+UyOZ&7pJN@L{EPH=Si_qW zH94QMi^9{dm-zt_UZu#vxP0Fa&2DeXKErpG!UD{I763YOBA)4#-BS+NdwNbUl={o) zJ4?caJ8Bq7ADi*8cAqfPiJz3Ta{1JyGksfgdl-Nmm1elJ7cf&)B%tG6h+u?zaPX&} zKy!^otCVE#>FFSvrg&4#CO86{Gq8p!FYVr%i>B1Vaiejl6}1L@_IwkJOBS7f}VEp&$HKGOn;^@RPpMFw7?6 zk<7Bs*45+jEZZ}q%$Fp#@gh&AUI%xHA*+4Il{0K!Gp2uqhGw`O9(7u?z9Ny6OUtr7 z=IsjMWk<68#1G!d{`{-XPAQ6G2mRQg-0(F=XuJ%y4*seL`lvyTrM4L$(z>}meo!#_ zI83^Ab_9Qcc*bMB%kF;vUA&YjtN0X}^4rttFmsqS4ZdbF?{3E@d|nfrRVJUaD@~29 zzO+dDh(mGHa-Y!|2MA3$fT+1P~EVVrg z&_k&=&xTkvaLrfL^(lK;f_M*qmB>;qYAWq?3o~3bHS3Kk={_v99!i#|7|-*0Q9ZHc zI-WuE^N8I#_L$i@Fs8QqXh8n-_Ak-qb|EvXAL)*GahxbD$%r$mlN=bF5o?H0rS$i0 zKBmZ`^GLOD7KTI|1hgzm)9#T0@%~P3zR}t+p2Jf{n%CRUVj&1e1YNeEPrGVUnb>xu z&BS7IkcE>$X(_F*_DEfIuywJ%;KvJ_HJ5l-3Lf!=Bdm2J!6o{LlPUTSZjSwKHnq!y z8I04OhVAR9aiv06OLC{RjQjQVLkxRean-YC_2+7EPqsKl;u`Qp0NSC(@Tb!Jdr1nY zT;zK{vAs)GdDMcptU+JzNWyOb`@C5XMZy5RYagNmxDv8wM3j|k@9n-> ziF;oE!-<*v;3YAKlXDC0TE1s8BSFWJ=^<0J=bGX%U6P&CK7Ch#!{SFt>gRXb&&@K1 z2M)BiV1_yAtjpr>XO#J*)jECew3bHEG4DxrT;A!r1~3Q;^VaJGV$kJgR<=8A28Jb< zv{%t9@a>^1jH##5ZFX^#wxTL+aX6FudZ-X3h7(Uor+7!}H+F47PkQcl8FCGP zuM02(#+#ro-Ylt*uD5V*;T+^F%AcV$W4H4Qxd?vx#LJWp`PvnT;887{?eQ9~p6~S{ z0~*g+y;9l@Q4S@_?s(7D#R?;T!5$1RQ>ZW{w3Ac6j`{e>FFy%!Yz#K#LnOQQOLb)d(lO_S7RHM=h0UZ zRU6^z68Am#4xGXwT$n(fItsbo>F2cXd4-F0&U`_*FF=RApBY8Bs~P`GN1)JF5Nc1z zFks5Wa-Pk3)$cF3NEk_nvHvUBZfOvGlYA=goi{}aUYaL9EXRW0d;=Su4!hsWF+C;! z^M~ojC)@|(Jh0#M7i{Mo-yb{CfO~axqMn^*hyq(xBD!CE`l0j1_Woa6Cr;h6On0Yg zy^p`R`a(=T{7yipmJbL_)|+*%)qJBUj&FW8$_=-T&V>b!)4n&!xCY+orJc*mznMPi zJ&45)Adp~v*>XK{hV=^jbuc`(QH8$vMXHUnGLMfdfyg2FxLL$C?UYQ#V_>mNf7K|$ zEkkXL4yRnESq<$EWFHPKyJQhzCsKNq!1LGydw_uOe%k#4J1640k3SeSXAlx-2LbQ1 zO3YJ@?^54Y(YW#%?`*CfN8m|CWZ+2>{8*u%qDrKfh=+ALdY{&Z-laIRYBV6fJ(3zN z?&rv<9%FxT4O})#*`~$Oqr&|77j1iOJ@9|%e_eT9P8yzOvY8Q+5&Gpd01!dm5obuKuW!)lNEA8Bd|;QlxccO6-()5dO#a36pN8N2O?W&AJv` z?Y$|+Z!3$(Gq5F(&W=^yeN~lTIn9t5NvchC#7Phz^EQ7ILqx!Xz4~Q+P4orzGp`!# zU@YlrW8p!%K3|^~rTovH-C`g3bO43G_Ph`2i#c2d+2blsEiQ*jtI8!as&+C+Z7Fwt ze(YlZ2uqLu5}>M5sXuP8%<|(Y886gGT{Y~LqVV`&s<@^fq3rr+;%}C2m zBfXgNC!azUBWio%|f7sv_AaeY~yzBPT%Bj2cSc zfr%wSXgrXE%S~h2&}Be`(;@<;bwT(HKl8Su=0Xp$lvBXlyn0TECJrathn-3XTzo$}y*?@%J0G_U$ccIM8?bFmt37pWVVS4pSJvU{ z``Y1n>XI;AB86LqQ3&hWOhI>`L~hP~d?&49s9<`~Zok8WsVqZ@Fq(g(6D)gM=O928 z!YF*Sx;a}F` zqH~cUp-|z~(D9!o*xC5?!RWz=Pm=k?c28{l`rdvoTO(A*d?Kr7qmfdVocJS0`dsEz zh5{O|@@eqtWa!gOu1@KL5t2Kx{3D0rgdO8QBuP-r$JaoZPczKjR%>dB+N!?1AyM;c zKmiH&rsUG`>wXqVb`21jVPgMkE*OLawo(V0vR;Vf_S}zI>X+MapjT{es7dOGvZJ1P zNzOYf98F)LSf(Ao8!tw{u2-Y;GiP%=5$0R5T=VV?kFF-S9W0Z>$!TMJE06~H*p?`0 z(mW#@?{LuQrSaB>toG+`W*-K}`^#4a>I7D)T#&Y3;mn@1U$BA(7A{=_SQpYGhr|9D zaY;F-&;2Fna1r8auBnVv^8D81Ipx(4sS2!)-RR8nxL`?Un=3Aq*A>0j zR#opbrG82h`*_}j5oeL<0VzbaUB%ep{oxX(H;Mqcgirho zj86XPDlx&H+>+v;S{0Cz6{&}<7BGlF< zz)gS!;<~Ma`IU_lY^G&*3>Dc7?9w3$q&BS3dKE}PcSESC8OiQL7ZJyYt}oA+n|k+q z^MLtSQJ3H5&2RzrqGQXEkg6Z6l34o|y*?7oZS6kGWQpW_w(+O5?Qgpi<3ikt zz1V=0#&0+U+o#YmTO;a-PA$Tv-AMatBZ_?>=3Gb<9`8_D2TMu(IX8 zbv$pFHxWQlE$L9JJa4=nxaf}nZy2ncC@y&S$D^}eqkNYHgs9vHx(-a>V_QM@SY~+Z z9-rL70&@o-(Glf~fK{(~Dp?ImY!{A^Ku^=bE-vl5zPxEC?-@ zKvJ{oNkD$UY$nNc`xQax;t{NsWrQ$Igc7~20RwrC$ZTuI^0O;`VrTC8rN{N2_xnz4 z%I~nNy*)l*BxC9&R=Df@sn=l05{>o5v)|m5FX6+6ml=16CML3FDB3O-=oG~>Kh$OB zdUsFq@g#{2kdd1R5iU)~zCRlc4|S`XdSFKIiz6GLi^ymn8VPu%QBT?9AG*>bL*euY zSo1G4&Tf0CB_&pHf1-z(_i8opy(ebdx0#2*VS_5ghVY80WGo z)uhmLi$vEu!?(xu~G zA>9dt2JhG~pC)ZvxlwfYl4gXmoShUZ1brfK=?bJ*dCBk$W)inFg^&P004a9B)`WEF z_?W;}rBnt|wHaQi5r-$sf?vTcLoZOpHlMMZ8=#Ofgm~Z^{qnN9be75Z1a{g`dS6#= ztheFaQ$94YwGuowI*Ob_zM3=L3Vmv~YLwFnMBQK+6Ir1LpDyx&Ow-K`|4uv3hR_o~ ziv_=YSOyld^I6KA55Jrov3D1b$kCd=aDkUDS}I=xz4PN!Me*Npj`I0GtBbQ7T0Ul% ze(NW%F0yDZQRqfrNJ!EnuMR6)W|6=oR25w+JGTGOeHPOSu9poWcUq;0yco4Z?m9ZG zSd_)26>jFi6VQ7Y9bWjK%M5lGhP4jZos*#)&ONT$k!@4YaQ4R+D}`8OhPHoIHS9mh z&0VSL%t*Uk)xkeq$1AT$7J`GULD$|}$(=Cxo@LsvC{4%a{oeFe+5>ABQ3 z(DoJOvOl=UoU{H_cTTV$d|$WSG*~^7*!|37r!|d{#>BHU=^C)id?O2PBJOb`u{ts% z0x1GWP~%;7M@_*_S+=QkwU@O_d2?5mjkcVsy4|gu`5d`4K`&AkOs)Yj^_M5A(&gSi zd9bAT>G(%ZkQZ#}+Ej05WEc|_Z{q>JL=qAK$&*Px+bjttTwkWaz$+#XMd1)(M{UGQnd*Z87K=4ZR}xSBjwQ3-*3PYNpq#>(WM~q8S5OBD zGt&C=?oL$}o5Z@Ex4ESM9;a1dsVO?w`IT}YydBKXZ*IeeDKDWD409W+WXSAIuz)S9 zEO~Eu4G@-&HB=v!tufE+4Z@^uX-x_3S0@I)4L*K90=Oa~a7B=X^iNN}@|nLC=Q8sH za7m~`<7J@kwn$JV5zR>d)?TI?;aC-d_LE~F~ieq%c$|*WI zL%YS*JskVUzKE@{mUt3{NI9ps96{-VKDY?H9}~yTSQiTW&*m5_MlT>a?=jN~^<}=M zS!j*yR=+(hp}-F#F61J^ZrxDklXAK6-!E(rq-wUJwOdqBf7#L*WNLw@>2s9ufX-3Hbi$&dLP??@&#o$}3;YL|7cfpH_@uD(x{ zYE{DE7wE%MXxml(cLhpAQvxmO#)?*~V76>Jy);STXtr3rOj-IU`R~oF;#Rf$dQVap zuLK6?c2O)UT~bu2{0=JX7;)pm*}1umv7b6hX3>7{Vb*tdD8C6^)M^@JxOLf`7)>46 zB@?{f*$s|9Og) z)XCO8JH&XOtj;?=p1P0M&xTi@co2f;N-2lc6nJ)Y?x+&>Vx1|jyW*Kf`i={aPXE^# z&b*YoUmIFe2@KGr>D9Y|YN`UIq)c}<^s#;^9LM^YWcX<1o;R=2t!jsWZ+c{6N1Ud7Mi zx299#{JBzZ=<8~Snn95r71~FKl1Dpq5A?Y)Z07C!;)G6!Y5mMVe8MB3L#S1zi zy*y?*+w-tkZ^w-MJR2)tzB79)dnq2MYYHu2pp?%Wv-^yULE7Rpbjm6!tE$uGeq|Me z+*0j{;FDk0tlseDyS_jM{>RkVTRao%!vYvPoxv3FM|Xsg1z1Px)3---?oudp{W2qj z=gAkFOt%G}V(6C&Q=Tl<*BPX;DwHsi+w&K=GudvV0F)m0i8zpa- zw$l@#d=;Miw$hWmDh}+>p0|oR;xum^KPFAG^kpaM>gQfcomDLv3w!Jc_eA)o9F~O8YhNO{fz=r4rFZvXNBP6vvs9a+Y(apL!=w z{r${S7MsN7_es6dSqTHj*vP|lX0IZthDtsCUeD6B@@A{?g#Gt0K}EC1N$=Cc=|G`P zr+1z2JW>X|nZA52OJTx?z~JCF8qt^FyO)qxS6#-?X4`83b)OI+MSyBppCXKNSD~M< z2_V=P?66^}7_t2EYQ1v$evOH)gJUUewoOIZoa2j>(iTcCrGa6(g>&nS;^;Hk*7?fj zF2Y*@gObdb$pVG-!WZ;QgG3WvUr#P+yFRCuq}{I68npAeZ+xFgUm?vpvA>z4oXf?? zL&=D&uwc-xv|pk+0CvQ0qg;Fk*Rk)ay}|MtKrg$Dy<+jxMCtCGw_F3az!yX>P~M)O zUp9$WR(}hjtfEEReB9tQtOhvR#AZ2mx1QioNP44Z_S2&t&~MqE3-~c#W?TsdjL(tm zjlJ{EyU-qO5Hj7XS_7DnuxUEZeF1P8F>6)Dd1qTmPj@LRmMm z3Emzj$qK8awoMpcFR6fiez+E!m*Ayg!0`MYxP3TDD!sqEZMctYk)#^pZV>!@Au+o2 z?PtLE4CB`ghWV2SfyAk{Pt3J76^Ua@quG#bN!v%c1A&RNgsOEv#bxunl2mZvR7TmB zU#34m7`L^Ahz+Hm#x;mfBr!_ybnhDHWw2j6LXiyki(^1p4B^2435>dec)=V5uKEHRnq+U8sLnR7tJ?v3+s4C|wsgc54+&A`4GO=-0v5Oo0?~&&4 zz=f1+pq%^z`0!3g1yjUQU@Lb-0On=7Kvc1##m_CXp(-Yo$cIYo_j{Ips&}e6n$1`w zJYH0%>G_SH8(`rF?(>Ia2aE@x@54Kcqo{6QB^@_M*A?g0F0pG5ulPa&EjIR5EU~8G z`sBQFiB2gF`&MptaL)h(MxR5tp<#9DgA(!dD13{i>G@+Z6AF*M5SWwEA42N zmXb&G9MfovyFQw;R*NR-8#FNWvRA4_PAD>Z%qCpy^>R;fp_kv^f}6q_mX`_IX$z0| zj|nf~QZJ=Knn*{%=l;P-WJ~Iu4x5JO1@uJy*&7-3nTEBAN=iDMx{KjBOC2sbE+pI3 z_EzUDJhu-f1$Da0UA2uRuk9ynlb8klR$&7viI!DmOk`2kC{ms{Bnd`nC{7 zJE?4`b1RUxt{05zChd_YoA_~{ZCM)^(1}8W3|%;!I`vH|6VP4GK>96}37xY z%8$8`NuVNR%`A@59);*LjU5H`=q_ME-I;9z)BNUEIsZ?dJ_%EL3Q%$SC#!h)v$2&6 ztv@oL6_?P@XZ3{|6J-ey<3flknmYp}EE&hK2wtAyYh!q4^~Y54%RI>?=WNBx!ujsg zbVIqnL>A%@bcfLMfC483zqb##{q*=BN$scK6}(M#sVJjMlO=?X2xEhDamQc>U*^rV ztgUD32?fdHbDZ<3%P^I^KBsMv(%qr=S`4aIg(|CiU95_h+*+otGTPRDDlJ)YmOGeI zYBo!tuQtWjLV4NCTen{FqrRVwOKquN$XnmQ|IPl<%yOhm%1T9X=ja44@1M?I;4vPR zzdyq$UVC^0GrW1PEnVIbTyguyX-|**p3zVU&jM$V>_n1ol}U7`S0Pp<5iw`2CjE7d z+#E;LIBX^AdX>SJpAX?`Gl2?tj=}7me@K^Tj#GJ0!g(Qj0wQNNiCsLY?a# zt-1bUV(h8!r6NJLY*2c)-Pgaydkvpn*%&iCN1iu(IKRWr`nHp2J{ z3k>wDEKoPzwf&S-b)( zC>Cdh7Krmbq8o-m0}gO@#CYb0y)l_BAS;^{NvfeO1`Nrcv5z}#6^aX|(39G~x`mUK zWE2>%bUg`cNZQTz#ycI*a2aUj>6jtRXmfN-is+Z-%m#04)lh0`jxcSt)|0pUXWQxQd_6khUADB;}j+9-vqrMK_;kp|Ad>u4lKqY*~ zfHP5k)0XCP)cvi((pdg)Jc<|+NQ^0gYlZ(vXbL~SxV%mEOO$?P)b7xu2P~@I+U1Uf~b(TtBW5yL0kms zC6Ec$`K7tKyX{n&{j{J#W32;kZ(XzE7)=~0(+53BkLw_y5yS{|a>q)qqF8&EO;Jdg zXfTgCIK})At8r^1OalXq0GS}aPFh_+u$Ajnpw9pV6}zws4~^}2>t2r^)0vfGBy*L z5>UgIrZhuFmiH-+clv<~e1v;d_#dr78?b03lS@0#>Rzx!u4az;k12?`J9AIUt4g{1 zJyE|N$aZZ=k%k5&>*!#-FIxVQg!#71L3En2gBUh2VaK$UC2%WN9b-mMU-Xu%t$ofa zoM(~qF`Fw#r6y^L#ZM9P$McQDZp)uf&vA4L^y$`z4*j700W6F_ZF9p+7z5S-4yo40 z?+`}X87k2RIVE7w&8v%n$gQiHDD1S(UD$*_Dc6A+SMY%xXKC@F3} zVO!o|R{H~qB@76(%fhE!A9#G~zen4~JmeqW=8We51o6yf%yC@X)uxgi!n+{X zE~|z$IpRY#-Zx<#(Tf+7*i=-G;5sN8B8gT+vYZFmt4@?@uS+uiHT*HT;rva|@oUKQ z;+IX3n+OrX!o+FvtGD#V8M}vonBqMWBj>L zrO4jxswHoDN-OgX5hUv*YvsxZld7Ri-nJK3vFN*+T~*hHm-P&4qcDRM}y%rJD8dh!qAGG zPH6j6?5^a+#YH;><}EDzxVGMa_0tKS`YKkaA!Vy$XkwsIq{mL1VzdiPx~ANOLPo&p zgGIajnak6@U2NLqu_S_X}c*=!q|E$04>vv zV8IEXXR1)xS~z!qVPQ#{G`DE#oWrG-zvI@hRFi}6NKbno=ozFuDdy@RSpTaJNBARm z^fd^9SPQ=VGI|Oq75u<`860&LOQ7<*VI_HXab6M z`w8x$yLDolxtz0zsu z2h#dazFI}<2M0F3>b@3Ek^$A>xa_N%j;XEMd{M<#l71_vb+Dm=N*LB&9{+w@F88jeY` zOPRkWK6C~9(Ii&@LSa;4UHu=Q<@uUDr>)^U=yv;K;{I&`)y(#^F>Vxfi!p(ZlYqS|!LluvKK6X!qm;DTMEJEPudX6K!4QiYGKc540 z=@w^)Q!d)EHNK;1?hl;tra(X4^k6RGjVDh@9z{^{;3*oEPC+`svq(mqC`R=n5ko{Y zAPgs(Ke4er&Gq?K3dQl8^-V4Q4{bQU47O2Pmytew!SmqCeN4rrO6Y}R<#-Xm1RHnp zKGjh}!6|6QC^Mh==|Hj!4Hb1=ga_4*^7kD@*id;7n;q>$?b?x?Y)7Bx>P(I37WuGc zwU^2kYKj~A+n~&qp?;c;KkPRuWp<_Apul|Gm*ICyW2vyc?|SWhSqjYcSur0p8`sEV zo2QK z-I+Y`?X8Q~;BV9^B6lqWaOt)FO?RjxZW9jrg)801f9UiHeB$zxe9~cA*^<^v{uY7x zh&}W{ICC}Z-_F=J5k9SutLE7rs zhseky0yp7zreHMxh)s{U=1+}A07NV^68@Rz!A&Z!5o#Wp3+8RN#Fw~>9<&M;;$Ba^ zOSqOg&p|`QNWv3EvQNKK_O)k+;>GwFx+glUI@rnVVb=G8efk5sB`Tf>! zDYTR>0tcROi+fO|Rc0T#b9bgCEoEyuuO1JH7uJ6EN;k9XoT8eS@iiB@0?C`I(ICE` zJ<0Lkg(2TLF>?ksvZu;gP5d+o^MbHK;oakTzZdvihz@4#p5R6PjNxl^_>7^|(a5n| zY*4dU4b`Jp(gHM1f_IG`3+6)Kw%QZnr*Fhge9=t|-9aAaX}575-)DnaueZJ}@`uKG z!h$%e22{KA+1I#DU;FJpzd(Ay+@RQK$^FPWK&w%D-f^~-Uciwet-|clqw&a1?8h5r zmFpfWVC84FA4yDZ9Qj{v-%ij`qL8}k#mHP}V@J`#{oG9GqTX^Tms!xCGS~IShIB2O zPWOk5KPvBbT)BXSr!w&$@HIBEukcxlhC%`?sKI)R;J^N!s|eDffb%EnM6HC++u?j5 znMj48H2tz!GK}}gw^KM}m|L}YRO<5UV-CJ=vTK}y7Z>Gh`3f5K8x$+-n+aiI2^2ee z%Xc@cND>MXh!W@Iia!JIb=7EICws~DTOe~x)pi5S~>|_m3b;LY-Rs;~=nLZ;HPTyvG zY)P;dsqoKQSrqn1&x8t|uQSxtE{A;G<{&c?J$&vYUmL-0W$~c_oseN$Xt%eay^?WwPw4_#lUZzkm!1~!=yq`>_ID*YP`FyF-~2rD>Z z0x@Zb-I@MTSKZcNc*B2fJ|Iz8(U~sko3u#9pJUu0Ql;(|&zGJ-Xt?*EUUhvYsAQ_W zern|Eor*izBD4s{cxr{S+W4CG%t8jk*if`i@W$(5S9{jqPli-P9{t1GZllQ{n(n@&Uw=s6H#Gp)t7M0pS4z>z*jm6rr z`zQl6c1U!je)kB^7qrl zpY+&SVpl+c+mpvSvxwxe?)USFi!Xgo^Jv)A$$lYf3nK5PKgdpSwngAAR;Oe-KN$s7SFet8 zv!h?X#KJJ$8@VB9!;V9~y&FMHYhp1- z7N8xF0rCNjh-)X`Z?+FVZ`163W;D0p?75#AyQ>3?D5?s5!m>Kvz=(uzyETaaS~%Pm z+t!2Dj~~Jw6s)4_6-}Bf;0x8#6H}xfz;`I+tBSkRIqb4}%Yg45+dg3l+@Ak&Y)=t0 zn^60`)%%JzMHa*MzeHwaq?0wt>TABMTV|M*RjL8o7>f-!;}U3v*&r%2ix~ndLsSE( z{cA7bQ6HWA;ILj3+`??s(e|_y*Q-yBEloMCgMz7j4-8#M%&P`T>?e^#4A~lq<)=HG zx(UE4yGH|Rb|T7HyC$@xT1~c_0`YKrAEo-OZ^EFb!qIk5c+(3KfAm$``H34+#|udb zH4IK&??EnPI9`SOmniV9|0M`G3mFdEiBKt2jVpPdrZ=?UAH&_C+MO^r+_P&$_6+N7qlyEB zVkp_Ts}HF}rCC_@d#0bX|44-0G*BXsG^L4B-Jj!wK{{|T!V_ob=VsMCMoDqmp{jD{ z%sGJGQEN$YHq=sgO2pdEuR%FN>b7C5;>Vr(=ZSYHcSxuB+AIf!ACj^iHIjMHCS+fn zA>ch94gHjwKmNYx#m<(Nx!h}&uy0x-wu(l=-s%5RmUoI;%j?%+#K?O!TQEIz2{pGv}ky_*WE-qCtIk{u-dLMhw7 zA*=y}>H5ctWE%7PG1$a?-ZUKA_b3kiekRu^yHjUuoFiT3wrQJyH0fPmpF_Gn-I-;9 zKdANJToJK*T}x}O!(BovZUMPuF-a)*lS=p#V{NM~FA}L3;JrH28nEzT;;4_Zlax&m z4&5?Oi+D3>CKP|eYeB_#w0Wj@d0rCFpOeH;yo47c?tC9?7w9(O4}od=aMR8-E27Rb z`L%zTEZ^S(SO8%SLRzt~to1Oel+u(^TU{0fzy}cSKtIhV5Uakf%$O>bSi{;)pYDPC zr~9Wweor6j2B(9VeY2*<<~Pzei9ArVljC9znXd~uc-eUf`uJ^DgT+2FV?Dc|09HtdYWw>8E^E28%|q9T?jS0Ry|a|Q3i*-4^y91)NwgA zd&l#F2){jDx|IwbT(d7m{74I4{=ONss!h=br6UI5V1a(m!lgy+!i|kF1M%fMlsya@ z+&QX%c&Ih9hS&fLjQU4H3VDLk(#Or$iAt>42d!84l307L@@yJz`TQkzHw`VA{hK(| zGP9WfJNuEp^uN#-nr`EFy{Gt;Q*nR6fApMPYzcBEZv}s`DS97c4bOZ^V#A7-x_seF z1GIEEf>nqezW#}*^Zw6?k;WP&7wiLq%DI2Ak<>tccr`}&Qh!_pPZZ94GPk*?{(qdl z+w$hm+JphMoO^{}>bqn%)aO@K4|!Ouudb>~D2R*NXGR>{5TgtV9}3arI__PiUv{>T z{Q3qn-@QEy){o*CZTt0>QVpO$lHbIP?L~8-Wcq+1Kt@rVEBdK*=II-BRD0j-zT(rD z;LV123IZ=&N}qhVwHz0AbA#SNfufMkrLqv}8(qS9!zI1W7oVv7FN?Nlc2pDih)-!i z7t2nnXul`!SS)-1ab+s^UV|k->;92MB3;}UQr1}`TIKR|@*Of|q6}@8G!UMiZPcMd zO-8eyoxf1I{onP8xR+yI)g!C%^NFsEdj@+iIikB68~)1gEVNFc`VWH8{TB}S>fpP} z5LwMwHK{{iKWE3~pK7g*@HRPv=0@RyZTRYf2O>Xm|tQ01xUMnEIlQ+n@6Gy1CR-d;!nGM~F zB6dLi-dW`;DLie8@zRzx3kGV;XSXiXTl15BF}+L0|LZ8I8Sk8liTkJ&u0{M7q_7^k zuI4vUl|o_8G;7?H`@L4!Y86+m*S9Hcmy;3#^(U~2KWkKPIeZzQRpU}4KnW#;0_fUI z2oYlr%~^OO97sFoT!=Y{n za-1{9gV*t>3jWQzg4l#c}OtcG-PUY%cHrk-}g_ zXCV4LBhl#yR0CgUK8}LL!+SE~5qzs9Q0Mkc(U%KTN}UTenEMS10}@X;bS@@{3+l!J zute&eyap}U>rT4o+s=y?>@F7|S_mZLNp6&y_by|60%MK4AE)o0m@Y_GLre5E|NAic zkosD2|6?}t^VFq1wr>InPkVjZ%X0A!M+DwOzwP_Aix7V!A-*%M)P7uBhsOyOsL2Y* zA-Zl!ciwo>OZ`>S$}3)v)yF6EY8|}D8e~j>-5C&V>^|RhY7|3XW(IkR2{$}ZDWR^` z{Aug<{#2;RHD8u!EP)u%i3XwF1^b~7hff<}=xrq)M)|0tOc-n}02p;`YVh-Zc za8+_8=}8k)Ob@k+f`nS=tO(5e5V3VQR=A-P^c93Q21LRcTd9govG6X?-LpkFB{<=T zd9C&^XO0=zm=iP!+C+P@E{OKTyyug5JuI4T+l)*XK5rP^96YLYtn)c~>qi2CM<0xly(O$w@?D26L z9n1XxZB4>b|B<+eeFfGE9=fi>zrrbe8tayyudBod^&|%IJ5m=HG;)_duDDccyLV9XePU_Um?{lRW8(|l(eT;KS6yr*Z*$-LI0{A+`-KgTI@!7=B2n(0cDS2t@PfNvWt0u2xwgx>#=ZN3%IWV^z5qK>^wW)}`S%{4f&#NKi`n zi>eK}FAKdF`Rj)U=QG=C-v+Il>gp5x{oYLkCG3_JJzcSR;zJ9T!j*v|KnFR`jgZw| zX%B*OmMUdlRjV?l+M(DDNKR*vl?Ylepl`KC75CsA19*XL%QOFLxFX*?9g*ewIhMTp z^+vpjZ0*(0kb&f9!$M8b{n>nbA?@#RDcI6=M2|BuWLzqXDFbHmCVch-V}pQtjZ@}GD^{eNPCr%?YL+d9y()KnH4SdG9wWrekB z-u(Y;Dgo_5^N0(p)~rrtmRSK)=f>KMt=e2obD&yaLD=Da3H55@0e^zaaGacw86Z8F z86f*($TW)9e#9KD zLRxg?o_%AG7Y>AWA}O)s7aqg|VxcTKiiuTi{=JPUumV-L^HRYp%?#=+!DIA zL&iY4|NDBQG3%TCS6!~|cDm(%Bz@bJBPj|V{w}$1&HWA)mB%DK%a9Itt zH1R?Y6Z;$eV`4lTzi&QPw4aT^EsA%|F9Qm#giakk6_XO$pa2cD{oL7mPxJSBG9RZX z*tzhh27F8VbqPzM;!`;IWDV1Bt*fA$^crm|r~X`a99_C4O#&-1B%ULMdPVPksH$^) z&>YSGP_}PdF=R@%;<9V9wuYRP$6j<#e3mHQG-EF7@Mt}{@{EgPoM|KNmZ(`0ehF_| z0<^*2`CRTA4>y&kC^uk@6mvd}T~Um3*X%S|Rh73we^A5fT63~uQN(3BXL!u_IBx;^H{_&Z2game%HsmLlR#UUfm8fpog z-@kZUkKG}%rxC%=rzCGm-`}KUQhbiCSr3N)02_9| zKTVybAAG56NH8B@HjfkL-?pv!+WKF_rU#uBC=K=a#4Sj1XXFU>Z*t8IQNC%z zX4%pSN@wik0uyBdW2=1}!tn}yG6oGcHm^N-tb@@U>7+1E*beA-+^T~L`CKWtEc;?Y zD%S4iu##ZoG3qj?9CU4mLGI9;zI#aYkAzv-%uBt7$)DUJ49L9icUIn+&Q%FSwZRV`U*AQcp6{P`NXL*`M=r;(iLC~tcRgI5tC+fvFa@`Rg`)ItN zJbbsnlbpWf@zw1wOpo7xA>kB4v7y+?v4lGir+_T5hGKt znl!^>EA*whk2>)_qeXa78J+U<&%9X&WUYHYhz1*j$M<7{F!57v`6cJAi0 zck+Lc_ZcsO&LCZ&pP*P?cpoqUNkw$^rsxIUS7bzAT43`WJ^j&_U4%!uwlfeNu4-1X zyL{j4)bDh2Ncz!L{aKOvM`CEI8?WAOBnlnIHJrRLEY(Qf&Z@eK{t-M01VBU!bk-46 zxYwBAjKbx|rm?0v^!qFqCr_8NOdcbc?}lFy#}k>+*u@LQ;tC?%3myQ!FxNaB)@w%*Ep+e6_9~GI~^cb21 zN@&;relrop%kWF@zpJe<3h`fE4S7*Rp6|o|n^|!tqFwdv--0rBbjK>IgAZCSpj*XQ zC2z@)hB!;F#hS6efIn;kj~65PisWwQ58nE;i=iu8*2?{K(a7jL>CB2GA5R;oTfYED zsj-MxW3HrP{>OtqY6Y!}fQ4aPoVQ|2J5m=9}fG=I(cu%Wnm&qKg0y zb2F2Kvvzj0kAAHN{D2h%P3K(9Xw%Ct!`$ zH)uo;B3k)28r}nEG+wlDRKES^9KdIsaV#L->CWFWBChq=V1dj_EM2h-exACw1r9g` zwU|Q9p-`0|I;|Z~S(b+HN4k$YBh09LGNHhe^8M$2nvUYy8GZjx6Xz zO4>;5)=xbXel(S#mb|f>@>np*a5%2kllLfTa|H`0Uf3?!2@Hrp)w>483RE<#=iHs@ zwjd|;vow#k^)5O+zsH~>K_?*?XNt)90695o3nE4Du_)c`O`JM%LOJmh^ zUUf}lyR&9GKe!;~Q%!=c3N0+IlIG6VBT5_4D&FeD~edh zjn&)WlwNMmTsikOba0LT_dWTqIdz>?nxzWGqRN4x@tgwoFv$C1p2X7cog&X;OAV+O zYF%I7i}VpGAH_ppL|VlLzOb{_f3W)lr-DZG!6Jwx6GQDWcW0hS8LLEBr3q2Lw6bKO zu9!I5a~!SPdy7|&Tk+jMxKvQy%?D_wF47tl10rwryOG0j;WN+R)L3s*_{YZI6%6+z zs9cUWD-*^w|GYAd8qHa*DKvMz%;33OaV)R~yuHbvZ~LPu%S*jd-D-Dw`9tN&J385R&&oo!<=w7yMhEu402ls| z$Q9}c3$L}y*eA==K+ktuGJewZb2S~tog;EGtM>ax8e@__cTjcob0!1?=np&cj|JH0 z0ujG`nbX6ZZa4K?q!WT(mX_8jzwJ7bXPCe`p~H69ndZ^ZtWb2{RO@_2Z#9xE9fv_WbSo zsD@^|mT})MF;Txo6x)3;N-)1?<_4QcCnD*r7Pm07U(U58mVaPIhxZsQ_|ggEl39MP zQJWH5Die)1?atV3?9X*12TmOuf>N^YHjt62NAI1MO{o-FTdP@#OlV@A#A47%r?*L2XvU9{@Wwfh1;*?}xbyR~Ig8RJH_?FV^o| zDfaM$vTl-iFx`qdeQwtI=#zWc&tlvwhX&<`Xx*kN$Cc+)ViFAsY7}9|AybGQ(DL|! z@R}%S9dVGeCPs>lOZ_8S8)et}F+2K5HFqy?lXbgkl;eUFpLUk>Vd`UK*UaRgGw(>D zcdPp=HWo7P2$IuT=8IMqS4vU`GJBCC44%RXyQIyR^EWWjK=t3$3EAYsxGR?A*1&-E z!Ts~IOT>`aVo`UI24=%aVOSLZLjy#d*yzi-W+NPO90o#on~(`uQgQAGhQWVA7;n75 z;yysKc`%HM@KrqeWT`Ui2*r(WHau;A3HsLDbW`a0b|^)4L%Z;hc}mi$G$+mj+A1IC zdtT-(mKMP_luJrKrUN0QPVRrBv3*Xn#g^~8o2=At(&HJq^z5d&!ApE9w`c`v+wEL+ z<@RL$zwL;XO*VJK&mV4AllJLtN}zs+4IuUnFDNj>kdOET$USI<=0)-L6vvzPq%Rx= zHJ_^BJb}eKadDh?3EK4Y+H;u8rsMv1m&d)q*U-)f1ir$WwSOe+5XRO-|4goHXM^{E z_4?^f<4D;}^S2Kbv+t0G#9W*G@J%rv&l&l%J`(&E=ZtY4%;hA6(!DbYbcp>>_!Z zi1ulYM+CFrb9abLW%S0>Ih5{QB{-*i)1EN$DUbsu?a0k{gH4!C{t(NpDGyt-A%4bg z5EITG3tLBqwUdMjAG-H8r?$h27RPp(o|`S#&rPaxN(gas_5K$}+9^wMcDXT&qh}@D zrADhP92@;1`Y$-uFTBl8n@wwHX_>6Eac3fLowWJ7*2d7s>dh}*Ej=my&E*%KFS6?V z$pF+24dn7pUuaf-)Vx1R{DPh7~l3SldI^tVBT` zavcmctH4plc}>!j=7UUbl}bGx)%+>)B5%o@N504;1f}ON1`Zy3(dzrrZKR~q}gDjG_8LUAb-!?F&^G8;iH;yu5jjgW!Kb zUBp7<>3TuY3l`Bu5CEDBXTdPxBFRC`#nJ7X*|vH6;H_(6Y;>k`e;w~@`7H*zM#Ilp z?Qr@Gp;|kw{*{veQz&SvYVE`Ns*OdCnv`98W_^l9POyE)R5wfBj}=FQ6CvvKqBw?m zk|A~(&f6MCaws`2*;l#=vuR-0g`OEGH2{|aw(mh?r%K+ta zD_1fP>L^WsGz)k^Er+d_mt?&vj%Z8bTSfir&%r>_rw%%5ijTQ3$-OAAgPE^C-Y7vk ziP(o5XrXj%8eXf~<^Gkb9BU$LmpuESl1C3jZzNu|gzR!utSvK%SD2cZ^L?1MceJc-&6Tjph>BQGOzF~)=z$EW zsjJdZk1CxZ54FCr?2OCFH8(4N6W-eEiZP(mi+xM3sRo~v_ zVF~hzm{!X^f0wIYP%;G>XSE^bXKb3v4_O6X?57Z8)wI6XwR8lzHo zZ~LbmOJt#A``fHhwk(jp^^I1S#mIBcm<{7hz5h0Nowtv_0yx?qL)iZS?Vw?BnmYSQ zMJ1Gb9Ps{OT`aYJl<4Sx+`MhcD;dLt}i=)!e8O^&2 z*%z)I5&bVr1<}2ML^sa(b|HKgK^&`tLUuPEsI;u@V||3l+rIA9OLV{XsXTq)vavOOqY5_D66MlP;)L_b;9WS`l`5&L!awszJGq7G*6S2T&fX#CE zyMgSRJj^^sxh08p5lw7MIikr67{`eK#3v)h(Fn1s`;%A6-%iOw>O=1n^oSjg1YYd_ z{elkuksQ<5JMfEMgoS@H_$>AIs`Ei;LALmtnf2wY` zY-StpW^33Guix>wtN=lpZOQrUjD}7z!8uD3MQ#!MBi|NxL^y@OLkS2IsVybLH)ZX| zeR#a4cWWFQPX}ECcbMYE{-Lg9?9*+a_+Kv%IYpb@edAp348;)!R!+uQzxSEWsq9O4 zRNdcs=Yok7CzMJBg05jN^{TuwHf`i^#92cRGc%cN9xqWE?4Nq>$NZ}39B`=`|2Q=p z({!J{i}_V8E~`E6H51CZmA5s{ zl>!2<6Z-1Qb5e)B)KGjB@cw$?CqpQe)TU^SNFnvVdYklk6nv-+(dD~;?}zkQ>9>2U zq{skFyt25bFW=Y^7{wWAGua+KA$_Gz9lw-)&KW@Ga%!YAvLKvytxl}X_t9<3{e7aZ z`|fwP+;C{wGTc^EZM2kSJ2SJLJqCvQ#Qw^#P_>2!lA(xiTNez5c8cR}ITDMg&{=|F zQ{1rU2KDF!3mecr+~0XT&rF+PTc-(m&5{JQ+o={vEW9@x{Fbj*u z$UA$hs`Z(>QGmxuRZRXnaYxn^5W@ozTE4g7G!FH(o0u!JnUb9?)#C7oG$||awgG3# zwY^-q9(efB?d70|_MPC=RI;J(&n!8r26y*+9s50)+$~fsRJ=UT4lS6Er;mXDrcW~L zpN3J$$qwwCAf983*V7@6Xd)+viBp_3Rd}Njzv2{E%;n`JJY{5)e7lM$Z;(p!ux1D? zqtk|)5Nx}&x-?YJxOq8$JHkidaW1)iC)?Adc3$1T9!~vo3;u2h8x90x!B&GJsw3J| z#QAK&#K=z6?yOT`bNoEr@QfmyLv2KV1Khdt{bx^+CT z7k~lP+p+zcF31G(k3MeH%71_wjj)I5X7~NZwRjJ6+S1Ag+|14aD(U)Sb-t|D!M;Ka zCC8l$oT}Bo?=w_hLE<%?UM+o||6GadfB0Hlc90LHHmg%7uEltjAp#;fCb3~3IR5x1 zWwl#51|yad+(Ol{Aw3{Vnte*ttGtXT9_Am*xk$$9!i?fQdF67~GDkxO zlV#(9>Rzc<7*kR+eny?wHi?ZpuB=Rf9^?Ub?*`T*4oT5sy#S`#kPRdwn6W#pIXJ0o zd9-}h%t+OzRGrDdx7yTv?@`5r^{wbv{0v3Mtig9YFPfC4RJaF)TZ&GV6%>cP7cBXcC zBt==r-&_+n?p@SNW~i=I#{0-I>3#B~UR?7gZ%QYG0c(8YPMBanXW1mD0k9EVh7&~4=d&xrah?c4Zj}5kZx{mu3k^+Ok)So z%@-wQCCh?ALGDQL9YF0$1IE5*l@;e)0Wn0EDU)If^Cc%O99S|ve{WQ_=1wR!Zd6GC z=l#MsZ{9_U32P<-V28)V`>$&sMC^#JBwmC*I5&I-U*_q$;TJ{563xI8hl>%(HszzP zNosYGr!P(>C*37mB~*FKLQ>P*hp>cOK1fz)?#F-JT6GY6tPfJpF~$PTZMlJ2(a~>p zPc%J_pV#;5bK9`!=4s#l%AK(eSYSi}LKWp?LUHUUApPHK{oz5rx!vZKA{(diXZU@o zy1HrIZ;8p~^>%}g8W^;|>5A*Wv$Fl1h+50r+M@W88#4>z!#uWf(JR2;L84m$(-h9? zMu{-a0C|q~Z6j7luoG;z8iuSv-b_sK;^NuLo-g4Y<_o(~pXO~g=7*^v@8R2|gu6<` zSOCfp$3SeEIpinYMkB*pwF)7I7{L%xTl82Ocj^NNdDr&5i$Iw-g5db_hmfYR&2h49 z0@)%Y2#d%U2wkv`mHJEZ)vqw2%K1UKW?{5$e!P-RlYTWhRa~t5W2Q%xa~iWbdm#E& z(_*jz;Le^&eZF$MyT2&TmtkdD(;@Bo6Js}4={%{I(%TAIN^E01AHV)c z1GP0dUrM&Cot&(&T`+15-2~t57yPAhD7PYwTAeDg$j{s{&c1KkDfd^W(7V4vVS2?0 z$wANs?@uZEl+f|`Sc1qrQ}@pi(WM_V;GUEYCV@FInmHW|9i zxZLip>VKCRHu5kmsX;L0d`$NI@SWju99s5u$ z;t0%6PrdJVcz}tTU*+?+0`5(hFZk5k(Zom&HR1ahA<1pJp#_Orl6ke%~T zZh#B#eOA1dXes@BZj4gV^RU+-Qub9?6X3V~T;`w9IrX}Z`H%$oGayJ~(?Qi{J85M<8)?GyDvL5J__dC?z>fAGoN|19zh(=* zw=+SS_icnjr|bun*QNG~oS*Svto;oH$A@_|j^oQ!PHp8Vj-XGMdfQ`{AYHOl_*Z-5 zg{~363N+50W{>XgyVTWM8`aRE(a9f-g3R1=>vKsT>S;=T2I4so`JSD7F96mpMu+pL z!=!yBut;Y-!eXR<-ivmYI{oJDDbaJwOM*u3X-7yMDYs|8lEY6{z5v%Yx+B1ap3 z2;dj?TC_%>jW}~#Z_8wbeBo|VC(TwAUz~OOYyum*hCHNcXK^a?1QuaIIjPK!WqpgL zh$Qp^^ z-ixp;gK%jlO^K7Bn+HWKsBC#mZhu~>r{qtW+xhNn{rfRn22#L(e@+GUgxFQ7$0%H8 zw1!lBetNcWRP7(ew2mc{R<+nGhX>p|$oFCRYTd}j$(;{(#~`-;KEHnQ(`FN~Fuq>P zErIoUim>D0XcLo2R<{04^jRZq`Z$F_bP<`N-4zH;!Qssl5ijUghT_hgJsPnaaq=4^ zytwpZkh4TT!ZQ&^4~hiTQFI9-zP3MY(i{2qTqc8xC~MMx$WP1ZLWM>HBBx0B^)(+-li&bgN}Qp{iTzW_xuy3Dvlw_msjQVGZ7 zk(#xu;>pI7Wf#xGtBzEM?ZV!L{Lv!}mG$fh?dUQ1*Xb%(KRJ?XMt+O` z0Kqu_0BE~!gC8AW@Lr{UZ9FyOaR!~JNhm9CZ+^SJ!*WRnZstE{ke|FBFh~hswEqCL z@4(A{kDm-~JUSLc)%2b7SxBn8$pbRNH+E)F%gk(Ibs4We@uORR zWk|CyLct2gNzVtk?T*#@@%wmw&o@(DP4Tb6HsULJ-Hqx;g^eX+@{pis_pOpTjpT!X z)%dZj-`rd@iFC&&20~6*i+>0lWAW+Uy!wB22_%9Fq6bk!ent7e&mPrm>}9xF#|x4%oDwnUdQ-{D9l=J$Ip>__sg!-EZ{EPcKbXx-NO?BJ(S1i! zIXx;Qy97~aI!X*|x!co|!992Ubx(_N?AI9F}F{o^w|BM7xoj0AQSd zkFlj047Q<~Ln3jU=Z>EL0M@J|hZ}Z|gp6kxJ;gu_jq@txoOK)zU&@g5`Iv!{G6zoh zsbOO3yB-M}I1Ss8=~g2Qeq-|xc^==7T+}Kyji)?v+p+ILBMY9SIOH%sqt~@# z%*wTyEKxekg#-h};74)SuW#jD-hp5gEy_oo{{SHG_4;(rHJ7C6pKEbE$Qc!e2d_MU zPpx_mp9+LTgoH*MXFT`*wVG*`pmbKOo=5vbKR3V7^!F9?pTqwE2YByG(vQR+h8JJk z1MD)%acK%EmK9f6zUg zY$N-6?1OZcz~oI319)h_`A!I6$Gv|>p9uc|Wvgvp_EGTGgWyM#RPhb<-LHkTh^^#| zO?Rlv5t3`C^OzsA!xBF7zjd$)3Jq}M8uo2IrqmPW(Ef=0AL1=1#hO$)*M@FZ_R4Ui zOCQWI!zwuFaoCFQ;`>h|^T7w#BED?+JNq_k9|LaDblpyIrzN`ENn?2vMRyF!7dzJ_ z8E_6ANe$T7(#p@baFBtJF^|(V`R*b%Z8PW+>S@68LcFid*BHSyapdyYhf+%a0G?|+ zOR_Xpa0&0ueX7h;i38=yPhNzY?NrGGC*C-g&MINrdH8yLav2hzTF{iA*o+Wb=Z ze?7gdWa<_O(%Wnx83sON`g#o4zD&3H3RH2J;oT9OoDn z=;125Q&UGCG92{WS^U%ZheW&4uBNhNXl8|u(T+g}mBAgq#=PBaR?Et~zaDBnOKbp) zgPa8?t$wzC+26DD*5*%&ULHatns48vYlVtN$0ym(w^Q$5m6KT5i`Ud=$|i8-22Ob; zfc^pQbCS~aQT%;;?!K;$eMe)fSZWixMs-Xsl`@P8ch|R zo{#6oNNgN~laq{kbQSazka#B_vKk+aejogG_{y%=tT9<_NIknFV$M%aSaKm9-o=H4s0FT$}Um3d?!HPk! zu1f=uS-K35K~ox~Sse2R*g-hK>zwB&jy=25F_`?U06w|v?^?esi@R~!FgW-2_Nr6D z!4-y78~}O1&+^abTE=PW#bi_=MoQ$9mdW%VjVmjc`A*@Uo}XHc-7*O{ZL^xYY?sHC051B{%5*RMQMf=UA#f_cI1`BOPhKA+CW7ka{cV_pT?V=@?;!f@Gx`7=}YpW5XS-Y z$?8b%5935^2@l~Lb8w`BIURA*oLEMnAtR5Qo|&l24dn^s@%};2N|j^W2`n2K>Bl&! zaDM@>7fwl1Unh}}27Q0}^yFm-0XQcI_2&oq z)N=_U(N_!s$0r%jLD!D?q9V@QLB`&=Jv~4A^;M+u_irGu$@+80C%suk4<62|k_r7f z`%x!hlf=6|P6@#rbU%h_bV#K6S0{}1?hivv5j~Wm!W5EX*`M#CWX!=dguRHD7i5^*)kQGAw#E!jx9%`+Ink7*4 z5*In>e)qR*`ewT8VG>!JbYZiTjBrWgKV0!#^LpH?YpJDbVvCg+3RDankIuUNBI8T8 z)GW`4jFD-wT}2(sz%w9&crpn7U%nSC2UCH?V`=tQ*LtO;tn#EQJn%&FF#}>tBF0>f z;X`gCt_K{~)HYgd9}9e2cko~0#l5Wl9MrXVQS}Jbi9|*)3z#2}xZZ|ClF@*3*EO1Y z=vlv~j}m+XzJmKp)DMcj9%{PWlFTDeE$##Z?97rD&L#34Mo!gtUBOnh>^vbAgcctX z{{UyJ)`VNdeRle3Wj8RSWW_GkIT9gB7YcINJRSxyG)s+h;NGjJL#;@BN#Kn};^KCU z5FopaqkA`z18(x%?N$RIkf4sa8W(y*-wiK(G4T)Kozlq;yAyd6j>NzWYD z??A1b^BVjd@Rot%pAKHO zv38Qls7tx7)WmZVyJey*+;3x?n0zjuG&nIEyghrekLh&Epw{6_?^_)Eg~LlDlG z7rKqP1tL;L9w;B?l&>4qMtKe^VEvF(*vaFULh>HP<9rD(*fpWa+!)MKF)^B9@A zJF~hGQC3EzWXK;LuoN?Z< zy^25o*Yc%_K{9L@8Tm=bIpeQityCzB7TjPk!Rge|yJ5nRi`%|Ee_Ck7kp5XanBWDEzEm&lHlW~9Y3X7h9}5bFbfQN=B5cVs3I_=U;qyX z{A;O4QyIxEjGO%u%UH3N$5DxAf^=kP*aEDr*yq1rr>%Y${?&i8cA@Zt#d2KfalHC1 z`Dcn{8ATt(6E`?3+dW4-^IyGC+eqXOyrZx61L;}5EBJq)`2PUIcU~6pRiK{EblO1! za+A@QJsD3R*SVAC62sKG*!le10~)dOKa_o18;h5Y%}TT&Wexyg*o^QEbL$|tk~>RS zWsc@IIb|SqKQKT2Zfos7+FSN&@n^t45VeM_6HlYw5^V0U3P_;iV`J{P7|8d?^DNkoNdky zeODmY&A%4D4`_PBORVWY#W+0|lk{MF0nTgXoj+Wj-uL@vOM`8D8UqZm0lRNuj)y({ zYv`W|d}>`uBag+%wrwirIkCDoE9=}7-#k#8S`%$GK3~?fZEM4C_FYyzs58?Ca5%|U z$3y(1GAeXy00Sn>f*bCcij$4dFNLYy%YXCt%$a7uCh`cM}9}V2K zw}~x`CwAw_4x|tnesm>BAmnq?t`7sBXbkKgRt$F*a7FB|w*81?H;juv^0Q2-2s89W{;VHgR(A8@$ncpM(}JeFffN4c2C z<(9w>SONX)V9l5f0h$`1&p4crXa;gab`kqHb6t1#r?dUpM5skPHB?VwMzJIg-- zhXF%pj2`)=NeY1o0yScNNgmxXTCqzBiKfWf6y)G@jxaqx4wU50Ag*14GTC5H_sAS) z9Y7rC2eo<^fqXXJF7Z~K;fra~IkgGW+(_r-Mr`fRxg#G_R=gqLi>+$&TGASHw7k)5 zX1f;mKf97iV)Dws!N4e3NC@xK*1dzmkxk<-2CkcLr&&R(_!iZk7jK!b#qH}In+XGb zu))qrJYyV+&P>--Qt)PtW32hV0sLcaZKqz#sYyHCVO#cypF zi2ONYW2Z$JC(YC%SCk$&9%2GO^(5r?A4Gf#_%Y+(+pbu?6nr>XSI0U`7BR&0BQ3gV z$Rvg4ydZ8-8Blq_Y!ps&j2x0qQe{CMkL;2AGyGoozww$M*+T0}n^UsX^!t~V>58?k zmu)j7@#+rhenGqhSo6L|a;P?|vi|^If3vsz6Myzr{hhomZJ_u&!m(aorHfe2s^9+r zq+ZG;!%vAHK2VXsVzGq-01g1IpY}ril{_o^EBq|8@HUBb`nId&Lb{%@I)$G4Sdc1~ z3NVqN$c{0>ufA*R*aVBTCeU%lNx>3 z%_mn3qm$}84l!33?J{Mv)7!5+{VOqU$-o5Tk8#akidT6C**Nq+pA{0bG*3f91F?uw z0VH%C4l711#-K<@B$LqKeJYAwCeQ?#+%Ur(DtRtu2W(G}qi;_1r3RX@NB_|9lNPSh zmqkZla>Ff>G1zp-9qQ~!G(an+Gt{Zc1oNMIxgxMRm54q0&Pe`sdOKNsy@iS%7+~|9 z_x}LvSMy4TWB2LJBRNZ^7c5wHIO+a1Y6u!68=bNIA(tmU-_o!BorW;LHUR)x>mW#s)_RjU8SG={J zTUCbAa$zl2yXS%~8+Jh3 zjtL!(DJL$*OAR%p%Pu5B02_ul0Co1L8_K(oT3E*_xf^5-+eSu4Kp(DZtY+?Z-W~CN zsi#3TwwV4+kdw_8^O4B|7+1zX?iZ)yUA@1HWVp9UrzRsP$cjUSIO~tkrFeD2tg@n9 zBE#gJl1N*V^}!>KgB3eXeC9hflkHaU9yYH~IV28G*EMhwJz{yHo)(T3+O7`N02Lq~ z?vspq*E_1(>60emXsV!w&9fN#40Ji*`d1h=?*(wyETl4cJy zLm1jwc;nRPr!`OlOPwm#c^Pf48r(igtdWt>@VkK{@u+{{7}Ty}VzWajIOxOpPad6W z*Y=RPPnE$OWMkjd_o)Ia%&bC^0s3dqVw;atOIO&*m&3aHH< zk)Z2#(-)QoLOS~bFhOpa^c8X+3u=B@oz)?VBn!NdyMttH!Touy7GE(o zmSUugf=>s&Yd(870LoJ;#~(I(bSFQhH|jrT%TZ}sJaIIamu~EY2;)ErVf{ z@!V;)f!4y=vi|@s=?(}7+mWBfvkv&%oGXqpPbc#4PFbx+5@`uJ<8M5DPfS)#^b?7p zadjl8=6{g?01EKA>(AHu)tgwJVS&IT`giVrp4C#@%e$6A415IhFacwLc{%I==DiV) zk0*rm`|T3iL3srC5#LWDGe+iF2iZcu-2VVpt+_`zIXK59kd%9pcw51G=Dl@wX=}A4 zvbCD_RhMvYDgYURt~WCrj0|)1uBt6B!`g?#)YY_aKl^sV=6NsK(6mw5uvLNck1P){ zj(>=p1I27>w^BEc^uLI{CXroyM7FxM;#oT@EE8>tNR;RA`7q$G1EBRax#9fyAL2y* z9Pt(1#)aYE6NESWq7uLMO!7%_Y6<|ua^XiDfyq9o)oxz#POm<_b)$S|^DN}mE^kfF zscRTuEoZX2i7kw(3HfeTAlWA*e4`_$VXHf6o+;2iGw5c@X|-#Ss@_`L67gBx{jKC^ zC11R%`1wiu+~5kq_;C=j@kP(W9}!$dWv1)xY%b=S6TB_InR9CK@B5pbmjsT7*jKvz z6!>|pKAn5u?-AQYdltJrszqY}KWLifDH&oSRU>FD;Z*(Oka!iGwj7^B=wI1S_B{C6 z`$>Fb&~@+G^=)k|Zal3^S=1y}YaJ?MEQUy#cPq?rF%(L7F(j5%=D)HJ*+=$H_(A(4 zcoKgH{3+AY8MQlud8%qMF6+DdrT}l6PEOPxEOC#PGyzm#RDZH(zR=j4{YJ#joWOv8o?mJh9 zKQphJv8@!t0X{?Tf-2-L$jTK|@_x9iq!v-A8yk#dWah5s$S5&~Q;Zy*pX63;m*!|8 z^3*9s7(dtgRlVoU07e+MTpr)jvs3IR0yiL&#(Lybiq@b2vof4=ILFg9HnX_m&1j^L zVM7ojsQOdVM3j@WrZ5J2_2#Msh=8jxUIsV^@u|#EqkNKw&)wtm{V3&5k z-skPLF$lPm&*k}Sna}%O!SwxWM&441ot*9m<~>-RX}@5$NWl&mjDkS*tM=MtOvmQP z!5zOk>xDgTa8<65#CCQLvAU6y_q{qAvThkzy2RZ-ygQ%HpB<&SVYXeaPh97(L5x$p zi$cu7j&L$EJ9~bW*BIz|lB!&{yIA(gvG-*1amfDwAFY2b-?jI{OK*kWAN*C}YXo>K zSE(S4Q)B0Pp5EmeK8R&g;*Xv)0U+`7m1Zp}r#Xk%D zKz8%3HGM6tIgEi6wl2~lnFj>QvoTO{jfWY@$JKE3xoX?F;O131qR+_tuPq657(00b zrv{;0n}lu9@zWXi?a9SmyAjHO6&dI_>4VAa4P-b|9@kOtlh0l__OH4=ea%?c7dFzk zS;DK}=0qhr{{Sy)qdlZi!#A3ZGdIkP9I0P(*FN=7N*UQ>!Nx!%>x^cS8K#70Ckiq+ zZ*F=XywzI!3QZBBzMX6uDI$M7C}eS$Rz3Fg+vrV27#6nPT!u)lHw>POf_dkt$mXT< zBD*1O_Ng2KKTOoxgficiWt0^~!sPTF2pIh-#cC$GUWYjN54$<%u6Q`(>NuyB3lUyR za7WX)#V?UGa{lvyz}#{{_5A8>$q^V(eR%KR+od~LmaIP6LgkPizn|gU_7$^Y5=p*p z&G&il>x>?ihO=WS*OAvF@)fTH8yo)7>CQ?R0C0wYa>wxMgV$>0^DWg;h{uXJvUEi2Fb)n^O$HlN2Adm+Vn@EOxq= z{1flT9%eSYcF^haIO$!Rl`S)AE6mJAI~N0J-bN+goBVXpHE)jjybRE zAN~tH`w#xd-v)jUYd$^r72xY%3M>%mTAivbtQMCsT;05A*0YGdMwj=k6JvMH%AE6G z$-Uag=DUDMCvH#I*XjDvbX$JukXZl&oD#L!;0%!CX&Ua8@~5M6jsN8TzrB^MlaV>W{D+sQ2&xhA9Z>QVFx+T!Pp8QBW$;H`QXyGUa zAqXwk1FdXLZwHBdFQp{UJi4rJJQK-2TNdL2*dr2f6*mG8ew6KOsAXH!g zUzK?Pk=Gf=HR*a*8B#I;I#AuM&8R{t_K{q?cwGB6$@;lCdY2 zxgCzx10uh0Kj4y|vZsl@D11Vb<5Nd(29@CnRNGB=6H64=>1=s!|_@7JgPlj!p?^M>Vp|iD%8*?PC0*3Te<(%`i6rR=n)&9-j0DKesKl~)o zei?Xe<;{d3-A2{8QeXij_031p<_UTs6nF7h?ol5Kl?5?K+@gB9uD0eqb#8GMg01yFf?P{Qr zhTEJT{lTl>Vfcv~oXcY{=r_d4pTs>$7MpW&0^92sN;;2{7VFzPMOc$V@dGcN7l@|= zwqStc+qP;|GL-bOGQ;Dc5LSZ4y)yCx{b|bwjL+^`&e6_taWk)9Pn3gETWQ`Z+)8U; zyL8Q}bkDQZ_-uS?80T8Ikf+OuEZgzvFsM}7QIZ`6&xzJg^vyK}IV_U`Gx(^j2f4h9 z<$DPkhxb_s^s4sIc*-{B{>hse{{W9^SD$~KyHt`79|MyvnCBycvna=}Q$nL{NtDn3 z()@+D{{Vu4c&!wDv%+!7CVDLDxKJ=iBw+K~jybFFf5AcZeq@uu(v<`*<(WA-_c`EV zzc_C-QmE6&bN9B4WbMcVkUDzQ5$lu2OsOagND6V+k51hykNr)-e<|eC<4j*!AE*K#xdwE#Z29RC1J`&U5+{1iXK&k{^LFQ@|Q*<7Ij{Xx$?tMX`gu6U>O zZP`OE6qXzj(tKu#xm_L?<8e$f+Ydk;iX-EAlEY7K?a}Kw&0I5>7Bj z1o!5(E&O+DXn{5#FpL7MFmgXS*ZoPr?vwk>*BD~^BlXRH;GmxegduKhbvVE$8(}+- z8OKZ<`+Y0t@7mk;nD`&@+xC3c`~hthrLaPhg~jf$NOp-nq$Q zR!pO0ZR01C?~i)noNVmRrKM8wGlC7=l0fOx@#pLHrB&G?vl2q!`}6$j+ZH(ieq8$g zKo8cS&f?otXCtURk6I+AVbf_sISg5qvN<--s*wmmv}55l5&?VZodv@jzn zoO*CNb)+cq;7ATScMFl%txF5D5Mph;iT3SRYk&(YAPA9|9OKjsbo?t?(iVZyqL=0e zK8J&lc<3@Xs$eeKX(hMs@L8HYcI? z=k2Zk00kKRt^WXTDYW~4+7HB5HyUo1#!GEGO0bVkvJ+?hbdjUV^GKlK3&>S5kfDa^ z{Q5RaI=7iF?%7P9KD=b~`qiH?Tjg#tIRN~}J$UU-+>C{Z0|T+^_4N8wsHA7k`k7Jb zFkDQCfutZ{;|tTC^`&iN3byo*X2Fk}mOiBVlloM##iNuZj=rT&10$23^vjqf5QL1b z-?|9Ker~@10G(=SFhgt>6#KdBj&cSu#XD#vEl%di-P_EQ13da1?|eQU;&q9} zW9O;Q&5pn499Nja{#qtHcw75)ctXq`!Duu_)T;1Lt2*SP*k_mbn%&`kOxL` zK3GWOC5A~D#xe=!yYl?9t}3dfMP0LtG0kY{on9U>9P$DV7_mbNya(!@Ay^Wr38^gP=XgA zW0A=9`q%Ser+(aDwhRa^8^sn5gnYTSa9DIbCF|&MTO;=R{jxNZ9Eq#xcMTcfybrXV zMjciA@thHZ&3QF^Ak5y$KcD;q(WT<9TWw_5$o`Fmim4H_V;w&4eweE8e{JhaK|Fuhb2~5}az^Xl>HNLxM%(@hVf$`chGTEx_EiHUiGFT=V~wW+ z+x4y)_)D2BITzk`L&Z$3rTfpppU}K^F(@zPZD29?Km(tpT1zu%fr3c34V6mx&!O#mrut0l~zKe5bb2mFf7 z_*I#u{6EDV5%D`LfAaJ2KYdoh*+=@k5;N1iS&vUlV`1)leFc6D5BMt=?Lz~)TzD5q zom7p@9n*q+aq9!~B8e>$JZ~o>rZd6!uf)wi{tEv9@jhr8d*6m62+u0F z5M`G<5KHv~uTNoHu>SzTVs%(zFRXkoyBIrebt4|5>E5VGug2~mFi9IZARnmfpM2y~^_c8!bv44a6#*en zsptT!GesO)jBVv@VgTCNJaov-KkXTre`C?zqG1Zj3K`}xgMe~AY>qkG>rh`Ry{Gn) zv1@htIKbP1>71XbrG{}G;nZDOmv+Y6kOmJp_2;c=%Y7c54a8Q+vZJXgG8c?`WAdl< z`Rr)&s!Ky27nH{t-{u*P6b{7n2N}SuonGc`HZL;bHUU@{+yTJj)4%kthe7b>sU4ht zBbbpCB;`E`9dY>cS`H@EH2G$=kIjupZblaau4w+zmd0-?r)wTsd|_o0$+?+|^vd)n zpZ>mUB2O7sO?Y zSaFYEPjAP)S_rYQ1gRwb;4y>O z9{H+p^Aj|q7Kfek43m~nInOcm)eeN6Ax%@w+L}RU)l$+{o3yXms1_tH%Fr%qF{XYtTGrK9v z4s(;&Bc?|~ilZd)$GPM@j!zvyJbpvck@XaX50;0o1mg#v>zXApPKqE_FEI#R#2ybm zybpeVooQJVc-dGIJGXof=zVJn&f#wqyg;Z9GEYIqJ9}4cqFMRQxC_eeY!mX2UrsyK zLELugb$$@i-&xe6wur2I*%ZjQ7vrg1u z6l+bS*<6^ng0AJrOoNa~>DR9u8vD8)C`V^Z{OY%Z)BgaUpMm;k7sTHV&9=);$hnA5 zBK*JxT;TfkIO$y+e-->aduu(-oGlE5L{@-Hf2&A%V*B9p@r$4);Q#@6*se?-yWR+8n8&95Tv8;cLRPZiL-Ny5G9vz{Ii zV)ea6_@Av-KNdV2b7XGA-K^2Y<~p+n1m_

M#X#R-X}cOVGl^%PqF>L!1JtcqDhm zdBLy7-w$}lTh?JWa<;=1OtJt-8<=p!bq5@A#ct`J5PU^rWj>h(=MU5zGo3k0<4I@1|hjEoZ}o0)p&eV&{}D% ze$Y}-{3M4VqwZH8g!Zq=tIrkqgG$nL>wPxxUrBur%^M7PMF=5%2yFDgti3nlFN!tY zay<)CMz^@O-x|7P`E18I1F81p;8jP&JQwn_8F*WmEpEQ^_3AH)I#srlJkZ@qaLI;M z;|MnuVh6bOtyuhNr_B|!OMFU9>>fg+DTFLHj)3H2K9%_!rg)RYFi9-`0B>bgY%nZ- zY-b>Y$G<&2>!G&zgRf}13l_dIWz1-tgStVSpYJX|D%L(AU^?8wei!B)8bANk{zvpl zPOE(bUI4`4amU^7^{qCzl5J{I+!Y`UdK_l4{3rhaAFzHkqMz~^pZ(?jV!Y;h1*jB@ zv0_<_WEa6FuOhW=blXdb=1CXstAIyd7b3G_{{WD(f4F~{u7^$k0FSGWqyGTt6|BJ3 z(HqOs;kIGEIY|r~oZxX>b^A$YZ!N8}6knL|eGe7a=^ydqYyR_pBV2y5)?fEu`O=7^ zvCi7uNp&P^HzI83wmy}a@fSeTMU+~CCfNcmNWjn6zw1{t-}TnNjb8YR{{SFJ{{Y-y z=T|L-J&z@`fg`pBayOhG%9_!xcCjoEud&5gw*LT+RQ~{b`c!TA$K(G1p-~l~o7oVU zm*v~WH)9^(=bE8~Wnw_V86&aAc=}eE?f(D+ti}6{{^_i)E`>QQAu)zwl1c0ADX+(kAb+hN@Gs_Tam(Q~Srs7+qn)9-=bn`7)s7oje6<|ppL4q(%85VJ z5BCT2rPROU)(^-307I#eLvl@ss*Ixr@ssrb0QFUgAPX2Fj|6_ap4Ah5$bS#yYUJPQ zht+C?_b`O>?0FT+pOo=|)YAErm6An~l!shn9B_TA75@NG{{Te(bs+x$Qz!fD{HnVd zK-aTRHX}TQmKYrO`MaLAy8D*SA(DTLGF;^s`lT1@in5~>X-hyN&KrQd6I5gK_1Y60HbPv z0LBkE$4d2EJ9w;gg}Ai=T6Sc90pkPISD0FV?8*GA)rb6mZT|r4tA8O{)7aW8L(+ax zWd*vZ92~Iw#3{mpeFbLQ*us28HkeC!M;-aW86!TKtt0-b52OD8=v583{Ekxn6aN4~ ztt3&dY~Zx=C4gb2kz;e*sa*b@tBuli8{H;(ZR}(ylOLFN`MUmOS9y2$Er09bKlB>& zX#W7?_wgUria!usmg4T?Qqm`B*oH=83i}*)$o(s^ourS#7B=d~W3+pRuI^26w*LU~ z2fF&V{)Ju5*Zhk5cl*(QDzyFMDQ?d1>{iLH+S;o8rqj$myNMm^GSf_tUAfe)Z{(22 z6YUBQ1P@$;Tdn^9BQ>Y}c(4A1DyN430OTX9f7eE>B-tx-nA5CaeKPXPkcbNmaB>O! z>k3(3Ee7Tx$WCKsNVHQ8(5de{EDC-SZ;@BTj1 O{<@#%S|_lrq5s*41p!O| literal 0 HcmV?d00001 diff --git a/apps/gpsnav/icon.png b/apps/gpsnav/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f899683d1d7e98b906c52bb0a5913de6f4dd2534 GIT binary patch literal 1887 zcmV-l2cY`(ry)@ zWg;nB2-><0R?!l+PBTp>?PycSfGwlYQ9@gxDi^5^Y!XysZ9`Hv!b-Z9ktKmZOG1;1 zCXVAvocMaqw;z!+C)oJ-up{jU&#!a&-tT!Hzu)Ekj)D8QkN;mB`Dd_r^P7X;l9Pjx zvvYyRCa<4=UQP~$oSjq9a;Gm;A}5Dz8F=jyHG+^e4tG$u`R$Hae0FUrS0IWbM zCMNh7<>Hae0420MdhPLrpOlM776XTGP!)j3qxZL6fv%nM{B=n=IV+3j}L&T$&Cy2NL|Z1ywhXg^}xUB_|UUE>&v^4ZV4e*T$c z6s_+xJvRAy_unUgh*(*o4OCWE^79H7A57O|{v>Vin)i>jHE|~6KF0_i~U{%gVDj4ZUBY__!88|{>mj)A_OwZjAb6Qdc%y{TwQc@h&! z_AV;2ps;i~JT9kU=(Fn$2X<{AJXZVS1^@t0HzkU7Pw+bc;M}REg{}66dO;Ab0H_$~ z>%r$;m!Z$i{Uyh7LP~m4H2?su_Qt;gcp^#+01RPZ$jiH`*m{Uig{nB(cK^w~>A0LM zrN6G|9E>5Rr_ zrRtEp6F*V8y`O--<>0kA<1I#mx*DJO7bK0#$>3@ar!=X60a&UV13EVc}j)QO~NW$2w~pc zy+YAJ2%$&;q71A*(XZC>?6a=%@Qz_u@F8Cy!rrZYtk9@|c;e&88KIQEM+t3FWUJoa zy_f_g8+f{YxG*62cX=iwPu+F~^MesSrEEn7??2ghM^;2)54iURXPNN16( z*pQV149!2raYX)NE{fm3@PqC# zpWmV`Tm{wFSE4hp039*nftdyX;9~D6h8-R(%bvvQ%r9Y5j33)jvF$mj8YJ(;$6l^k z=N!3h5qx8qymA)$tAB>W;Yk{|LVXM0^}L1htZT?&$3ZB5_}f*u?mbo3u)QLNX!JZPI3Z z#IRGeF$W^TgZ@T}mXr+~t=;p2*Ewp85l;cM2n?}2R$0B%pi^B+6ieB(mOZb&v1Vam zNttQxysNP$2=Ms(EsfSx^`v|ra65)yi4osQ1ZuNxt^PFnUZ2Sx2e3Y_0g%%Gu;Z2e z7Xg@${$kJ5KG)chfxeyx0HCmR`94bNs#Ge{l$OyWw&xG3)EPf3u#|QZ2rpSHx3|S> z_aN6B9-oXTfEml^V9mqIh4I9_{!-0Om(#J|IA^Y|pk&#W4bN1c601q{5aKvasnzM% z6+X1I(ppiqI+1t)n4?o&oBfP{oKE!1KDY1H`r6~o`UoGk4c)l<^Y-?3(IZ2&0W+Xn zxW-y$t*B~Amg1~*_MO?!C>72m8{bdZxSvkZ{buANgnzX+}uL(%f;Ug8Y8OUJO z2bigCnGch+vvTpsie>w*yAO2+&dbRm>%Wvnjq(BkK9rL~Rs&h->}!;uUrvtuxQ~0p Ze*jRY!kx=d0W$yq002ovPDHLkV1iy}i`f7G literal 0 HcmV?d00001 diff --git a/apps/gpsnav/marked_screen.jpg b/apps/gpsnav/marked_screen.jpg new file mode 100644 index 0000000000000000000000000000000000000000..accd3b15fe5fa0996c51ada2f75ddd416dd17394 GIT binary patch literal 65895 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%0D85DN}Kju4Ys-^?RDWah8DK1Yt!XB1!a-x5(? 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

SKQuyodtT#X^!9_vAdcfo!M@gV% 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 literal 0 HcmV?d00001 diff --git a/apps/gpsnav/waypoints.json b/apps/gpsnav/waypoints.json new file mode 100644 index 000000000..143316b19 --- /dev/null +++ b/apps/gpsnav/waypoints.json @@ -0,0 +1,23 @@ +[ + { + "mark":0, + "name":"NONE" + }, + { + "mark":1, + "name":"No10", + "lat":51.5032, + "lon":-0.1269 + }, + { + "mark":1, + "name":"Stone", + "lat":51.1788, + "lon":-1.8260 + }, + { "name":"WP0" }, + { "name":"WP1" }, + { "name":"WP2" }, + { "name":"WP3" }, + { "name":"WP4" } +] \ No newline at end of file From 73366a600cdf52d0f108f2aacd7542ee502bb583 Mon Sep 17 00:00:00 2001 From: jeffmer Date: Sat, 18 Apr 2020 14:44:00 +0100 Subject: [PATCH 057/878] Update apps.json --- apps.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps.json b/apps.json index 0c97b9e57..0b7001a5e 100644 --- a/apps.json +++ b/apps.json @@ -291,6 +291,18 @@ {"name":"gpsrec.wid.js","url":"widget.js"} ] }, + { "id": "gpsnav", + "name": "GPS Navigation", + "icon": "icon.png", + "version":"0.01", + "description": "Displays GPS Course and Speed, + Directions to waypoint and waypoint recording", + "tags": "tool,outdoors,gps", + "storage": [ + {"name":"gpsnav.app.js","url":"app.js"}, + {"name":"waypoints.json","url":"waypoints.json","evaluate":false}, + {"name":"gpsnav.img","url":"app-icon.js","evaluate":true} + ] + }, { "id": "heart", "name": "Heart Rate Recorder", "icon": "app.png", From 696afd7f6bae48410d27df696298b239b31c1f3f Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 18 Apr 2020 16:08:33 +0200 Subject: [PATCH 058/878] ble hid control is removed from require and is now hard written in app --- apps/hidcam/app.js | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/apps/hidcam/app.js b/apps/hidcam/app.js index 6a4150673..f529deff2 100644 --- a/apps/hidcam/app.js +++ b/apps/hidcam/app.js @@ -1,16 +1,46 @@ -var controls = require("ble_hid_controls"); var storage = require('Storage'); const settings = storage.readJSON('setting.json',1) || { HID: false }; +// hidcontrol module selective and manual import : +report = new Uint8Array([ + 0x05, 0x0c, // USAGE_PAGE (Consumer Devices) + 0x09, 0x01, // USAGE (Consumer Control) + 0xa1, 0x01, // COLLECTION (Application) + // -------------------- common global items + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) - each field occupies 1 bit + // -------------------- misc bits + 0x95, 0x05, // REPORT_COUNT (5) + 0x09, 0xb5, // USAGE (Scan Next Track) + 0x09, 0xb6, // USAGE (Scan Previous Track) + 0x09, 0xb7, // USAGE (Stop) + 0x09, 0xcd, // USAGE (Play/Pause) + 0x09, 0xe2, // USAGE (Mute) + 0x81, 0x06, // INPUT (Data,Var,Rel) - relative inputs + // -------------------- volume up/down bits + 0x95, 0x02, // REPORT_COUNT (2) + 0x09, 0xe9, // USAGE (Volume Up) + 0x09, 0xea, // USAGE (Volume Down) + 0x81, 0x02, // INPUT (Data,Var,Abs) - absolute inputs + // -------------------- padding bit + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x01, // INPUT (Cnst,Ary,Abs) + 0xc0 // END_COLLECTION +]); +function p(c,cb) { NRF.sendHIDReport(c, function() { NRF.sendHIDReport(0, cb) }); } +volumeUp = function(cb) { p(0x20,cb) }; +//end of manual selective import + g.clear(); E.showMessage('BTN2 to trigger','camTrigger'); Bangle.loadWidgets(); Bangle.drawWidgets(); if (settings.HID) { - NRF.setServices(undefined, { hid : controls.report }); - shotTrigger = function() {controls.volumeUp();}; + NRF.setServices(undefined, { hid : report }); + shotTrigger = function() {volumeUp();}; } else { E.showMessage('HID disabled'); setTimeout(load, 1000); From 41d206cdbe03461808b54f71149f6598b7ac0a24 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 18 Apr 2020 16:24:33 +0200 Subject: [PATCH 059/878] typos in code and no more useless timeout --- apps/hidcam/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/hidcam/app.js b/apps/hidcam/app.js index f529deff2..9117d94f5 100644 --- a/apps/hidcam/app.js +++ b/apps/hidcam/app.js @@ -33,6 +33,8 @@ function p(c,cb) { NRF.sendHIDReport(c, function() { NRF.sendHIDReport(0, cb) }) volumeUp = function(cb) { p(0x20,cb) }; //end of manual selective import +NRF.setServices(undefined, { hid : report }); + g.clear(); E.showMessage('BTN2 to trigger','camTrigger'); Bangle.loadWidgets(); @@ -50,7 +52,6 @@ setWatch(function(e){ E.showMessage('capture'); Bangle.beep(); shotTrigger(); - set.Timeout(load,1000); g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); From fc6d6aa4bbe1fdfefade4a0e85ab96460d1feda2 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 18 Apr 2020 16:41:43 +0200 Subject: [PATCH 060/878] hid code correction --- apps/hidcam/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hidcam/app.js b/apps/hidcam/app.js index 9117d94f5..e114863cc 100644 --- a/apps/hidcam/app.js +++ b/apps/hidcam/app.js @@ -30,7 +30,7 @@ report = new Uint8Array([ 0xc0 // END_COLLECTION ]); function p(c,cb) { NRF.sendHIDReport(c, function() { NRF.sendHIDReport(0, cb) }); } -volumeUp = function(cb) { p(0x20,cb) }; +volumeUp = function(cb) { p(0x80,cb) }; //end of manual selective import NRF.setServices(undefined, { hid : report }); From b58069fba13b50bba26dadf667dc55616d64bdc2 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 18 Apr 2020 16:52:30 +0200 Subject: [PATCH 061/878] massive rewrite with really heavy inspiration from music control app --- apps/hidcam/app.js | 89 +++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/apps/hidcam/app.js b/apps/hidcam/app.js index e114863cc..57d4a6f05 100644 --- a/apps/hidcam/app.js +++ b/apps/hidcam/app.js @@ -2,58 +2,51 @@ var storage = require('Storage'); const settings = storage.readJSON('setting.json',1) || { HID: false }; -// hidcontrol module selective and manual import : -report = new Uint8Array([ - 0x05, 0x0c, // USAGE_PAGE (Consumer Devices) - 0x09, 0x01, // USAGE (Consumer Control) - 0xa1, 0x01, // COLLECTION (Application) - // -------------------- common global items - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x75, 0x01, // REPORT_SIZE (1) - each field occupies 1 bit - // -------------------- misc bits - 0x95, 0x05, // REPORT_COUNT (5) - 0x09, 0xb5, // USAGE (Scan Next Track) - 0x09, 0xb6, // USAGE (Scan Previous Track) - 0x09, 0xb7, // USAGE (Stop) - 0x09, 0xcd, // USAGE (Play/Pause) - 0x09, 0xe2, // USAGE (Mute) - 0x81, 0x06, // INPUT (Data,Var,Rel) - relative inputs - // -------------------- volume up/down bits - 0x95, 0x02, // REPORT_COUNT (2) - 0x09, 0xe9, // USAGE (Volume Up) - 0x09, 0xea, // USAGE (Volume Down) - 0x81, 0x02, // INPUT (Data,Var,Abs) - absolute inputs - // -------------------- padding bit - 0x95, 0x01, // REPORT_COUNT (1) - 0x81, 0x01, // INPUT (Cnst,Ary,Abs) - 0xc0 // END_COLLECTION -]); -function p(c,cb) { NRF.sendHIDReport(c, function() { NRF.sendHIDReport(0, cb) }); } -volumeUp = function(cb) { p(0x80,cb) }; -//end of manual selective import - -NRF.setServices(undefined, { hid : report }); - -g.clear(); -E.showMessage('BTN2 to trigger','camTrigger'); -Bangle.loadWidgets(); -Bangle.drawWidgets(); +var sendHid, camShot, profile; if (settings.HID) { - NRF.setServices(undefined, { hid : report }); - shotTrigger = function() {volumeUp();}; + profile = 'camShutter'; + sendHid = function (code, cb) { + try { + NRF.sendHIDReport([1,code], () => { + NRF.sendHIDReport([1,0], () => { + if (cb) cb(); + }); + }); + } catch(e) { + print(e); + } + }; + camShot = function (cb) { sendHid(0x80, cb); }; } else { E.showMessage('HID disabled'); setTimeout(load, 1000); } - -setWatch(function(e){ - E.showMessage('capture'); - Bangle.beep(); - shotTrigger(); +function drawApp() { g.clear(); - Bangle.loadWidgets(); - Bangle.drawWidgets(); - E.showMessage('BTN2 to trigger','camTrigger'); -},BTN2,{ repeat:true, edge:'falling' }); + g.setFont("6x8",2); + g.setFontAlign(0,0); + g.drawString(profile, 120, 120); + const d = g.getWidth() - 18; + + function c(a) { + return { + width: 8, + height: a.length, + bpp: 1, + buffer: (new Uint8Array(a)).buffer + }; + } + + g.drawImage(c([0,8,12,14,255,14,12,8]),d,116); +} + +if (camShot) { + setWatch(function(e) { + E.showMessage('camShot !'); + setTimeout(drawApp, 1000); + camShot(() => {}); + }, BTN2, { edge:"falling",repeat:true,debounce:50}); + + drawApp(); +} From 58e826accc018bbc638721f822b105959a19df52 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 18 Apr 2020 17:01:01 +0200 Subject: [PATCH 062/878] adding widgets --- apps/hidcam/app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/hidcam/app.js b/apps/hidcam/app.js index 57d4a6f05..c3c672d4c 100644 --- a/apps/hidcam/app.js +++ b/apps/hidcam/app.js @@ -24,6 +24,8 @@ if (settings.HID) { } function drawApp() { g.clear(); + Bangle.loadWidgets() + Bangle.drawWidgets() g.setFont("6x8",2); g.setFontAlign(0,0); g.drawString(profile, 120, 120); From 63526c49e227a423eea5eaab25226c029d3e37b9 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 18 Apr 2020 17:08:01 +0200 Subject: [PATCH 063/878] using app icon instead of text --- apps/hidcam/app.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/hidcam/app.js b/apps/hidcam/app.js index c3c672d4c..6e599959c 100644 --- a/apps/hidcam/app.js +++ b/apps/hidcam/app.js @@ -26,9 +26,10 @@ function drawApp() { g.clear(); Bangle.loadWidgets() Bangle.drawWidgets() - g.setFont("6x8",2); - g.setFontAlign(0,0); - g.drawString(profile, 120, 120); +// g.setFont("6x8",2); +// g.setFontAlign(0,0); +// g.drawString(profile, 120, 120); + g.drawImage(storage.read("hidcam.img"),120,120) const d = g.getWidth() - 18; function c(a) { From aa168c3d5c5dce983dc4f3a52a24bd5e1d435868 Mon Sep 17 00:00:00 2001 From: fredericrous Date: Sat, 18 Apr 2020 16:30:05 +0100 Subject: [PATCH 064/878] Fix App Calculator issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Javascript rounded float issues - Reset after equals wasn't done properly - Introduce unit tests 🤗 --- apps.json | 4 +- apps/calculator/ChangeLog | 1 + apps/calculator/app.js | 146 +++++++++++++------- apps/calculator/tests.html | 273 +++++++++++++++++++++++++++++++++++++ 4 files changed, 369 insertions(+), 55 deletions(-) create mode 100644 apps/calculator/tests.html diff --git a/apps.json b/apps.json index 0c97b9e57..9bd4ee6fb 100644 --- a/apps.json +++ b/apps.json @@ -1264,8 +1264,8 @@ "name": "Calculator", "shortName":"Calculator", "icon": "calculator.png", - "version":"0.01", - "description": "Basic calculator reminiscent of MacOs's one. Handy for small calculus. Push button1 and 3 to navigate up/down, tap right or left to navigate the sides, push button 2 to select.", + "version":"0.02", + "description": "Basic calculator reminiscent of MacOs's one. Handy for small calculus.", "tags": "app,tool", "storage": [ {"name":"calculator.app.js","url":"app.js"}, diff --git a/apps/calculator/ChangeLog b/apps/calculator/ChangeLog index 5560f00bc..3b9b23270 100644 --- a/apps/calculator/ChangeLog +++ b/apps/calculator/ChangeLog @@ -1 +1,2 @@ 0.01: New App! +0.02: fix precision rounding issue + no reset when equals pressed diff --git a/apps/calculator/app.js b/apps/calculator/app.js index 91dd7c49d..ad26d2d22 100644 --- a/apps/calculator/app.js +++ b/apps/calculator/app.js @@ -144,19 +144,57 @@ function drawKey(name, k, selected) { g.drawString(k.val || name, k.xy[0] + RIGHT_MARGIN + rMargin, k.xy[1] + BOTTOM_MARGIN + bMargin); } +function getIntWithPrecision(x) { + var xStr = x.toString(); + var xRadix = xStr.indexOf('.'); + var xPrecision = xRadix === -1 ? 0 : xStr.length - xRadix - 1; + return { + num: Number(xStr.replace('.', '')), + p: xPrecision + }; +} + +function multiply(x, y) { + var xNum = getIntWithPrecision(x); + var yNum = getIntWithPrecision(y); + return xNum.num * yNum.num / Math.pow(10, xNum.p + yNum.p); +} + +function divide(x, y) { + var xNum = getIntWithPrecision(x); + var yNum = getIntWithPrecision(y); + return xNum.num / yNum.num / Math.pow(10, xNum.p - yNum.p); +} + +function sum(x, y) { + let xNum = getIntWithPrecision(x); + let yNum = getIntWithPrecision(y); + + let diffPrecision = Math.abs(xNum.p - yNum.p); + if (diffPrecision > 0) { + if (xNum.p > yNum.p) { + yNum.num = yNum.num * Math.pow(10, diffPrecision); + } else { + xNum.num = xNum.num * Math.pow(10, diffPrecision); + } + } + return (xNum.num + yNum.num) / Math.pow(10, Math.max(xNum.p, yNum.p)); +} + +function subtract(x, y) { + return sum(x, -y); +} + function doMath(x, y, operator) { - // might not be a number due to display of dot "." algo - x = Number(x); - y = Number(y); switch (operator) { case '/': - return x / y; + return divide(x, y); case '*': - return x * y; + return multiply(x, y); case '+': - return x + y; + return sum(x, y); case '-': - return x - y; + return subtract(x, y); } } @@ -204,7 +242,7 @@ function displayOutput(num) { } len = (num + '').length; - if (numNumeric < 0) { + if (numNumeric < 0 || (numNumeric === 0 && 1/numNumeric === -Infinity)) { // minus is not available in font 7x11Numeric7Seg, we use Vector g.setFont('Vector', 20); g.drawString('-', 220 - (len * 15), 10); @@ -214,18 +252,33 @@ function displayOutput(num) { } g.drawString(num, 220 - (len * 15) + minusMarge, 10); } - +var wasPressedEquals = false; +var hasPressedNumber = false; function calculatorLogic(x) { - if (hasPressedEquals) { - currNumber = results; + if (wasPressedEquals && hasPressedNumber !== false) { prevNumber = null; - operator = null; - results = null; - isDecimal = null; - displayOutput(currNumber); - hasPressedEquals = false; + currNumber = hasPressedNumber; + wasPressedEquals = false; + hasPressedNumber = false; + return; } - if (prevNumber != null && currNumber != null && operator != null) { + if (hasPressedEquals) { + if (hasPressedNumber) { + prevNumber = null; + hasPressedNumber = false; + operator = null; + } else { + currNumber = null; + prevNumber = results; + } + hasPressedEquals = false; + wasPressedEquals = true; + } + + if (currNumber == null && operator != null && '/*-+'.indexOf(x) !== -1) { + operator = x; + displayOutput(prevNumber); + } else if (prevNumber != null && currNumber != null && operator != null) { // we execute the calculus only when there was a previous number entered before and an operator results = doMath(prevNumber, currNumber, operator); operator = x; @@ -255,8 +308,10 @@ function buttonPress(val) { operator = null; } else { keys.R.val = 'AC'; - drawKey('R', keys.R); + drawKey('R', keys.R, true); } + wasPressedEquals = false; + hasPressedNumber = false; displayOutput(0); break; case '%': @@ -265,11 +320,12 @@ function buttonPress(val) { } else if (currNumber != null) { displayOutput(currNumber /= 100); } + hasPressedNumber = false; break; case 'N': if (results != null) { displayOutput(results *= -1); - } else if (currNumber != null) { + } else { displayOutput(currNumber *= -1); } break; @@ -278,6 +334,7 @@ function buttonPress(val) { case '-': case '+': calculatorLogic(val); + hasPressedNumber = false; break; case '.': keys.R.val = 'C'; @@ -290,18 +347,24 @@ function buttonPress(val) { results = doMath(prevNumber, currNumber, operator); prevNumber = results; displayOutput(results); - hasPressedEquals = true; + hasPressedEquals = 1; } + hasPressedNumber = false; break; default: keys.R.val = 'C'; drawKey('R', keys.R); + const is0Negative = (currNumber === 0 && 1/currNumber === -Infinity); if (isDecimal) { - currNumber = currNumber == null ? 0 + '.' + val : currNumber + '.' + val; + currNumber = currNumber == null || hasPressedEquals === 1 ? 0 + '.' + val : currNumber + '.' + val; isDecimal = false; } else { - currNumber = currNumber == null ? val : currNumber + val; + currNumber = currNumber == null || hasPressedEquals === 1 ? val : (is0Negative ? '-' + val : currNumber + val); } + if (hasPressedEquals === 1) { + hasPressedEquals = 2; + } + hasPressedNumber = currNumber; displayOutput(currNumber); break; } @@ -315,38 +378,15 @@ for (var k in keys) { g.setFont('7x11Numeric7Seg', 2.8); g.drawString('0', 205, 10); - -setWatch(function() { - drawKey(selected, keys[selected]); - // key 0 is 2 keys wide, go up to 1 if it was previously selected - if (selected == '0' && prevSelected === '1') { - prevSelected = selected; - selected = '1'; - } else { - prevSelected = selected; - selected = keys[selected].trbl[0]; - } - drawKey(selected, keys[selected], true); -}, BTN1, {repeat: true, debounce: 100}); - -setWatch(function() { +function moveDirection(d) { drawKey(selected, keys[selected]); prevSelected = selected; - selected = keys[selected].trbl[2]; + selected = (d === 0 && selected == '0' && prevSelected === '1') ? '1' : keys[selected].trbl[d]; drawKey(selected, keys[selected], true); -}, BTN3, {repeat: true, debounce: 100}); +} -Bangle.on('touch', function(direction) { - drawKey(selected, keys[selected]); - prevSelected = selected; - if (direction == 1) { - selected = keys[selected].trbl[3]; - } else if (direction == 2) { - selected = keys[selected].trbl[1]; - } - drawKey(selected, keys[selected], true); -}); - -setWatch(function() { - buttonPress(selected); -}, BTN2, {repeat: true, debounce: 100}); +setWatch(_ => moveDirection(0), BTN1, {repeat: true, debounce: 100}); +setWatch(_ => moveDirection(2), BTN3, {repeat: true, debounce: 100}); +setWatch(_ => moveDirection(3), BTN4, {repeat: true, debounce: 100}); +setWatch(_ => moveDirection(1), BTN5, {repeat: true, debounce: 100}); +setWatch(_ => buttonPress(selected), BTN2, {repeat: true, debounce: 100}); diff --git a/apps/calculator/tests.html b/apps/calculator/tests.html new file mode 100644 index 000000000..1cbfdf617 --- /dev/null +++ b/apps/calculator/tests.html @@ -0,0 +1,273 @@ + + + + + + Calculator tests + + + + + +

+
+ + + + + + + From 20f7c80462ce905288a987eda8455d9016771041 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 18 Apr 2020 17:30:28 +0200 Subject: [PATCH 065/878] graphical adjustments --- apps/hidcam/app.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/apps/hidcam/app.js b/apps/hidcam/app.js index 6e599959c..89b8ac4a1 100644 --- a/apps/hidcam/app.js +++ b/apps/hidcam/app.js @@ -24,12 +24,10 @@ if (settings.HID) { } function drawApp() { g.clear(); - Bangle.loadWidgets() - Bangle.drawWidgets() -// g.setFont("6x8",2); -// g.setFontAlign(0,0); -// g.drawString(profile, 120, 120); - g.drawImage(storage.read("hidcam.img"),120,120) + Bangle.loadWidgets(); + Bangle.drawWidgets(); + g.fillCircle(122,127,60); + g.drawImage(storage.read("hidcam.img"),100,105); const d = g.getWidth() - 18; function c(a) { @@ -40,8 +38,7 @@ function drawApp() { buffer: (new Uint8Array(a)).buffer }; } - - g.drawImage(c([0,8,12,14,255,14,12,8]),d,116); + g.fillRect(180,130, 240, 124); } if (camShot) { From d545a7a87d8a73270f90263e337a232339355360 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 18 Apr 2020 17:36:47 +0200 Subject: [PATCH 066/878] changelog update --- apps/hidcam/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hidcam/ChangeLog b/apps/hidcam/ChangeLog index 665c0df6e..73b3268b7 100644 --- a/apps/hidcam/ChangeLog +++ b/apps/hidcam/ChangeLog @@ -1 +1 @@ -0.01: Init +0.01: Core functionnality From 406deafadd762bd45c427362a40a210c61fb8bbf Mon Sep 17 00:00:00 2001 From: Ignas Bukys Date: Sat, 18 Apr 2020 21:22:04 +0300 Subject: [PATCH 067/878] BlackJack game --- apps/blackjack/ChangeLog | 1 + apps/blackjack/blackjack.app.js | 191 ++++++++++++++++++++++++++++++++ apps/blackjack/blackjack.img | Bin 0 -> 706 bytes apps/blackjack/blackjack.info | 1 + 4 files changed, 193 insertions(+) create mode 100644 apps/blackjack/ChangeLog create mode 100644 apps/blackjack/blackjack.app.js create mode 100644 apps/blackjack/blackjack.img create mode 100644 apps/blackjack/blackjack.info diff --git a/apps/blackjack/ChangeLog b/apps/blackjack/ChangeLog new file mode 100644 index 000000000..c941d90e5 --- /dev/null +++ b/apps/blackjack/ChangeLog @@ -0,0 +1 @@ +0.01: New game! BTN4- Hit card, BTN5- Stand \ No newline at end of file diff --git a/apps/blackjack/blackjack.app.js b/apps/blackjack/blackjack.app.js new file mode 100644 index 000000000..dc5d35494 --- /dev/null +++ b/apps/blackjack/blackjack.app.js @@ -0,0 +1,191 @@ +const Clubs = { width : 48, height : 48, bpp : 1, + buffer : require("heatshrink").decompress(atob("ACcP+AFDn/8Aod//wFD///AgUBAoOAApsDAoPAAr4vLI4pTEgP8L4M/wEH/5rB//gh//x/x//wj//9/3//4n4iBAAIZBAol/Aof+Apv5z4FP+OPAo41BAoX8I4Pj45HBAoPD4YFBLIOD4JZBRAMD4CKC/AFBj59Cg/gQYYFXAB4=")) +}; + +const Spades = { width : 48, height : 48, bpp : 1, + buffer : require("heatshrink").decompress(atob("ABsBwAFDgfAAocH8AFDh/wAocf/AFDn/8Aod//wFD///FwYFBGAUDAoIwCg4FBGAUPAoIwCj4FBGAU/AoIwCv4FBGAQEBGAQuCGAQuCGAQFLHQQ8CAupHLL4prB+fPTgU/8fHVwbLLApbXFbpYFLdIoADA==")) +}; + +const Hearts = { width : 48, height : 48, bpp : 4, + buffer : require("heatshrink").decompress(atob("ADlVqtQBQ8FBYIKIrnMAAINGqoKC4okGCwYAB4AKDhgKE4oWKAAILDBQwYEBYwwDFwojFgoLHEgQ6H5hhCBZAkCBRAjLEgI6IC4YLIC5Y7BBZXBjgjVABYX/C8CnKABbXLABTvMC8sMC6fAC4KQURwIABRypgULwRgULwRIUCwhIRIwiRSRoZITCwx5POoowRCxAwNFxIwNCxQwLFxYwLCxgwJFxowJCxwwHFx4wHCyAwFFyIwFCyQwDFycAgoXBqAXTgFc4oWUJAJGUJARGVAEo")) + }; + +const Diamonds = { width : 48, height : 48, bpp : 4, + buffer : require("heatshrink").decompress(atob("AHUFC60M4AXV5nFIyvM5hGVC4JIUCwJIUIwRIUIwRIUCwZISIwgABqBGUJCQWFPKBGGJCFcC455OCw4wOOox5QIxB5NOpBIOFxZ5LCxYwKOpQwMIxh5KOxipLL6xgNR5QwMX5TvXPJZ1JJBpGLPJR1LJBZGNPJIWOJA5GOPJB1NJBIWQPIpGRJApGRPIoWSJAa8PJA5GTJAYWUJAJGVAAJGVAHo=")) + }; + + +var deck = []; +var player = {Hand:[]}; +var computer = {Hand:[]}; + +function createDeck() { + var suits = ["Spades", "Hearts", "Diamonds", "Clubs"]; + var values = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]; + + var dck = []; + for (var i = 0 ; i < values.length; i++) { + for(var x = 0; x < suits.length; x++) { + dck.push({ Value: values[i], Suit: suits[x] }); + } + } + return dck; +} + +function shuffle(a) { + var j, x, i; + for (i = a.length - 1; i > 0; i--) { + j = Math.floor(Math.random() * (i + 1)); + x = a[i]; + a[i] = a[j]; + a[j] = x; + } + return a; +} + +function EndGameMessdage(msg){ + g.drawString(msg, 155, 200); + setTimeout(function(){ + startGame(); + }, 2500); + +} + +function hitMe() { + player.Hand.push(deck.pop()); + renderOnScreen(1); + var playerWeight = calcWeight(player.Hand, 0); + + if(playerWeight == 21) + EndGameMessdage('WINNER'); + else if(playerWeight > 21) + EndGameMessdage('LOOSER'); +} + +function calcWeight(hand, hideCard) { + + if(hideCard === 1) { + if (hand[0].Value == "J" || hand[0].Value == "Q" || hand[0].Value == "K") + return "10 +"; + else if (hand[0].Value == "A") + return "11 +"; + else + return parseInt(hand[0].Value) +" +"; + } + else { + var weight = 0; + for(i=0; i 21 || bangleWeight < playerWeight) + EndGameMessdage('WINNER'); + else if(bangleWeight > playerWeight) + EndGameMessdage('LOOSER'); +} + +function renderOnScreen(HideCard) { + const fontName = "6x8"; + + g.clear(); // clear screen + g.reset(); // default draw styles + g.setFont(fontName, 1); + + g.drawString('RST', 220, 35); + g.drawString('Hit', 60, 230); + g.drawString('Stand', 165, 230); + + g.setFont(fontName, 3); + for(i=0; i9WgH5ul2)7_0>|Km^WM! ktsjd-R^R}YcOcfVu~7y4Cx08IkIR{#J2 literal 0 HcmV?d00001 diff --git a/apps/blackjack/blackjack.info b/apps/blackjack/blackjack.info new file mode 100644 index 000000000..b30333f2e --- /dev/null +++ b/apps/blackjack/blackjack.info @@ -0,0 +1 @@ +{"id":"blackjack","name":"Black Jack","src":"blackjack.app.js","icon":"blackjack.img","version":"0.1","files":"blackjack.info,blackjack.app.js,blackjack.img"} \ No newline at end of file From 58d640a2e2dc08e79423ce984f9c1c0156e23a80 Mon Sep 17 00:00:00 2001 From: Ignas Bukys Date: Sat, 18 Apr 2020 22:11:50 +0300 Subject: [PATCH 068/878] added blackjack game to apps.json --- apps.json | 12 ++++++++++++ apps/blackjack/blackjack.png | Bin 0 -> 646 bytes 2 files changed, 12 insertions(+) create mode 100644 apps/blackjack/blackjack.png diff --git a/apps.json b/apps.json index 0c97b9e57..0a6281c37 100644 --- a/apps.json +++ b/apps.json @@ -1293,5 +1293,17 @@ "evaluate": true } ] + }, + { "id": "blackjack", + "name": "Black Jack game", + "shortName":"BlackJack game", + "icon": "blackjack.png", + "version":"0.01", + "description": "Simplle implementation of card game Black Jack", + "tags": "", + "storage": [ + {"name":"blackjack.app.js","url":"blackjack.app.js"}, + {"name":"blackjack.img","url":"blackjack-icon.js","evaluate":true} + ] } ] diff --git a/apps/blackjack/blackjack.png b/apps/blackjack/blackjack.png new file mode 100644 index 0000000000000000000000000000000000000000..53715b5e44226d70a129a36fc2f663e4e6157f0e GIT binary patch literal 646 zcmV;10(t$3P)Px#1ZP1_K>z@;j|==^1poj5Fi=cXMF0Q*78VvLC@3~IHc3fIR8&-GXlQnJc87+Amh{@>F7O#lD@32;bRa{vGi!vFvd!vV){sAK>D0pCeP zK~y-)rIWu;6hRcnzXx|W!-?iPS{f2UNu$=DlaT_>83S%9tk^I!6*|as>t=o1 zrJvG>k!LXqxx|Z4A74gs{_PI%Akg(TfJI{Cugo!h<(+25uNnN{ERuBfM1wo3)LJn|XA$T-T{l3VA%^j=gFO901_m@WD5=}vb6`NG zp~0hQy+xe_M*_^V$jA-SJqspuhUDwPhYMI>u2sI{R&{~_ zO#|9M{X0KJ$pE7kvV(yxZ{BVjVAMjiQUAui9s?Oa?~ Date: Sat, 18 Apr 2020 22:20:09 +0300 Subject: [PATCH 069/878] adde icon for game --- apps/blackjack/blackjack-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/blackjack/blackjack-icon.js diff --git a/apps/blackjack/blackjack-icon.js b/apps/blackjack/blackjack-icon.js new file mode 100644 index 000000000..5c184fe4a --- /dev/null +++ b/apps/blackjack/blackjack-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("ABsD4AECn//2AEBg/4gEQAoMIAQIFFjACHBYoFIh+AgEMGQXwAokfAoMP8EHwPghk//AXBmEMnl8n+AjEMvl8/4FCvE9AoMQAoM894XBgkYvgdCgkAAocGgF4AoNgAoPwAongAocB4AFDgeAAoPAg0HL4QFBhwFEjkGh+BwEGnEOAoUCv/+Apd//a3BAorBDAohLBgf+AocB/gFDgFMAogCCUoUH8AFDDASxDn/AYYQrB/DMCAAN/zAFDg7LBAAYlBAAoA==")) \ No newline at end of file From 98795281a190d9dd5ba9e6ff2217ba919d9f331e Mon Sep 17 00:00:00 2001 From: Ignas Bukys Date: Sat, 18 Apr 2020 22:20:57 +0300 Subject: [PATCH 070/878] fix typo in description --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 0a6281c37..3b7ac0def 100644 --- a/apps.json +++ b/apps.json @@ -1299,7 +1299,7 @@ "shortName":"BlackJack game", "icon": "blackjack.png", "version":"0.01", - "description": "Simplle implementation of card game Black Jack", + "description": "Simple implementation of card game Black Jack", "tags": "", "storage": [ {"name":"blackjack.app.js","url":"blackjack.app.js"}, From 34e3748ee6ee01eddbf09e47b08ecc1c7dbc5303 Mon Sep 17 00:00:00 2001 From: Ignas Bukys Date: Sat, 18 Apr 2020 22:27:58 +0300 Subject: [PATCH 071/878] add game tag and change icon --- apps.json | 5 +++-- apps/blackjack/blackjack-icon.js | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 apps/blackjack/blackjack-icon.js diff --git a/apps.json b/apps.json index 3b7ac0def..a62fa9ece 100644 --- a/apps.json +++ b/apps.json @@ -1300,10 +1300,11 @@ "icon": "blackjack.png", "version":"0.01", "description": "Simple implementation of card game Black Jack", - "tags": "", + "tags": "game", + "allow_emulator":true, "storage": [ {"name":"blackjack.app.js","url":"blackjack.app.js"}, - {"name":"blackjack.img","url":"blackjack-icon.js","evaluate":true} + {"name":"blackjack.img","url":"blackjack.img"} ] } ] diff --git a/apps/blackjack/blackjack-icon.js b/apps/blackjack/blackjack-icon.js deleted file mode 100644 index 5c184fe4a..000000000 --- a/apps/blackjack/blackjack-icon.js +++ /dev/null @@ -1 +0,0 @@ -require("heatshrink").decompress(atob("ABsD4AECn//2AEBg/4gEQAoMIAQIFFjACHBYoFIh+AgEMGQXwAokfAoMP8EHwPghk//AXBmEMnl8n+AjEMvl8/4FCvE9AoMQAoM894XBgkYvgdCgkAAocGgF4AoNgAoPwAongAocB4AFDgeAAoPAg0HL4QFBhwFEjkGh+BwEGnEOAoUCv/+Apd//a3BAorBDAohLBgf+AocB/gFDgFMAogCCUoUH8AFDDASxDn/AYYQrB/DMCAAN/zAFDg7LBAAYlBAAoA==")) \ No newline at end of file From aee60d97c0476dd7fd694a78e73e85d45ce4badf Mon Sep 17 00:00:00 2001 From: Ignas Bukys Date: Sat, 18 Apr 2020 22:43:29 +0300 Subject: [PATCH 072/878] Fix icon --- apps.json | 4 ++-- apps/blackjack/blackjack-icon.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 apps/blackjack/blackjack-icon.js diff --git a/apps.json b/apps.json index a62fa9ece..6e221c778 100644 --- a/apps.json +++ b/apps.json @@ -1296,7 +1296,7 @@ }, { "id": "blackjack", "name": "Black Jack game", - "shortName":"BlackJack game", + "shortName":"Black Jack game", "icon": "blackjack.png", "version":"0.01", "description": "Simple implementation of card game Black Jack", @@ -1304,7 +1304,7 @@ "allow_emulator":true, "storage": [ {"name":"blackjack.app.js","url":"blackjack.app.js"}, - {"name":"blackjack.img","url":"blackjack.img"} + {"name":"blackjack.img","url":"blackjack-icon.js","evaluate":true} ] } ] diff --git a/apps/blackjack/blackjack-icon.js b/apps/blackjack/blackjack-icon.js new file mode 100644 index 000000000..f0976a5be --- /dev/null +++ b/apps/blackjack/blackjack-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgIQNgfAAgU/+UQAgMHmEAAoUIAQIFFjACHBYoFIgeAAocA+EAhgFCg4FBg/ggeB8EMj/4h+AmEMnl4j+AjEMvF8v4FDnv3wEQhk4nnnC4MEjE8g4FCgF4Ao8gAoNwAoNgg0A8AFDgPAAoZXBAoPAgxQBAocOAokcBoOAwEGnEOg+BwECv/+AosPAol//MAAoP8v/7RgLBDAokCAoO8AoJRBgHMAolMAogCCNIJLBcQKrCgP8WIk7wC9Dgf4ZgQABu4FEYIIFDRYIFEAAI")) \ No newline at end of file From 0c03bce926a8cac1282001c885dfa9d28eafde33 Mon Sep 17 00:00:00 2001 From: Ignas Bukys Date: Sat, 18 Apr 2020 22:45:33 +0300 Subject: [PATCH 073/878] icon brightness --- apps/blackjack/blackjack-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/blackjack/blackjack-icon.js b/apps/blackjack/blackjack-icon.js index f0976a5be..cb4d00cdd 100644 --- a/apps/blackjack/blackjack-icon.js +++ b/apps/blackjack/blackjack-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwgIQNgfAAgU/+UQAgMHmEAAoUIAQIFFjACHBYoFIgeAAocA+EAhgFCg4FBg/ggeB8EMj/4h+AmEMnl4j+AjEMvF8v4FDnv3wEQhk4nnnC4MEjE8g4FCgF4Ao8gAoNwAoNgg0A8AFDgPAAoZXBAoPAgxQBAocOAokcBoOAwEGnEOg+BwECv/+AosPAol//MAAoP8v/7RgLBDAokCAoO8AoJRBgHMAolMAogCCNIJLBcQKrCgP8WIk7wC9Dgf4ZgQABu4FEYIIFDRYIFEAAI")) \ No newline at end of file +require("heatshrink").decompress(atob("mEwgIQNgfAAgU///wAgMH/4dBAoMMAQMQAQMIAQMYAQ4RCApcPwAFDgIwBAoQ4BAoMP8EHwfghk//AXBuEMv38n+AjEMvl8/4FDvoFBmEMvF994FBg04vgdBAoMAAot4AoNgAoPwAoZFBAongAoPggyIBAoPAg0HwAFDh4BBAoUeh0PwOAg08AocDv/+Ao3DAod//a3BAorBDAohRBgf+AocBAokApgCBhzSCWIkHVYgYCWIngYwQrB/gFDgF//AFDD4QAD8AFEAAIA=")) \ No newline at end of file From 79f18015ef8ae54f9ff24eb1573fb2acb6f9bb8a Mon Sep 17 00:00:00 2001 From: fredericrous Date: Sat, 18 Apr 2020 22:05:36 +0100 Subject: [PATCH 074/878] Add Calculator App Readme --- apps/calculator/README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 apps/calculator/README.md diff --git a/apps/calculator/README.md b/apps/calculator/README.md new file mode 100644 index 000000000..78848908a --- /dev/null +++ b/apps/calculator/README.md @@ -0,0 +1,23 @@ +# Calculator + +Basic calculator reminiscent of MacOs's one. Handy for small calculus. + + + +## Features + +- add / substract / divide / multiply +- handles floats +- basic memory button + +## Controls + +- UP: BTN1 +- DOWN: BTN3 +- LEFT: BTN4 +- RIGHT: BTN5 +- SELECT: BTN2 + +## Creator + + From 0df1fb19e3d45f92ed5e490c11a59017df9d27eb Mon Sep 17 00:00:00 2001 From: Michael Bengfort Date: Sun, 19 Apr 2020 13:55:20 +0200 Subject: [PATCH 075/878] initial commit adding metronome app --- apps.json | 20 +++++++ apps/metronome/README.md | 10 ++++ apps/metronome/metronome-icon.js | 1 + apps/metronome/metronome.info | 1 + apps/metronome/metronome.js | 93 ++++++++++++++++++++++++++++++ apps/metronome/metronome_icon.png | Bin 0 -> 7575 bytes 6 files changed, 125 insertions(+) create mode 100644 apps/metronome/README.md create mode 100644 apps/metronome/metronome-icon.js create mode 100644 apps/metronome/metronome.info create mode 100644 apps/metronome/metronome.js create mode 100644 apps/metronome/metronome_icon.png diff --git a/apps.json b/apps.json index 0c97b9e57..590a85e38 100644 --- a/apps.json +++ b/apps.json @@ -1293,5 +1293,25 @@ "evaluate": true } ] + }, + { + "id": "Metronome", + "name": "Metronome", + "icon": "metronome_icon.png", + "version": "0.03", + "description": "Makes the watch blinking and vibrating with a given rate", + "tags": "tool", + "allow_emulator": true, + "storage": [ + { + "name": "metronome.app.js", + "url": "metronome.js" + }, + { + "name": "metronome.img", + "url": "metronome-icon.js", + "evaluate": true + } + ] } ] diff --git a/apps/metronome/README.md b/apps/metronome/README.md new file mode 100644 index 000000000..19d489327 --- /dev/null +++ b/apps/metronome/README.md @@ -0,0 +1,10 @@ +# Metronome + +This metronome makes your watch blink and vibrate with a given rate. + +## Usage + +* Tap the screen at least three times. The app calculates the mean rate of your tapping. This rate is displayed in bmp while the text blinks and the watch softly vibrates with every beat. +* Use `BTN1` to increase the bmp value by one. +* Use `BTN3` to decrease the bmp value by one. +* You can change the bpm value any time by tapping the screen or using `BTN1` and `BTN3`. diff --git a/apps/metronome/metronome-icon.js b/apps/metronome/metronome-icon.js new file mode 100644 index 000000000..8b45f233b --- /dev/null +++ b/apps/metronome/metronome-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+ABt4AB4fOFyFOABtUGDotOAAYvcp4ARqovbq0rACAvbqwABF98yGCAvdGAcHgAAEF8tWmIuGGA6QaF4lWFw4vgFwovPmIvuYDIvd0ejF59cF6qQFFwIvnMAguSqxfaFyQvYvOi0QuTF64uCAAQuRXwIvUqouEF6guFF5+cAAiOZF6iOaF5sxv+iF6xfRmVWFwWjv8rp4tSL6YvBqwuDMgQvnFwovURwIvQRggAELygvPgwuIF8ouEBwIvnFwwwXF54uBvwuFq0yF6buCF5guClQuFGAgvfFwcAF49WmIvRFwQvKFwkAmQvHYQMxF7l+FwgvKGAIvalQuGF5dWFx1VABVUvF4p0qAAdPCZNPF51OAD4vOKQIACF/4waF9wuEqgv/F/gwMF97vvAAUqADYtQAAMAADYuRGDgmLA=")) diff --git a/apps/metronome/metronome.info b/apps/metronome/metronome.info new file mode 100644 index 000000000..74dcbd2c7 --- /dev/null +++ b/apps/metronome/metronome.info @@ -0,0 +1 @@ +{"id":"metronome","name":"Metronome","src":"metronome.app.js", "icon": "metronome_icon.png", "sortorder":-2,"version":"0.03","files":"metronome.info,metronome.app.js, metronome_icon.png"} diff --git a/apps/metronome/metronome.js b/apps/metronome/metronome.js new file mode 100644 index 000000000..acd4b70b8 --- /dev/null +++ b/apps/metronome/metronome.js @@ -0,0 +1,93 @@ +var tStart = Date.now(); +var cindex=0; // index to iterate through colous +var bpm=60; // ininital bpm value +var time_diffs = [1000, 1000, 1000]; //array to calculate mean bpm +var tindex=0; //index to iterate through time_diffs + +Bangle.setLCDTimeout(undefined); //do not deaktivate display while running this app + +function changecolor() { + const maxColors = 2; + const colors = { + 0: { value: 0xFFFF, name: "White" }, + 1: { value: 0x000F, name: "Navy" }, + // 2: { value: 0x03E0, name: "DarkGreen" }, + // 3: { value: 0x03EF, name: "DarkCyan" }, + // 4: { value: 0x7800, name: "Maroon" }, + // 5: { value: 0x780F, name: "Purple" }, + // 6: { value: 0x7BE0, name: "Olive" }, + // 7: { value: 0xC618, name: "LightGray" }, + // 8: { value: 0x7BEF, name: "DarkGrey" }, + // 9: { value: 0x001F, name: "Blue" }, + // 10: { value: 0x07E0, name: "Green" }, + // 11: { value: 0x07FF, name: "Cyan" }, + // 12: { value: 0xF800, name: "Red" }, + // 13: { value: 0xF81F, name: "Magenta" }, + // 14: { value: 0xFFE0, name: "Yellow" }, + // 15: { value: 0xFFFF, name: "White" }, + // 16: { value: 0xFD20, name: "Orange" }, + // 17: { value: 0xAFE5, name: "GreenYellow" }, + // 18: { value: 0xF81F, name: "Pink" }, + }; + g.setColor(colors[cindex].value); + if (cindex == maxColors-1) { + cindex = 0; + } + else { + cindex += 1; + } + return cindex; +} + +function updateScreen() { + g.clear(); + changecolor(); + Bangle.buzz(50, 0.75); + g.setFont("Vector",48); + g.drawString(Math.floor(bpm)+"bpm", -1, 70); +} + +Bangle.on('touch', function(button) { +// setting bpm by tapping the screen. Uses the mean time difference between several tappings. + if (tindex < time_diffs.length) { + if (Date.now()-tStart < 5000) { + time_diffs[tindex] = Date.now()-tStart; + } + } else { + tindex=0; + time_diffs[tindex] = Date.now()-tStart; + } + tindex += 1; + mean_time = 0.0; + for(count = 0; count < time_diffs.length; count++) { + mean_time += time_diffs[count]; + } + time_diff = mean_time/count; + + tStart = Date.now(); + clearInterval(time_diff); + g.clear(); + g.setFont("Vector",48); + bpm = (60 * 1000/(time_diff)); + g.drawString(Math.floor(bpm)+"bpm", -1, 70); + clearInterval(interval); + interval = setInterval(updateScreen, 60000 / bpm); + return bpm; +}); + +// enable bpm finetuning via buttons. +setWatch(() => { + bpm += 1; + clearInterval(interval); + interval = setInterval(updateScreen, 60000 / bpm); +}, BTN1, {repeat:true}); + +setWatch(() => { + if (bpm > 1) { + bpm -= 1; + clearInterval(interval); + interval = setInterval(updateScreen, 60000 / bpm); + } +}, BTN3, {repeat:true}); + +interval = setInterval(updateScreen, 60000 / bpm); diff --git a/apps/metronome/metronome_icon.png b/apps/metronome/metronome_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4dac7117f9e91221b0cfec54538e339c81df1939 GIT binary patch literal 7575 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 literal 0 HcmV?d00001 From 28dc51c377cb8b1c692df97f5f0bbc741b16ed7d Mon Sep 17 00:00:00 2001 From: Michael Bengfort Date: Sun, 19 Apr 2020 14:03:11 +0200 Subject: [PATCH 076/878] correct app path --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 590a85e38..83c0ba88f 100644 --- a/apps.json +++ b/apps.json @@ -1295,7 +1295,7 @@ ] }, { - "id": "Metronome", + "id": "metronome", "name": "Metronome", "icon": "metronome_icon.png", "version": "0.03", From 0bdf476ea6fe78aafaaf5318d92ac7f0fe8b5b60 Mon Sep 17 00:00:00 2001 From: Michael Bengfort Date: Sun, 19 Apr 2020 14:13:26 +0200 Subject: [PATCH 077/878] remove metronome.info --- apps/metronome/metronome.info | 1 - 1 file changed, 1 deletion(-) delete mode 100644 apps/metronome/metronome.info diff --git a/apps/metronome/metronome.info b/apps/metronome/metronome.info deleted file mode 100644 index 74dcbd2c7..000000000 --- a/apps/metronome/metronome.info +++ /dev/null @@ -1 +0,0 @@ -{"id":"metronome","name":"Metronome","src":"metronome.app.js", "icon": "metronome_icon.png", "sortorder":-2,"version":"0.03","files":"metronome.info,metronome.app.js, metronome_icon.png"} From 1596b0246b9693bdf7fd26a04417e49aa61dfb9d Mon Sep 17 00:00:00 2001 From: Amos Blanton Date: Sun, 19 Apr 2020 16:18:13 +0200 Subject: [PATCH 078/878] Add setting to hide widget when battery is over 20%. --- apps/widbatpc/{settings.js => widbatpc.settings.js} | 12 +++++++++--- apps/widbatpc/widbatpc.settings.json | 1 + apps/widbatpc/{widget.js => widbatpc.wid.js} | 13 ++++++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) rename apps/widbatpc/{settings.js => widbatpc.settings.js} (88%) create mode 100644 apps/widbatpc/widbatpc.settings.json rename apps/widbatpc/{widget.js => widbatpc.wid.js} (95%) diff --git a/apps/widbatpc/settings.js b/apps/widbatpc/widbatpc.settings.js similarity index 88% rename from apps/widbatpc/settings.js rename to apps/widbatpc/widbatpc.settings.js index 5c0bdbcae..9f39b5d07 100644 --- a/apps/widbatpc/settings.js +++ b/apps/widbatpc/widbatpc.settings.js @@ -11,6 +11,7 @@ 'color': COLORS[0], 'percentage': true, 'charger': true, + 'hideifmorethan20pct': false, } // ...and overwrite them with any saved values // This way saved values are preserved if a new version adds more settings @@ -51,8 +52,13 @@ const newIndex = (oldIndex + 1) % COLORS.length s.color = COLORS[newIndex] save('color')(s.color) - }, - }, - } + } + }, + 'Hide when \> 20\%': { + value: s.hideifmorethan20pct, + format: onOffFormat, + onchange: save('hideifmorethan20pct'), + }, + } E.showMenu(menu) }) diff --git a/apps/widbatpc/widbatpc.settings.json b/apps/widbatpc/widbatpc.settings.json new file mode 100644 index 000000000..7a22adfc0 --- /dev/null +++ b/apps/widbatpc/widbatpc.settings.json @@ -0,0 +1 @@ +{"color":"By Level","percentage":true,"charger":true,"hideifmorethan20pct":false} diff --git a/apps/widbatpc/widget.js b/apps/widbatpc/widbatpc.wid.js similarity index 95% rename from apps/widbatpc/widget.js rename to apps/widbatpc/widbatpc.wid.js index aca690ce0..959ec211f 100644 --- a/apps/widbatpc/widget.js +++ b/apps/widbatpc/widbatpc.wid.js @@ -3,6 +3,7 @@ const DEFAULTS = { 'color': 'By Level', 'percentage': true, 'charger': true, + 'hideifmorethan20pct': false, } const COLORS = { 'white': -1, @@ -53,8 +54,16 @@ function setWidth() { } } function draw() { + var s = 39; var x = this.x, y = this.y; + const l = E.getBattery(), + c = levelColor(l); + const xl = x+4+l*(s-12)/100 + + if(!Bangle.isCharging() && setting('hideifmorethan20pct') && l > 20){ + return;} + if (Bangle.isCharging() && setting('charger')) { g.setColor(chargerColor()).drawImage(atob( "DhgBHOBzgc4HOP////////////////////3/4HgB4AeAHgB4AeAHgB4AeAHg"),x,y); @@ -64,9 +73,7 @@ function draw() { g.fillRect(x,y+2,x+s-4,y+21); g.clearRect(x+2,y+4,x+s-6,y+19); g.fillRect(x+s-3,y+10,x+s,y+14); - const l = E.getBattery(), - c = levelColor(l); - const xl = x+4+l*(s-12)/100 + g.setColor(c).fillRect(x+4,y+6,xl,y+17); g.setColor(-1); if (!setting('percentage')) { From d2270eaae6565a322895e25afb3c638a26c2b186 Mon Sep 17 00:00:00 2001 From: Frederic R Date: Sun, 19 Apr 2020 16:48:33 +0100 Subject: [PATCH 079/878] Update App Calculator's Readme. Larger image --- apps/calculator/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/calculator/README.md b/apps/calculator/README.md index 78848908a..b25d355bf 100644 --- a/apps/calculator/README.md +++ b/apps/calculator/README.md @@ -2,7 +2,7 @@ Basic calculator reminiscent of MacOs's one. Handy for small calculus. - + ## Features From 4d52de224ceddc49aabc107bf246374da8393106 Mon Sep 17 00:00:00 2001 From: Stefano Baldan Date: Sun, 19 Apr 2020 18:03:14 +0200 Subject: [PATCH 080/878] Added app for running --- apps.json | 21 +++ apps/banglerun/ChangeLog | 1 + apps/banglerun/app-icon.js | 1 + apps/banglerun/app.js | 314 +++++++++++++++++++++++++++++++++++ apps/banglerun/banglerun.png | Bin 0 -> 10456 bytes 5 files changed, 337 insertions(+) create mode 100755 apps/banglerun/ChangeLog create mode 100644 apps/banglerun/app-icon.js create mode 100644 apps/banglerun/app.js create mode 100644 apps/banglerun/banglerun.png diff --git a/apps.json b/apps.json index 0c97b9e57..143b02bd3 100644 --- a/apps.json +++ b/apps.json @@ -1293,5 +1293,26 @@ "evaluate": true } ] + }, + { + "id": "banglerun", + "name": "BangleRun", + "shortName": "BangleRun", + "icon": "banglerun.png", + "version": "0.01", + "description": "An app for running sessions.", + "tags": "run,running,fitness,outdoors", + "allow_emulator": false, + "storage": [ + { + "name": "banglerun.app.js", + "url": "app.js" + }, + { + "name": "banglerun.img", + "url": "app-icon.js", + "evaluate": true + } + ] } ] diff --git a/apps/banglerun/ChangeLog b/apps/banglerun/ChangeLog new file mode 100755 index 000000000..7b83706bf --- /dev/null +++ b/apps/banglerun/ChangeLog @@ -0,0 +1 @@ +0.01: First release diff --git a/apps/banglerun/app-icon.js b/apps/banglerun/app-icon.js new file mode 100644 index 000000000..0ccbedab4 --- /dev/null +++ b/apps/banglerun/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwMB/4ACx4ED/0DApP8AqAXB84GDg/DAgXj/+DCAUABgIFB4EAv4FCwEAj0PAoJPBgwFEgEfDgMOAoM/AoMegFAAoP8jkA8F/AoM8gP4DgP4nBvD/F4KQfwuAFE+A/CAoPgAofx8A/CKYRwELIIFDLII6BAoZSBLIYeC/0BwAFDgfAGAQFBHgf8g4BBIIUH/wFBSYMPAoXwAog/Bj4FEv4FDDQQCBQoQFCZYYFi/6KE/+P/4A=")) diff --git a/apps/banglerun/app.js b/apps/banglerun/app.js new file mode 100644 index 000000000..fc21e3627 --- /dev/null +++ b/apps/banglerun/app.js @@ -0,0 +1,314 @@ +/** Global constants */ +const DEG_TO_RAD = Math.PI / 180; +const EARTH_RADIUS = 6371008.8; + +/** Utilities for handling vectors */ +class Vector { + static magnitude(a) { + let sum = 0; + for (const key of Object.keys(a)) { + sum += a[key] * a[key]; + } + return Math.sqrt(sum); + } + + static add(a, b) { + const result = {}; + for (const key of Object.keys(a)) { + result[key] = a[key] + b[key]; + } + return result; + } + + static sub(a, b) { + const result = {}; + for (const key of Object.keys(a)) { + result[key] = a[key] - b[key]; + } + return result; + } + + static multiplyScalar(a, x) { + const result = {}; + for (const key of Object.keys(a)) { + result[key] = a[key] * x; + } + return result; + } + + static divideScalar(a, x) { + const result = {}; + for (const key of Object.keys(a)) { + result[key] = a[key] / x; + } + return result; + } +} + +/** Interquartile range filter, to detect outliers */ +class IqrFilter { + constructor(size, threshold) { + const q = Math.floor(size / 4); + this._buffer = []; + this._size = 4 * q + 2; + this._i1 = q; + this._i3 = 3 * q + 1; + this._threshold = threshold; + } + + isReady() { + return this._buffer.length === this._size; + } + + isOutlier(point) { + let result = true; + if (this._buffer.length === this._size) { + result = false; + for (const key of Object.keys(point)) { + const data = this._buffer.map(item => item[key]); + data.sort((a, b) => (a - b) / Math.abs(a - b)); + const q1 = data[this._i1]; + const q3 = data[this._i3]; + const iqr = q3 - q1; + const lower = q1 - this._threshold * iqr; + const upper = q3 + this._threshold * iqr; + if (point[key] < lower || point[key] > upper) { + result = true; + break; + } + } + } + this._buffer.push(point); + this._buffer = this._buffer.slice(-this._size); + return result; + } +} + +/** Process GPS data */ +class Gps { + constructor() { + this._lastCall = Date.now(); + this._lastValid = 0; + this._coords = null; + this._filter = new IqrFilter(10, 1.5); + this._shift = { x: 0, y: 0, z: 0 }; + } + + isReady() { + return this._filter.isReady(); + } + + getDistance(gps) { + const time = Date.now(); + const interval = (time - this._lastCall) / 1000; + this._lastCall = time; + + if (!gps.fix) { + return { t: interval, d: 0 }; + } + + const p = gps.lat * DEG_TO_RAD; + const q = gps.lon * DEG_TO_RAD; + const coords = { + x: EARTH_RADIUS * Math.sin(p) * Math.cos(q), + y: EARTH_RADIUS * Math.sin(p) * Math.sin(q), + z: EARTH_RADIUS * Math.cos(p), + }; + + if (!this._coords) { + this._coords = coords; + this._lastValid = time; + return { t: interval, d: 0 }; + } + + const ds = Vector.sub(coords, this._coords); + const dt = (time - this._lastValid) / 1000; + const v = Vector.divideScalar(ds, dt); + + if (this._filter.isOutlier(v)) { + return { t: interval, d: 0 }; + } + + this._shift = Vector.add(this._shift, ds); + const length = Vector.magnitude(this._shift); + const remainder = length % 10; + const distance = length - remainder; + + this._coords = coords; + this._lastValid = time; + if (distance > 0) { + this._shift = Vector.multiplyScalar(this._shift, remainder / length); + } + + return { t: interval, d: distance }; + } +} + +/** Process step counter data */ +class Step { + constructor(size) { + this._buffer = []; + this._size = size; + } + + getCadence() { + this._buffer.push(Date.now() / 1000); + this._buffer = this._buffer.slice(-this._size); + const interval = this._buffer[this._buffer.length - 1] - this._buffer[0]; + return interval ? Math.round(60 * (this._buffer.length - 1) / interval) : 0; + } +} + +const gps = new Gps(); +const step = new Step(10); + +let totDist = 0; +let totTime = 0; +let totSteps = 0; + +let speed = 0; +let cadence = 0; +let heartRate = 0; + +let gpsReady = false; +let hrmReady = false; +let running = false; + +function formatClock(date) { + return ('0' + date.getHours()).substr(-2) + ':' + ('0' + date.getMinutes()).substr(-2); +} + +function formatDistance(m) { + return ('0' + (m / 1000).toFixed(2) + ' km').substr(-7); +} + +function formatTime(s) { + const hrs = Math.floor(s / 3600); + const min = Math.floor(s / 60); + const sec = Math.floor(s % 60); + return (hrs ? hrs + ':' : '') + ('0' + min).substr(-2) + `:` + ('0' + sec).substr(-2); +} + +function formatSpeed(kmh) { + if (kmh <= 0.6) { + return `__'__"`; + } + const skm = 3600 / kmh; + const min = Math.floor(skm / 60); + const sec = Math.floor(skm % 60); + return ('0' + min).substr(-2) + `'` + ('0' + sec).substr(-2) + `"`; +} + +function drawBackground() { + g.setColor(running ? 0x00E0 : 0x0000); + g.fillRect(0, 30, 240, 240); + + g.setColor(0xFFFF); + g.setFontAlign(0, -1, 0); + g.setFont('6x8', 2); + + g.drawString('DISTANCE', 120, 50); + g.drawString('TIME', 60, 100); + g.drawString('PACE', 180, 100); + g.drawString('STEPS', 60, 150); + g.drawString('STP/m', 180, 150); + g.drawString('SPEED', 40, 200); + g.drawString('HEART', 120, 200); + g.drawString('CADENCE', 200, 200); +} + +function draw() { + const totSpeed = totTime ? 3.6 * totDist / totTime : 0; + const totCadence = totTime ? Math.round(60 * totSteps / totTime) : 0; + + g.setColor(running ? 0x00E0 : 0x0000); + g.fillRect(0, 30, 240, 50); + g.fillRect(0, 70, 240, 100); + g.fillRect(0, 120, 240, 150); + g.fillRect(0, 170, 240, 200); + g.fillRect(0, 220, 240, 240); + + g.setFont('6x8', 2); + + g.setFontAlign(-1, -1, 0); + g.setColor(gpsReady ? 0x07E0 : 0xF800); + g.drawString(' GPS', 6, 30); + + g.setFontAlign(1, -1, 0); + g.setColor(0xFFFF); + g.drawString(formatClock(new Date()), 234, 30); + + g.setFontAlign(0, -1, 0); + g.setFontVector(20); + g.drawString(formatDistance(totDist), 120, 70); + g.drawString(formatTime(totTime), 60, 120); + g.drawString(formatSpeed(totSpeed), 180, 120); + g.drawString(totSteps, 60, 170); + g.drawString(totCadence, 180, 170); + + g.setFont('6x8', 2); + g.drawString(formatSpeed(speed), 40, 220); + + g.setColor(hrmReady ? 0x07E0 : 0xF800); + g.drawString(heartRate, 120, 220); + + g.setColor(0xFFFF); + g.drawString(cadence, 200, 220); +} + +function handleGps(coords) { + const step = gps.getDistance(coords); + gpsReady = coords.fix > 0 && gps.isReady(); + speed = isFinite(gps.speed) ? gps.speed : 0; + if (running) { + totDist += step.d; + totTime += step.t; + } +} + +function handleHrm(hrm) { + hrmReady = hrm.confidence > 50; + heartRate = hrm.bpm; +} + +function handleStep() { + cadence = step.getCadence(); + if (running) { + totSteps += 1; + } +} + +function start() { + running = true; + drawBackground(); + draw(); +} + +function stop() { + if (!running) { + totDist = 0; + totTime = 0; + totSteps = 0; + } + running = false; + drawBackground(); + draw(); +} + +Bangle.on('GPS', handleGps); +Bangle.on('HRM', handleHrm); +Bangle.on('step', handleStep); + +Bangle.setGPSPower(1); +Bangle.setHRMPower(1); + +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +drawBackground(); +draw(); + +setInterval(draw, 500); + +setWatch(start, BTN1, { repeat: true }); +setWatch(stop, BTN3, { repeat: true }); diff --git a/apps/banglerun/banglerun.png b/apps/banglerun/banglerun.png new file mode 100644 index 0000000000000000000000000000000000000000..bf2cd8af3ef5f9711d18df1656a03a98283bcc67 GIT binary patch literal 10456 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 O0000 Date: Mon, 20 Apr 2020 09:27:57 +0200 Subject: [PATCH 081/878] Removed href="#" that scrolls page on top --- js/index.js | 2 +- js/utils.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/index.js b/js/index.js index ef9bcb4f1..d8c7a4473 100644 --- a/js/index.js +++ b/js/index.js @@ -207,7 +207,7 @@ function refreshLibrary() { var version = getVersionInfo(app, appInstalled); var versionInfo = version.text; if (versionInfo) versionInfo = " ("+versionInfo+")"; - var readme = `Read more...`; + var readme = `Read more...`; var favourite = favourites.find(e => e == app.id); return `
diff --git a/js/utils.js b/js/utils.js index 4913c7129..406e3a0a1 100644 --- a/js/utils.js +++ b/js/utils.js @@ -49,7 +49,7 @@ function getVersionInfo(appListing, appInstalled) { var versionText = ""; var canUpdate = false; function clicky(v) { - return `${v}`; + return `${v}`; } if (!appInstalled) { From 9cc58597cd5d0934f34da6a935b2187cb1b3df36 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 20 Apr 2020 09:21:27 +0100 Subject: [PATCH 082/878] merge with new namings --- apps/widbatpc/{widbatpc.settings.js => settings.js} | 0 apps/widbatpc/{widbatpc.wid.js => widget.js} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename apps/widbatpc/{widbatpc.settings.js => settings.js} (100%) rename apps/widbatpc/{widbatpc.wid.js => widget.js} (100%) diff --git a/apps/widbatpc/widbatpc.settings.js b/apps/widbatpc/settings.js similarity index 100% rename from apps/widbatpc/widbatpc.settings.js rename to apps/widbatpc/settings.js diff --git a/apps/widbatpc/widbatpc.wid.js b/apps/widbatpc/widget.js similarity index 100% rename from apps/widbatpc/widbatpc.wid.js rename to apps/widbatpc/widget.js From 20bb1aed8456dcfc6028d77400970e45ebf6c2db Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 20 Apr 2020 10:06:23 +0100 Subject: [PATCH 083/878] Add 'hide if charge greater than' Move 'DEFAULTS' to try and reduce memory usage a little --- apps.json | 4 +-- apps/widbatpc/ChangeLog | 1 + apps/widbatpc/settings.js | 23 +++++++------ apps/widbatpc/widbatpc.settings.json | 1 - apps/widbatpc/widget.js | 50 +++++++++++++++++----------- 5 files changed, 46 insertions(+), 33 deletions(-) delete mode 100644 apps/widbatpc/widbatpc.settings.json diff --git a/apps.json b/apps.json index fe3d5f3eb..5b024eb97 100644 --- a/apps.json +++ b/apps.json @@ -354,7 +354,7 @@ "name": "Battery Level Widget (with percentage)", "shortName": "Battery Widget", "icon": "widget.png", - "version":"0.09", + "version":"0.10", "description": "Show the current battery level and charging status in the top right of the clock, with charge percentage", "tags": "widget,battery", "type":"widget", @@ -1372,7 +1372,7 @@ {"name":"hidcam.img","url":"app-icon.js","evaluate":true} ] }, - { + { "id": "rclock", "name": "Round clock with seconds, minutes and date", "shortName":"Round Clock", diff --git a/apps/widbatpc/ChangeLog b/apps/widbatpc/ChangeLog index 129707320..4c5f16a04 100644 --- a/apps/widbatpc/ChangeLog +++ b/apps/widbatpc/ChangeLog @@ -6,3 +6,4 @@ 0.07: Add settings: percentage/color/charger icon 0.08: Draw percentage as inverted on monochrome battery 0.09: Fix regression stopping correct widget updates +0.10: Add 'hide if charge greater than' diff --git a/apps/widbatpc/settings.js b/apps/widbatpc/settings.js index 9f39b5d07..bfed48f09 100644 --- a/apps/widbatpc/settings.js +++ b/apps/widbatpc/settings.js @@ -11,22 +11,22 @@ 'color': COLORS[0], 'percentage': true, 'charger': true, - 'hideifmorethan20pct': false, + 'hideifmorethan': 100, } // ...and overwrite them with any saved values // This way saved values are preserved if a new version adds more settings const storage = require('Storage') const saved = storage.readJSON(SETTINGS_FILE, 1) || {} for (const key in saved) { - s[key] = saved[key] + s[key] = saved[key]; } // creates a function to safe a specific setting, e.g. save('color')(1) function save(key) { return function (value) { - s[key] = value - storage.write(SETTINGS_FILE, s) - WIDGETS["batpc"].reload() + s[key] = value; + storage.write(SETTINGS_FILE, s); + WIDGETS["batpc"].reload(); } } @@ -54,11 +54,14 @@ save('color')(s.color) } }, - 'Hide when \> 20\%': { - value: s.hideifmorethan20pct, - format: onOffFormat, - onchange: save('hideifmorethan20pct'), + 'Hide if >': { + value: s.hideifmorethan||100, + min: 10, + max : 100, + step: 10, + format: x => x+"%", + onchange: save('hideifmorethan'), }, - } + } E.showMenu(menu) }) diff --git a/apps/widbatpc/widbatpc.settings.json b/apps/widbatpc/widbatpc.settings.json deleted file mode 100644 index 7a22adfc0..000000000 --- a/apps/widbatpc/widbatpc.settings.json +++ /dev/null @@ -1 +0,0 @@ -{"color":"By Level","percentage":true,"charger":true,"hideifmorethan20pct":false} diff --git a/apps/widbatpc/widget.js b/apps/widbatpc/widget.js index 959ec211f..fe6f8550c 100644 --- a/apps/widbatpc/widget.js +++ b/apps/widbatpc/widget.js @@ -1,10 +1,4 @@ (function(){ -const DEFAULTS = { - 'color': 'By Level', - 'percentage': true, - 'charger': true, - 'hideifmorethan20pct': false, -} const COLORS = { 'white': -1, 'charging': 0x07E0, // "Green" @@ -17,10 +11,19 @@ const SETTINGS_FILE = 'widbatpc.settings.json' let settings function loadSettings() { settings = require('Storage').readJSON(SETTINGS_FILE, 1) || {} + const DEFAULTS = { + 'color': 'By Level', + 'percentage': true, + 'charger': true, + 'hideifmorethan': 100, + }; + Object.keys(DEFAULTS).forEach(k=>{ + if (settings[k]===undefined) settings[k]=DEFAULTS[k] + }); } function setting(key) { if (!settings) { loadSettings() } - return (key in settings) ? settings[key] : DEFAULTS[key] + return settings[key]; } const levelColor = (l) => { @@ -46,24 +49,27 @@ const levelColor = (l) => { const chargerColor = () => { return (setting('color') === 'Monochrome') ? COLORS.white : COLORS.charging } - +// sets width, returns true if it changed function setWidth() { - WIDGETS["batpc"].width = 40; - if (Bangle.isCharging() && setting('charger')) { - WIDGETS["batpc"].width += 16; - } + var w = 40; + if (Bangle.isCharging() && setting('charger')) + w += 16; + if (E.getBattery() > setting('hideifmorethan')) + w = 0; + var changed = WIDGETS["batpc"].width != w; + WIDGETS["batpc"].width = w; + return changed; } function draw() { - + // if hidden, don't draw + if (!WIDGETS["batpc"].width) return; + // else... var s = 39; var x = this.x, y = this.y; const l = E.getBattery(), c = levelColor(l); const xl = x+4+l*(s-12)/100 - if(!Bangle.isCharging() && setting('hideifmorethan20pct') && l > 20){ - return;} - if (Bangle.isCharging() && setting('charger')) { g.setColor(chargerColor()).drawImage(atob( "DhgBHOBzgc4HOP////////////////////3/4HgB4AeAHgB4AeAHgB4AeAHg"),x,y); @@ -104,20 +110,24 @@ function reload() { g.clear(); Bangle.drawWidgets(); } +// update widget - redraw just widget, or all widgets if size changed +function update() { + if (setWidth()) Bangle.drawWidgets(); + else WIDGETS["batpc"].draw(); +} Bangle.on('charging',function(charging) { if(charging) Bangle.buzz(); - setWidth(); - Bangle.drawWidgets(); // relayout widgets + update(); g.flip(); }); var batteryInterval; Bangle.on('lcdPower', function(on) { if (on) { - WIDGETS["batpc"].draw(); + update(); // refresh once a minute if LCD on if (!batteryInterval) - batteryInterval = setInterval(()=>WIDGETS["batpc"].draw(), 60000); + batteryInterval = setInterval(update, 60000); } else { if (batteryInterval) { clearInterval(batteryInterval); From 5fe7f48477818c1bb31b7650e9d93f45d594f7e0 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 20 Apr 2020 10:07:55 +0100 Subject: [PATCH 084/878] Add 'update all' button (fix #237) --- index.html | 1 + js/index.js | 42 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index f016ffb49..3c8b440e4 100644 --- a/index.html +++ b/index.html @@ -113,6 +113,7 @@
+
diff --git a/js/index.js b/js/index.js index 2b1fb1cfc..51b1d71c3 100644 --- a/js/index.js +++ b/js/index.js @@ -218,7 +218,7 @@ function refreshLibrary() {

${escapeHtml(app.description)}${app.readme?`
${readme}`:""}

See the code on GitHub
-
+
@@ -401,10 +401,18 @@ function showLoadingIndicator(id) { panelbody.innerHTML = '
'; } +function getAppsToUpdate() { + var appsToUpdate = []; + appsInstalled.forEach(appInstalled => { + var app = appNameToApp(appInstalled.id); + if (app.version != appInstalled.version) + appsToUpdate.push(app); + }); + return appsToUpdate; +} + function refreshMyApps() { var panelbody = document.querySelector("#myappscontainer .panel-body"); - var tab = document.querySelector("#tab-myappscontainer a"); - tab.setAttribute("data-badge", appsInstalled.length); panelbody.innerHTML = appsInstalled.map(appInstalled => { var app = appNameToApp(appInstalled.id); var version = getVersionInfo(app, appInstalled); @@ -436,6 +444,17 @@ return `
if (icon.classList.contains("icon-download")) handleAppInterface(app); }); }); + var appsToUpdate = getAppsToUpdate(); + var tab = document.querySelector("#tab-myappscontainer a"); + var updateApps = document.querySelector("#myappscontainer .updateapps"); + if (appsToUpdate.length) { + updateApps.innerHTML = `Update ${appsToUpdate.length} apps`; + updateApps.classList.remove("hidden"); + tab.setAttribute("data-badge", `${appsInstalled.length} ⬆${appsToUpdate.length}`); + } else { + updateApps.classList.add("hidden"); + tab.setAttribute("data-badge", appsInstalled.length); + } } let haveInstalledApps = false; @@ -471,6 +490,22 @@ htmlToArray(document.querySelectorAll(".btn.refresh")).map(button => button.addE showToast("Getting app list failed, "+err,"error"); }); })); +htmlToArray(document.querySelectorAll(".btn.updateapps")).map(button => button.addEventListener("click", () => { + var appsToUpdate = getAppsToUpdate(); + var count = appsToUpdate.length; + function updater() { + if (!appsToUpdate.length) return; + var app = appsToUpdate.pop(); + return updateApp(app).then(function() { + return updater(); + }); + } + updater().then(err => { + showToast(`Updated ${count} apps`,"success"); + }).catch(err => { + showToast("Update failed, "+err,"error"); + }); +})); connectMyDeviceBtn.addEventListener("click", () => { if (connectMyDeviceBtn.classList.contains('is-connected')) { Comms.disconnectDevice(); @@ -621,4 +656,3 @@ document.getElementById("installfavourite").addEventListener("click",event=>{ showToast("App Install failed, "+err,"error"); }); }); - From 0f8247e7e49f3b976e96dea0626a3369ea2a9456 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Mon, 20 Apr 2020 11:52:19 +0200 Subject: [PATCH 085/878] Data file fixes for settings/welcome/ncstart settings: never delete settings file welcome: fix typo, remove outdated comment ncstart: remove outdated comment --- apps.json | 3 --- apps/ncstart/settings.js | 1 - apps/welcome/settings.js | 3 +-- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/apps.json b/apps.json index a18029abc..32a7e7dff 100644 --- a/apps.json +++ b/apps.json @@ -130,9 +130,6 @@ {"name":"setting.boot.js","url":"boot.js"}, {"name":"setting.img","url":"settings-icon.js","evaluate":true} ], - "data": [ - {"name":"setting.json"} - ], "sortorder" : -2 }, { "id": "alarm", diff --git a/apps/ncstart/settings.js b/apps/ncstart/settings.js index 6780264a7..560fad8ba 100644 --- a/apps/ncstart/settings.js +++ b/apps/ncstart/settings.js @@ -1,4 +1,3 @@ -// The welcome app is special, and gets to use global settings (function(back) { let settings = require('Storage').readJSON('ncstart.json', 1) || require('Storage').readJSON('setting.json', 1) || {} diff --git a/apps/welcome/settings.js b/apps/welcome/settings.js index e873c2785..20c2e9b13 100644 --- a/apps/welcome/settings.js +++ b/apps/welcome/settings.js @@ -1,6 +1,5 @@ -// The welcome app is special, and gets to use global settings (function(back) { - let settings = require('Storage').readJSON('welcome.sjson', 1) + let settings = require('Storage').readJSON('welcome.json', 1) || require('Storage').readJSON('setting.json', 1) || {} E.showMenu({ '': { 'title': 'Welcome App' }, From ae738e9d99b9f54f20b230ea23a5e0ad043b7471 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 20 Apr 2020 15:57:26 +0200 Subject: [PATCH 086/878] chronowid 0.03 --- apps/chronowid/ChangeLog | 5 +- apps/chronowid/widget.js | 184 +++++++++++++++++++-------------------- 2 files changed, 95 insertions(+), 94 deletions(-) diff --git a/apps/chronowid/ChangeLog b/apps/chronowid/ChangeLog index 263145407..e173467a1 100644 --- a/apps/chronowid/ChangeLog +++ b/apps/chronowid/ChangeLog @@ -1,2 +1,3 @@ -0.01: New widget and app! -0.02: Setting to reset values, timer buzzes at 00:00 and not later (see readme) \ No newline at end of file +0.01: New widget and app! +0.02: Setting to reset values, timer buzzes at 00:00 and not later (see readme) +0.03: Display only minutes:seconds when less than 1 hour left \ No newline at end of file diff --git a/apps/chronowid/widget.js b/apps/chronowid/widget.js index 557104d92..0c9366b86 100644 --- a/apps/chronowid/widget.js +++ b/apps/chronowid/widget.js @@ -1,93 +1,93 @@ -(() => { - const storage = require('Storage'); - settingsChronowid = storage.readJSON("chronowid.json",1)||{}; //read settingsChronowid from file - var height = 23; - var width = 58; - var interval = 0; //used for the 1 second interval timer - var now = new Date(); - - var time = 0; - var diff = settingsChronowid.goal - now; - - //Convert ms to time - function getTime(t) { - var milliseconds = parseInt((t % 1000) / 100), - seconds = Math.floor((t / 1000) % 60), - minutes = Math.floor((t / (1000 * 60)) % 60), - hours = Math.floor((t / (1000 * 60 * 60)) % 24); - - hours = (hours < 10) ? "0" + hours : hours; - minutes = (minutes < 10) ? "0" + minutes : minutes; - seconds = (seconds < 10) ? "0" + seconds : seconds; - - return hours + ":" + minutes + ":" + seconds; - } - - function printDebug() { - print ("Nowtime: " + getTime(now)); - print ("Now: " + now); - print ("Goaltime: " + getTime(settingsChronowid.goal)); - print ("Goal: " + settingsChronowid.goal); - print("Difftime: " + getTime(diff)); - print("Diff: " + diff); - print ("Started: " + settingsChronowid.started); - print ("----"); - } - - //counts down, calculates and displays - function countDown() { - now = new Date(); - diff = settingsChronowid.goal - now; //calculate difference - WIDGETS["chronowid"].draw(); - //time is up - if (settingsChronowid.started && diff < 1000) { - Bangle.buzz(1500); - //write timer off to file - settingsChronowid.started = false; - storage.writeJSON('chronowid.json', settingsChronowid); - clearInterval(interval); //stop interval - } - //printDebug(); - } - - // draw your widget - function draw() { - if (!settingsChronowid.started) { - width = 0; - return; //do not draw anything if timer is not started - } - g.reset(); - if (diff >= 0) { - if (diff < 600000) { //less than 1 hour left - width = 58; - g.clearRect(this.x,this.y,this.x+width,this.y+height); - g.setFont("6x8", 2); - g.drawString(getTime(diff).substring(3), this.x+1, this.y+5); //remove hour part 00:00:00 -> 00:00 - } - if (diff >= 600000) { //one hour or more left - width = 48; - g.clearRect(this.x,this.y,this.x+width,this.y+height); - g.setFont("6x8", 1); - g.drawString(getTime(diff), this.x+1, this.y+((height/2)-4)); //display hour 00:00:00 - } - } - // not needed anymoe, because we check if diff < 1000 now, so 00:00 is displayed. - // else { - // width = 58; - // g.clearRect(this.x,this.y,this.x+width,this.y+height); - // g.setFont("6x8", 2); - // g.drawString("END", this.x+15, this.y+5); - // } - } - - if (settingsChronowid.started) interval = setInterval(countDown, 1000); //start countdown each second - - // add the widget - WIDGETS["chronowid"]={area:"bl",width:width,draw:draw,reload:function() { - reload(); - Bangle.drawWidgets(); // relayout all widgets - }}; - - //printDebug(); - countDown(); +(() => { + const storage = require('Storage'); + settingsChronowid = storage.readJSON("chronowid.json",1)||{}; //read settingsChronowid from file + var height = 23; + var width = 58; + var interval = 0; //used for the 1 second interval timer + var now = new Date(); + + var time = 0; + var diff = settingsChronowid.goal - now; + + //Convert ms to time + function getTime(t) { + var milliseconds = parseInt((t % 1000) / 100), + seconds = Math.floor((t / 1000) % 60), + minutes = Math.floor((t / (1000 * 60)) % 60), + hours = Math.floor((t / (1000 * 60 * 60)) % 24); + + hours = (hours < 10) ? "0" + hours : hours; + minutes = (minutes < 10) ? "0" + minutes : minutes; + seconds = (seconds < 10) ? "0" + seconds : seconds; + + return hours + ":" + minutes + ":" + seconds; + } + + function printDebug() { + print ("Nowtime: " + getTime(now)); + print ("Now: " + now); + print ("Goaltime: " + getTime(settingsChronowid.goal)); + print ("Goal: " + settingsChronowid.goal); + print("Difftime: " + getTime(diff)); + print("Diff: " + diff); + print ("Started: " + settingsChronowid.started); + print ("----"); + } + + //counts down, calculates and displays + function countDown() { + now = new Date(); + diff = settingsChronowid.goal - now; //calculate difference + WIDGETS["chronowid"].draw(); + //time is up + if (settingsChronowid.started && diff < 1000) { + Bangle.buzz(1500); + //write timer off to file + settingsChronowid.started = false; + storage.writeJSON('chronowid.json', settingsChronowid); + clearInterval(interval); //stop interval + } + //printDebug(); + } + + // draw your widget + function draw() { + if (!settingsChronowid.started) { + width = 0; + return; //do not draw anything if timer is not started + } + g.reset(); + if (diff >= 0) { + if (diff < 3600000) { //less than 1 hour left + width = 58; + g.clearRect(this.x,this.y,this.x+width,this.y+height); + g.setFont("6x8", 2); + g.drawString(getTime(diff).substring(3), this.x+1, this.y+5); //remove hour part 00:00:00 -> 00:00 + } + if (diff >= 3600000) { //one hour or more left + width = 48; + g.clearRect(this.x,this.y,this.x+width,this.y+height); + g.setFont("6x8", 1); + g.drawString(getTime(diff), this.x+1, this.y+((height/2)-4)); //display hour 00:00:00 + } + } + // not needed anymoe, because we check if diff < 1000 now, so 00:00 is displayed. + // else { + // width = 58; + // g.clearRect(this.x,this.y,this.x+width,this.y+height); + // g.setFont("6x8", 2); + // g.drawString("END", this.x+15, this.y+5); + // } + } + + if (settingsChronowid.started) interval = setInterval(countDown, 1000); //start countdown each second + + // add the widget + WIDGETS["chronowid"]={area:"bl",width:width,draw:draw,reload:function() { + reload(); + Bangle.drawWidgets(); // relayout all widgets + }}; + + //printDebug(); + countDown(); })(); \ No newline at end of file From af0ac4041cb772856b7c12ac6d3ada6f360a246e Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 20 Apr 2020 15:58:05 +0200 Subject: [PATCH 087/878] chronowid 0.03 --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index d7bd6a7a1..274a3a8b2 100644 --- a/apps.json +++ b/apps.json @@ -1142,7 +1142,7 @@ "name": "Chrono Widget", "shortName":"Chrono Widget", "icon": "app.png", - "version":"0.02", + "version":"0.03", "description": "Chronometer (timer) which runs as widget.", "tags": "tools,widget", "readme": "README.md", From 74bd784b091ad97964a7923fa888816fd8770412 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Mon, 20 Apr 2020 15:00:06 +0100 Subject: [PATCH 088/878] Initial commit of BuffGym 5x5 training program --- apps.json | 14 ++ apps/buffgym/.eslintrc.json | 33 ++++ apps/buffgym/buffgym-exercise.js | 187 +++++++++++++++++++ apps/buffgym/buffgym-icon.js | 1 + apps/buffgym/buffgym-program.js | 68 +++++++ apps/buffgym/buffgym-set.js | 46 +++++ apps/buffgym/buffgym.app.js | 311 +++++++++++++++++++++++++++++++ apps/buffgym/buffgym.png | Bin 0 -> 1800 bytes 8 files changed, 660 insertions(+) create mode 100644 apps/buffgym/.eslintrc.json create mode 100644 apps/buffgym/buffgym-exercise.js create mode 100644 apps/buffgym/buffgym-icon.js create mode 100644 apps/buffgym/buffgym-program.js create mode 100644 apps/buffgym/buffgym-set.js create mode 100755 apps/buffgym/buffgym.app.js create mode 100644 apps/buffgym/buffgym.png diff --git a/apps.json b/apps.json index 60b47dbd8..e993f0e18 100644 --- a/apps.json +++ b/apps.json @@ -1293,5 +1293,19 @@ "evaluate": true } ] + }, + { + "id": "buffgym", + "name": "BuffGym", + "icon": "buffgym.png", + "version":"0.01", + "description": "BuffGym is the famous 5x5 workout program for the BangleJS", + "tags": "tool,outdoors", + "type": "app", + "storage": [ + {"name":"buffgym"}, + {"name":"buffgym.app.js"}, + {"name":"buffgym.img","url":"buffgym-icon.js","evaluate":true} + ] } ] diff --git a/apps/buffgym/.eslintrc.json b/apps/buffgym/.eslintrc.json new file mode 100644 index 000000000..c91a72544 --- /dev/null +++ b/apps/buffgym/.eslintrc.json @@ -0,0 +1,33 @@ +{ + "env": { + "browser": true, + "commonjs": true, + "es6": true + }, + "extends": "eslint:recommended", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 2018 + }, + "rules": { + "indent": [ + "error", + 2 + ], + "linebreak-style": [ + "error", + "windows" + ], + "quotes": [ + "error", + "double" + ], + "semi": [ + "error", + "always" + ] + } +} \ No newline at end of file diff --git a/apps/buffgym/buffgym-exercise.js b/apps/buffgym/buffgym-exercise.js new file mode 100644 index 000000000..b7a1e3e15 --- /dev/null +++ b/apps/buffgym/buffgym-exercise.js @@ -0,0 +1,187 @@ +const STARTED = 1; +const RESTING = 2; +const COMPLETED = 3; +const ONE_SECOND = 1000; +const INCREMENT = "increment"; +const DECREMENT = "decrement"; + +class Exercise { + constructor(params /*{title, weight, unit, restPeriod}*/) { + const DEFAULTS = { + title: "Unknown", + weight: 0, + unit: "Kg", + restPeriod: 90, + weightIncrement: 2.5, + }; + const p = Object.assign({}, DEFAULTS, params); + + this._title = p.title; + this._weight = p.weight; + this._unit = p.unit; + this._originalRestPeriod = p.restPeriod; // Used when reseting _restPeriod + this._restPeriod = p.restPeriod; + this._weightIncrement = p.weightIncrement; + this._started = new Date(); + this._completed = false; + this._sets = []; + this._restTimeout = null; + this._restInterval = null; + this._state = null; + } + + get title() { + return this._title; + } + + get humanTitle() { + return `${this._title} ${this._weight}${this._unit}`; + } + + get subTitle() { + const totalSets = this._sets.length; + const uncompletedSets = this._sets.filter((set) => !set.isCompleted()).length; + const currentSet = (totalSets - uncompletedSets) + 1; + return `Set ${currentSet} of ${totalSets}`; + } + + get restPeriod() { + return this._restPeriod; + } + + decRestPeriod() { + this._restPeriod--; + } + + get weight() { + return this._weight; + } + + get unit() { + return this._unit; + } + + get started() { + return this._started; + } + + addSet(set) { + this._sets.push(set); + } + + addSets(sets) { + sets.forEach(set => this.addSet(set)); + } + + get currentSet() { + return this._sets.filter(set => !set.isCompleted())[0]; + } + + isLastSet() { + return this._sets.filter(set => !set.isCompleted()).length === 1; + } + + isCompleted() { + return !!this._completed; + } + + canSetCompleted() { + return this._sets.filter(set => set.isCompleted()).length === this._sets.length; + } + + setCompleted() { + if (!this.canSetCompleted()) throw "All sets must be completed"; + if (this.canProgress) this._weight += this._weightIncrement; + this._completed = true; + } + + get canProgress() { + let completedRepsTotalSum = 0; + let targetRepsTotalSum = 0; + + const completedRepsTotal = this._sets.forEach(set => completedRepsTotalSum += set.reps); + const targetRepsTotal = this._sets.forEach(set => targetRepsTotalSum += set.maxReps); + + return (targetRepsTotalSum - completedRepsTotalSum) === 0; + } + + startRestTimer(program) { + this._restTimeout = setTimeout(() => { + this.next(); + }, ONE_SECOND * this._restPeriod); + + this._restInterval = setInterval(() => { + program.emit("redraw"); + }, ONE_SECOND); + } + + resetRestTimer() { + clearTimeout(this._restTimeout); + clearInterval(this._restInterval); + this._restTimeout = null; + this._restInterval = null; + this._restPeriod = this._originalRestPeriod; + } + + isRestTimerRunning() { + return this._restTimeout != null; + } + + setupStartedButtons(program) { + clearWatch(); + + setWatch(() => { + this.currentSet.incReps(); + program.emit("redraw"); + }, BTN1, {repeat: true}); + + setWatch(program.next.bind(program), BTN2, {repeat: false}); + + setWatch(() => { + this.currentSet.decReps(); + program.emit("redraw"); + }, BTN3, {repeat: true}); + } + + setupRestingButtons(program) { + clearWatch(); + setWatch(program.next.bind(program), BTN2, {repeat: true}); + } + + next(program) { + global.poo = this; + switch(this._state) { + case null: + console.log("XXX 1 moving null -> STARTED"); + this._state = STARTED; + this.setupStartedButtons(program); + break; + case STARTED: + console.log("XXX 2 moving STARTED -> RESTING"); + this._state = RESTING; + this.startRestTimer(program); + this.setupRestingButtons(program); + break; + case RESTING: + this.resetRestTimer(); + this.currentSet.setCompleted(); + + if (this.canSetCompleted()) { + console.log("XXX 3b moving RESTING -> COMPLETED"); + this._state = COMPLETED; + this.setCompleted(); + } else { + console.log("XXX 3a moving RESTING -> null"); + this._state = null; + } + // As we are changing state and require it to be reprocessed + // invoke the next step of program + program.next(program); + break; + default: + throw "Exercise: Attempting to move to an unknown state"; + } + + program.emit("redraw"); + } +} \ No newline at end of file diff --git a/apps/buffgym/buffgym-icon.js b/apps/buffgym/buffgym-icon.js new file mode 100644 index 000000000..949b0e45b --- /dev/null +++ b/apps/buffgym/buffgym-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwhC/AFEEolAC6lN7vdDCcECwPd6guVGCYuDC4cCBQMikQXQJAMjkECmcyIx4XDmUjmYvLC4XUDARHBIoIWLgATCGQdA7tEonQC5ouDDYg0BOxgSEAggwKRwgUCC6ZIDSwoXNogWDDgNCAgIWIkUEoUk6kiCgMkokipsiBIQXIki2CAgNCAoYADC5Eic4Mic4ICCAIIJCC5MzAAcykYGEAAIXOABAXTmUzGoIXVAIIXLB4SICDIovjO76PZbYR3PDI4XiI6530MIh3SC6R33C/oAOC48CCxsgC44A/ADY=")) diff --git a/apps/buffgym/buffgym-program.js b/apps/buffgym/buffgym-program.js new file mode 100644 index 000000000..22f39f10b --- /dev/null +++ b/apps/buffgym/buffgym-program.js @@ -0,0 +1,68 @@ +class Program { + constructor(params) { + const DEFAULTS = { + title: "Unknown", + trainDay: "", // Day of week + }; + const p = Object.assign({}, DEFAULTS, params); + + this._title = p.title; + this._trainDay = p.trainDay; + this._exercises = []; + + this.on("redraw", redraw.bind(null, this)); + } + + get title() { + return `${this._title} - ${this._trainDay}`; + } + + addExercise(exercise) { + this._exercises.push(exercise); + } + + addExercises(exercises) { + exercises.forEach(exercise => this.addExercise(exercise)); + } + + currentExercise() { + return ( + this._exercises + .filter(exercise => !exercise.isCompleted())[0] + ); + } + + canComplete() { + return ( + this._exercises + .filter(exercise => exercise.isCompleted()) + .length === this._exercises.length + ); + } + + setCompleted() { + if (!this.canComplete()) throw "All exercises must be completed"; + this._completed = true; + } + + isCompleted() { + return !!this._completed; + } + + // State machine + next() { + console.log("XXX Program.next"); + const exercise = this.currentExercise(); + + // All exercises are completed so mark the + // Program as comleted + if (this.canComplete()) { + this.setCompleted(); + this.emit("redraw"); + + return; + } + + exercise.next(this); + } +} \ No newline at end of file diff --git a/apps/buffgym/buffgym-set.js b/apps/buffgym/buffgym-set.js new file mode 100644 index 000000000..d7d610a78 --- /dev/null +++ b/apps/buffgym/buffgym-set.js @@ -0,0 +1,46 @@ +class Set { + constructor(maxReps) { + this._minReps = 0; + this._maxReps = maxReps; + this._reps = 0; + this._completed = false; + } + + get title() { + return this._title; + } + + get weight() { + return this._weight; + } + + isCompleted() { + return !!this._completed; + } + + setCompleted() { + this._completed = true; + } + + get reps() { + return this._reps; + } + + get maxReps() { + return this._maxReps; + } + + incReps() { + if (this._completed) return; + if (this._reps >= this._maxReps) return; + + this._reps++; + } + + decReps() { + if (this._completed) return; + if (this._reps <= this._minReps) return; + + this._reps--; + } +} \ No newline at end of file diff --git a/apps/buffgym/buffgym.app.js b/apps/buffgym/buffgym.app.js new file mode 100755 index 000000000..e74b7062a --- /dev/null +++ b/apps/buffgym/buffgym.app.js @@ -0,0 +1,311 @@ +/* global g, setWatch, clearWatch, reset, BTN1, BTN2, BTN3 */ + +(() => { + const W = g.getWidth(); + const H = g.getHeight(); + const RED = "#d32e29"; + const PINK = "#f05a56"; + const WHITE = "#ffffff"; + + const Set = require("set.js"); + const Exercise = require("exercise.js"); + const Program = require("program.js"); + + function centerStringX(str) { + return (W - g.stringWidth(str)) / 2; + } + + function iconIncrement() { + const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglHA4IpJBYwTHA4RMJCY5oDJo4THKIQKET5IMGCaY7TMaKLTWajbTFJIlICgoVBFYXJYQYSGCggAGCRAVIBgw")); + return img; + } + + function iconDecrement() { + const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglKFJADBCRYABCYQmOFAhNMKIw6FTw4LHCaY7TMaKLTWajbTFJglFCgoVBFYXJYQYSGCggAGCRAVIBgw=")); + return img; + } + + function iconOk() { + const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglKFJADBCJQxCCYQmMIwZoDJpQMCKIg6KBYwTGFQgeHHYouCCRI7EMYTXFRhILEK5SfFRgYSIborbSbpglFCgoVBFYXJYQYSGCggAGCRAVIBgwA==")); + return img; + } + + function drawMenu(params) { + const DEFAULT_PARAMS = { + showBTN1: false, + showBTN2: false, + showBTN3: false, + }; + const p = Object.assign({}, DEFAULT_PARAMS, params); + if (p.showBTN1) g.drawImage(iconIncrement(), W - 30, 10); + if (p.showBTN2) g.drawImage(iconOk(), W - 30, 110); + if (p.showBTN3) g.drawImage(iconDecrement(), W - 30, 210); + } + + function clearScreen() { + g.setColor(RED); + g.fillRect(0,0,W,H); + } + + function drawTitle(exercise) { + const title = exercise.humanTitle; + + g.setFont("Vector",20); + g.setColor(WHITE); + g.drawString(title, centerStringX(title), 5); + } + + function drawReps(exercise) { + const set = exercise.currentSet; + if (set.isCompleted()) return; + + g.setColor(PINK); + g.fillCircle(W / 2, H / 2, 50); + g.setColor(WHITE); + g.setFont("Vector", 40); + g.drawString(set.reps, centerStringX(set.reps), (H - 45) / 2); + g.setFont("Vector", 15); + const note = `of ${set.maxReps}`; + g.drawString(note, centerStringX(note), (H / 2) + 25); + } + + function drawSets(exercise) { + const sets = exercise.subTitle; + + g.setColor(WHITE); + g.setFont("Vector", 15); + g.drawString(sets, centerStringX(sets), H - 25); + } + + function drawSetProgress(exercise) { + drawTitle(exercise); + drawReps(exercise); + drawSets(exercise); + drawMenu({showBTN1: true, showBTN2: true, showBTN3: true}); + } + + function drawStartNextExercise() { + const title = "Good work"; + const msg = "No need to rest\nmove straight on\nto the next exercise"; + + g.setColor(WHITE); + g.setFont("Vector", 35); + g.drawString(title, centerStringX(title), 10); + g.setFont("Vector", 15); + g.drawString(msg, 30, 150); + drawMenu({showBTN1: false, showBTN2: true, showBTN3: false}); + } + + function drawProgramCompleted() { + const title1 = "You did"; + const title2 = "GREAT!"; + const msg = "That's the program\ncompleted. Now eat\nsome food and\nget plenty of rest."; + + clearWatch(); + setWatch(reset, BTN2, {repeat: false}); + + g.setColor(WHITE); + g.setFont("Vector", 35); + g.drawString(title1, centerStringX(title1), 10); + g.setFont("Vector", 40); + g.drawString(title2, centerStringX(title2), 50); + g.setFont("Vector", 15); + g.drawString(msg, 30, 150); + drawMenu({showBTN1: false, showBTN2: true, showBTN3: false}); + } + + /* + function drawExerciseCompleted(program) { + const exercise = program.currentExercise(); + const title = exercise.canProgress? + "WELL DONE!" : + "NOT BAD!"; + const msg = exercise.canProgress? + `You weight is automatically increased\nfor ${exercise.title} to ${exercise.weight}${exercise.unit}` : + "It looks like you struggled\non a few sets, your weight will\nstay the same"; + const action = "Move straight on to the next exercise"; + + clearScreen(); + g.setColor(WHITE); + g.setFont("Vector", 20); + g.drawString(title, centerStringX(title), 10); + g.setFont("Vector", 10); + g.drawString(msg, centerStringX(msg), 180); + g.drawString(action, centerStringX(action), 210); + drawMenu({showBTN2: true}); + + clearWatch(); + setWatch(() => { + init(program); + }, BTN2, {repeat: false}); + } + */ + + function drawRestTimer(program) { + const exercise = program.currentExercise(); + const motivation = "Take a breather.."; + clearScreen(); + drawMenu({showBTN2: true}); + + g.setColor(PINK); + g.fillCircle(W / 2, H / 2, 50); + g.setColor(WHITE); + g.setFont("Vector", 15); + g.drawString(motivation, centerStringX(motivation), 25); + g.setFont("Vector", 40); + g.drawString(exercise.restPeriod, centerStringX(exercise.restPeriod), (H - 45) / 2); + exercise.decRestPeriod(); + + if (exercise.restPeriod <= 0) { + exercise.resetRestTimer(); + redraw(program); + } + } + + function redraw(program) { + const exercise = program.currentExercise(); + + clearScreen(); + + if (program.isCompleted()) { + drawProgramCompleted(program); + return; + } + + if (exercise.isRestTimerRunning()) { + if (exercise.isLastSet()) { + drawStartNextExercise(program); + } else { + drawRestTimer(program); + } + + return; + } + + drawSetProgress(exercise); + } + + function init(program) { + clearWatch(); + program.next(); + } + + // Setup training program. This should come from file + + // Squats + function buildPrograms() { + const squats = new Exercise({ + title: "Squats", + weight: 40, + unit: "Kg", + }); + squats.addSets([ + new Set(5), + new Set(5), + new Set(5), + new Set(5), + new Set(5), + ]); + + const bench = new Exercise({ + title: "Bench press", + weight: 20, + unit: "Kg", + }); + bench.addSets([ + new Set(5), + new Set(5), + new Set(5), + new Set(5), + new Set(5), + ]); + + const row = new Exercise({ + title: "Row", + weight: 20, + unit: "Kg", + }); + row.addSets([ + new Set(5), + new Set(5), + new Set(5), + new Set(5), + new Set(5), + ]); + + const ohPress = new Exercise({ + title: "Overhead press", + weight: 20, + unit: "Kg", + }); + ohPress.addSets([ + new Set(5), + new Set(5), + new Set(5), + new Set(5), + new Set(5), + ]); + + const deadlift = new Exercise({ + title: "Deadlift", + weight: 20, + unit: "Kg", + }); + deadlift.addSets([ + new Set(5), + ]); + + const pullups = new Exercise({ + title: "Pullups", + weight: 0, + unit: "Kg", + }); + pullups.addSets([ + new Set(10), + new Set(10), + new Set(10), + ]); + + const triceps = new Exercise({ + title: "Tricep extension", + weight: 20, + unit: "Kg", + }); + triceps.addSets([ + new Set(10), + new Set(10), + new Set(10), + ]); + + const programA = new Program({ + title: "Program A", + }); + programA.addExercises([ + squats, + ohPress, + deadlift, + pullups, + ]); + + const programB = new Program({ + title: "Program B", + }); + programB.addExercises([ + squats, + bench, + row, + triceps, + ]); + + const programs = [ + programA, + programB, + ]; + return programs; + } + + // For this spike, just run the first program, what will + // really happen is the user picks a program to do from + // some menu on a start page. + init(buildPrograms()[0]); +})(); \ No newline at end of file diff --git a/apps/buffgym/buffgym.png b/apps/buffgym/buffgym.png new file mode 100644 index 0000000000000000000000000000000000000000..93a29a4a686f172e5e6dbd2ecb2a1d3edf4751c0 GIT binary patch literal 1800 zcmV+j2lx1iP)tlxqC9)f@Omu&Na^VuQ3o*OkLX&0x0b91a zC7LC3CR;|G&UwKyoC)@U)%oe$2-|YHkk(v4M!t35mBz$@a#wDU>?rxOl>4iDU0;K~&^NeJ~rZV1qG0 z2VEWRN{fW6B-AV=vyLG{LNQb2i6*D;)z1+>HV9oV)YY-AYv;CEAGyt1BxHeIB6`O1 zgNbCKvH5&(h}tjTY&oMqX-z=6c>c(BKect-eBUPt!g0uGg&+h40X>Fzw5_e#pVR#$ zXoP~+BFSrtk0nGN171%U%*9ZeH|HLjvY%#M?bNRbI9pq_zjAQwp^ph~HbFcpN~ZRz z(p@Mo-ho770lfp=4bOss8*F%I4msLmKr#xaD)J*)`yvYx`ky+nJwKX`iBeY-qKGqH z?QS=3P!M$53s7Hu5JniTm@SU>rp6YK0dui1iN|DU+@DO!eyGs{ttdh(`FAE0vla{o z?WidZt%?gW#AR7;<X-pbXX@H zNxpMYdq4RMO4a}WV;wc05JSkxHD~SsCa-dTj zNTxVqQheR_7dUJ%8VslVKYYW7jWB?j;7(;1x|h0^D=>+_|8G8A);PQcVdy~=1vqUM z=Bmmm)pMW?ZosIy0KK;IbR&uXN!$f_n-$fCGwJquLBgH9YRnj{JTt}EHBxNEeXlt^ z=25u`mrr_dyKd3t92OJZd{9ZwAii{~WsvTQjEnfS8xO2y_@!_U?;}HwP2R(Ijz)}m zit&g9Oe?63KH;Lj-FATAd+p`e9q7aT9cJ8VbS}; zQ^kGnzzKFl@TSGDoSS-YQ$q_XStXt~30!=tPYtT;z`;H5V0>y6M#+fsq8;frcBVm9 z*_*JM9oV^KK>zTcC~y_yt(v2JXX>jDabwn+OJjC>_p^QzY!*8o^Zl)_Rq0Y~0Idq0 zS2Ejbz57Z043707FgeP1%EK<&HQJ?2qjG*1bTS%v z%ubCHDDjk|*z-F39AIq&YmVQ|gsn7eCKBY&B;IDWBhQ|XP-F^P(QUxw%mhX!9y3?4 za|0-g(DPbUZ?Ai9XPitl89;gYdW9(B>6do0 z&{d=<|EJJx0R4iRi$%B)8xs*{tC-D)*IL!li9sItRi$t8xdUT=@j7sD@4L`~ZUg#< z@9|7Teoy(EeEDwwZ_kbU;PA;c-%(!VWd_vn&m{hDmP)mv+W`74ORG=SmA{Aypl2;4 z5^=uzMCz^;-3HXM(oa{4%%IK%Ex`EHFzC+|RLpt@yWwJmOe>of#Mu@=51VEH#S6s{ z9o#%D1JN_>#7hfe`U6y8YJ?wyDGkFo zERDt!OF!~i5Yltbc`JfdVhJF1ywFnv_&cBz%HNa*=^#c>zCWO1`&}!lb?WRyb7@D_ zoMJQ4ZGbZ)W6%m}S;fo+s9pL&qm@ky;%p0`2i^anc~wxo1C;V!MN}J*?VR%}kkbG~ qkv|qi@hCO{S(a~Li!HWTm;V6Sm{)4DoNDL*0000 Date: Mon, 20 Apr 2020 15:27:21 +0100 Subject: [PATCH 089/878] Update apps.json --- apps.json | 4 + apps/buffgym/buffgym-programs.json | 101 ++++++++++++++++++++++++ apps/buffgym/buffgym.app.js | 121 +++++------------------------ 3 files changed, 125 insertions(+), 101 deletions(-) create mode 100644 apps/buffgym/buffgym-programs.json diff --git a/apps.json b/apps.json index e993f0e18..bff5fe66b 100644 --- a/apps.json +++ b/apps.json @@ -1305,6 +1305,10 @@ "storage": [ {"name":"buffgym"}, {"name":"buffgym.app.js"}, + {"name":"buffgym-set.js","url":"buffgym-set.js"}, + {"name":"buffgym-exercise.js","url":"buffgym-exercise.js"}, + {"name":"buffgym-program.js","url":"buffgym-program.js"}, + {"name":"buffgym-programs.json","url":"buffgym-program.json"}, {"name":"buffgym.img","url":"buffgym-icon.js","evaluate":true} ] } diff --git a/apps/buffgym/buffgym-programs.json b/apps/buffgym/buffgym-programs.json new file mode 100644 index 000000000..bf5aa0e0d --- /dev/null +++ b/apps/buffgym/buffgym-programs.json @@ -0,0 +1,101 @@ +[ + { + title: "Program A", + exercises: [ + { + title: "Squats", + weight: 40, + unit: "Kg", + sets: [ + 5, + 5, + 5, + 5, + 5 + ] + }, + { + title: "Overhead press", + weight: 20, + unit: "Kg", + sets: [ + 5, + 5, + 5, + 5, + 5 + ] + }, + { + title: "Deadlift", + weight: 20, + unit: "Kg", + sets: [ + 5 + ] + }, + { + title: "Pullups", + weight: 0, + unit: "Kg", + sets: [ + 10, + 10, + 10 + ] + } + ] + }, + { + title: "Program B", + exercises: [ + { + title: "Squats", + weight: 40, + unit: "Kg", + sets: [ + 5, + 5, + 5, + 5, + 5 + ] + }, + { + title: "Bench press", + weight: 20, + unit: "Kg", + sets: [ + 5, + 5, + 5, + 5, + 5 + ] + }, + { + title: "Row", + weight: 20, + unit:"Kg", + sets: [ + 5, + 5, + 5, + 5, + 5 + ] + + }, + { + title: "Tricep extension", + weight: 20, + unit: "Kg", + sets: [ + 10, + 10, + 10 + ] + } + ] + } +] \ No newline at end of file diff --git a/apps/buffgym/buffgym.app.js b/apps/buffgym/buffgym.app.js index e74b7062a..d3a4e6834 100755 --- a/apps/buffgym/buffgym.app.js +++ b/apps/buffgym/buffgym.app.js @@ -194,113 +194,32 @@ // Squats function buildPrograms() { - const squats = new Exercise({ - title: "Squats", - weight: 40, - unit: "Kg", - }); - squats.addSets([ - new Set(5), - new Set(5), - new Set(5), - new Set(5), - new Set(5), - ]); + const programsJSON = require("Storage").readJSON("buffgym-programs.json", 1); - const bench = new Exercise({ - title: "Bench press", - weight: 20, - unit: "Kg", - }); - bench.addSets([ - new Set(5), - new Set(5), - new Set(5), - new Set(5), - new Set(5), - ]); + if (!programsJSON) throw "No programs JSON found"; - const row = new Exercise({ - title: "Row", - weight: 20, - unit: "Kg", - }); - row.addSets([ - new Set(5), - new Set(5), - new Set(5), - new Set(5), - new Set(5), - ]); + const programs = []; - const ohPress = new Exercise({ - title: "Overhead press", - weight: 20, - unit: "Kg", - }); - ohPress.addSets([ - new Set(5), - new Set(5), - new Set(5), - new Set(5), - new Set(5), - ]); + programsJSON.forEach(programJSON => { + const program = new Program({ + title: programJSON.title, + }); + const exercises = programJSON.exercises.map(exerciseJSON => { + const exercise = new Exercise({ + title: exerciseJSON.title, + weight: exerciseJSON.weight, + unit: exerciseJSON.unit, + }); + exerciseJSON.sets.forEach(setJSON => { + exercise.addSet(new Set(setJSON)); + }); - const deadlift = new Exercise({ - title: "Deadlift", - weight: 20, - unit: "Kg", + return exercise; + }); + program.addExercises(exercises); + programs.push(program); }); - deadlift.addSets([ - new Set(5), - ]); - const pullups = new Exercise({ - title: "Pullups", - weight: 0, - unit: "Kg", - }); - pullups.addSets([ - new Set(10), - new Set(10), - new Set(10), - ]); - - const triceps = new Exercise({ - title: "Tricep extension", - weight: 20, - unit: "Kg", - }); - triceps.addSets([ - new Set(10), - new Set(10), - new Set(10), - ]); - - const programA = new Program({ - title: "Program A", - }); - programA.addExercises([ - squats, - ohPress, - deadlift, - pullups, - ]); - - const programB = new Program({ - title: "Program B", - }); - programB.addExercises([ - squats, - bench, - row, - triceps, - ]); - - const programs = [ - programA, - programB, - ]; return programs; } From 8238bb766a6f4fc80c14e2c781f5dd1ff25da22a Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 16:40:26 +0200 Subject: [PATCH 090/878] Create app.js --- apps/hamloc/app.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 apps/hamloc/app.js diff --git a/apps/hamloc/app.js b/apps/hamloc/app.js new file mode 100644 index 000000000..ac608a5f4 --- /dev/null +++ b/apps/hamloc/app.js @@ -0,0 +1,21 @@ +latLonToGridSquare=function(o,a){var t,e,n,s,l,i,r,h,M,f=-100,g=0,u="ABCDEFGHIJKLMNOPQRSTUVWX",d=u.toLowerCase();function N(o){return"number"==typeof o?o:"string"==typeof o?parseFloat(o):"function"==typeof o?parseFloat(o()):void E.showMessage("can't convert \ninput: "+o)}return"object"==typeof o?2===o.length?(f=N(o[0]),g=N(o[1])):"lat"in o&&"lon"in o?(f=N(o.lat),g=N(o.lon)):"latitude"in o&&"longitude"in o?(f=N(o.latitude),g=N(o.longitude)):E.showMessage("can't convert \nobject "+o):(f=N(o),g=N(a)),isNaN(f)&&E.showMessage("lat is NaN"),isNaN(g)&&E.showMessage("lon is NaN"),90===Math.abs(f)&&E.showMessage("grid invalid \nat N/S"),90 Date: Mon, 20 Apr 2020 16:43:00 +0200 Subject: [PATCH 091/878] Add files via upload --- apps/hamloc/app.png | Bin 0 -> 3697 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/hamloc/app.png diff --git a/apps/hamloc/app.png b/apps/hamloc/app.png new file mode 100644 index 0000000000000000000000000000000000000000..54dac5882e4aa4b14cb1e20d04471c4a5efc027b GIT binary patch literal 3697 zcmV-%4vz7OP)=ueZM8`>TRtawvha`2{8mij16u{n-t1S zowi{hDReqhpah1JgftB>3ALw5X{S@#p=2g4?j#K*yb{|1GKPS`avU33e#o-k+SRVs z`?`1c-hJKvv9hf7u4D&jI{D39Y3@1ach2{F&hPxr?|1IPZ@CB`S4Vq(GX5zgSNME1 zk-au1YaJQ2j+f1Y~1$%Hfs=Tgc2;#Z zGd2}rcsz{VYQ}65nMH_-j1P__@3>=Y4_nrDav}nIUOG)zOFdiq z+bJz-e{?j?=58MVCga5=ZfW!}6OAvlvzr9IcvB}EI(L~;P?%vkLJvaC8!9@Iz z?*EUW(Weg$yFLo)abv6M~Z++>85qO!5Cb76WjIT)DHIWdu> z!EK@5X$Byc(HHu2*euvAW@3pnn_C1tmU#ezz+KzAn2KdMI5f-PEToGP*Kg`2U(ihh z6S33J49wL3+62y=NR4IlMQO|Wm6${k04 z^pVL|_UZRIkP6BI_zU8)N!-4rjsH0`#YDWUBuOG$*7uOn3ewRNsdG!=6l)cJ<%O{$ z$48^~tNXi9GU`J4@OTJ|S>n1*8>L(ZfMyFMRVbEVdM?E^-F1vd6#!;aI*C+S*Jl&x z@tZj|7GJ1eEMAullUd^UnF+ev0t@B+-E9mEo^?L<;>4lHKiB@rOZBSU=-=;)-1)O( zqu(o*N|#pszlyIzN5;IKfsw-R+GP z^#g+=6bgmh_rBC;t{}Gf<%!oOpN*WCO?^FWRRG6l=D512uA(ekfMa3!#e~lB85NJs zQ~@3?f(NjhMI2U%NJ8aO>G#8p9Rk7TI>zVEi^a0Kr=4g#ZF=(6&_69n;Phnj3&A!& z7L!z=oJ?m>GAiqX7o9;w(RpV=CoJp8IXD|pvDz%?I?GDHZ6T7XCZOvu6on>#9cej3 zTFF+_Tg(z2Eq+c<&)r*-!0rR#2cijC>{_&eE=YJTfzRVaDVfO?;q)9F4VBH~f@D+; zQIwcWF3-U0FmXPet0*h#a5M~|w2s|o!Q*lejwY&fd)ga`#1(PRzR+J(5txc8j|A#m zSk0y?#kqKjdXIydw9cEOI%A1ykXo*Q#Vj$IS{6S}t3+D8=wAyZI5MphRW9~f=W#HX zsP4#OG2yRsF%wt5T18+ok_@y4YMd83oKGpZU5;ge<#KsUl0@k;Cgie+$Z7#7yWYdo zI`K;^%ImTdOIEvDfR;cVB zuWH=)jnB006aiA%+)9_tN^4`a3C$%^6pK0?E&hsf$p}^nBmuluc=_-IYgTw^_F0!D zFcr)2{_q@40YAAVzyq8foyO;O;B!}7#bkJnbSB>m^Pz;C&DD9`c7m#u4WSv6Nt z*W?uF_k(fKG5G4h1nYtxdRyGf5*V6HaCkUIOVjeU7LK0BZnMAf{ssN+WK(SDps3;oA&);|$=Ks`e z>9Yz*1`rmF=dygXn;0d3G0C}{2ulp5>mbbcVgRs7$faT>hbE`M)h*EGG2)bp)Y}9k zV`Xf!SVW_N!sQMDU@}p{cm*p}ES4}BY7bT@77-<}xIn-p3TcN}nSFG4%KuH00X0{k zuK{eew@I0RK_FjT-nNq}%qb-d!sYi$u~0-5t6eCR6DzZ5$iuuBa#+Oi*|^f~wnque zR);O8wWi$@qcm^Gv(W&UN1QK!DNtefH=A0gK7>tI%}%`a&T>t^{fx#^xLAdVzE%$6G@YbREtuvHHcL&fr9xk#KrR zf^rV>`2xjaiLvR(vII0OPdp`8MWq08R;9Pi{lNkOuifxmRxAAFpWVKi2A3H*2j}7t zk#*8pjeTz)AwE?bORolNOH8?a`p84^aC^vqhZ^^#ojLLy` zj&uFSilM#L zqMQo=IIJS6OSAYzVwcJ$spa#SrP{WAK@uqilPFe!2Z)?c;&NK_`)~HY28)vVwtDOP z?+?d5bwmHfe86ac6>fn}zk`$0G6tKs#&9}bD>y6?a<;G}DA53$n+1l33s^17cmv8d z?(@`+ekVdPIvPCV7v2}#f!||${9HIqC|+%IeQiz>DS7DuvtSU7q_az}0D#*9R%4#7 zI*D7l1#SomtPOzYlJF^(kg4}pU&^JFEQzE{z-Rkf6@dqDZr>ja*rWT8hN=|TuJ96# zr%}|UJxm@m(R6kAd#S|b9CgmJX;_Tq^Ja6iu;8MVj7lOU(^y{}Q=J)|p{2pCJ+wXW zpH&0^Is=ZczJGSEY89G&He3!XQ=!6M#3mS>->aI zgkv}zHk|g#Wl6~yre@F6)9Ty3xV(bE!@t}4Z(WU!spk)lRUP;J9ra9vs&5M}h}~*N z)pE?qMb5;^9%tlyWiN_WK+fi?u2cZL)^cz#8JeS`rP7n>z_HWgtZ4Gee|<~iV~gvm zy!t=9GQMfwP-vid1!2K&QVfE?&6~S#`m3Aj-&kB;^H_R#@2O{prjmF6>5V}e=XY31 zhrREHNT#!F?5llYe0Xq#7Qc^Xf7x4kECRiYCiBQhjN{`8?%LK>rK>t7DwA0mk z(G#YWEWaEYV_lE`z*DycZ>}O%3&`$Wy5)O%fIwcNscUyF?u4fcg6q2yWB?5Zfc@Py(SvRa-sJ?#tnl4Rt>@FZ8Qs1Mfy zza#;Gu5S5izuP+b^eZQc&S%~${U-XmTRDDa0xehVGJS3bu|(P38U+YADi`={C`~X> zom(fBJU@DOlH0Cn#X6r;D_NCa963$EXU}|TP3MZGa4t#U-p!lyD_5FUdmW~!-7lVC zJgOiWU~_i>m&3x5p>yb$Z1o1OlT21c$!c`@%3o+MNF=Eemo-*4SNiv2N$0sY&eC3Q zyEuD$P*J*nH;`h&p+`_bJm4)OEBF!c_& zdUZERIm_`=;}z{~Rx=)#9YKu~^j6OPFVDqj_d6=$DIIwJ;24pl#@*YxK!CC7Fb4-t z5p42=?pf38xp#*zxg5qTPOlz+`P`m?;kgH!yf&dL*nuv{S#?I(y$5XDXJ_H?C^@@z-x{ z`-3aNb;VyPAN#$|hqm@LZ;*_}sW;vmZL9sv#4;6O z^{MG3;bfLAE6Z0iaXH6#Up~dD=_Fscv6I)1%<#m24`Pyp>0356Z@N1(aC7S>UB6M>P50@j$76@vb8V3t4F4pKA+*i-@gi7hdn1AO9(iQvitqorSUysQzWYG<^Rw~H6O)nTiiE5hjPpMuaM?^K zS{}Pa1igF$+szWGYz~7UP%P>A-4?C2-uiB%)AG&xcXqt_VKIDcKlb>}{;Bnfs@*wz zKC?BJ$p Date: Mon, 20 Apr 2020 16:44:35 +0200 Subject: [PATCH 092/878] Create app-icon.js --- apps/hamloc/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/hamloc/app-icon.js diff --git a/apps/hamloc/app-icon.js b/apps/hamloc/app-icon.js new file mode 100644 index 000000000..175b492c7 --- /dev/null +++ b/apps/hamloc/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4ACwVeAAM6nQECJsYqDFYItCAgQ0DFrxWE2ZhBxOJA4ICBGwhbbxGtAYOz2etnWt2YwBnQCBGgWtxBjXJQQpBLgQABEQIDBMAgwE2YYBwRcUxOtDwgABGgYvGTQQLCMSRNGEQaODF4SQDHgYwUFIlfAgY2DYQQGDsouCGAQSEGBouEKANl1onEwQvGA4QACA4IwQaIISFFwIwDXwI2ExL2BB4YABJgwwKnQAkRpzYDAAbuBA4oABe4aaDD44uGxCNEQwStEdwgAFR4IHGF4iRBxJeLBwIdCcwgvJxLwFFIRgLBo4dBcwj2CF45xIKIxeLAww4FAAuINIYbKMAteso8FAwovPCQllQQtlF4gLFUYwvDsq/HfIShEDhCQDIgIAFnQHGBBITRnWIXwdfAAYGFSYblBNI5KBsobEDo4GCdxyFDr2tR4+tDQrwNF5YlEnQvJaZIvKr4RIEoovaSAIvyXArbBF6OJR6mCXAgvBDwIlFd5IfBd6tfSQQRGCgeIBJE6DIIAFDoIGGF4OCAgIAEnQHGBBITRnWIF4P+V4ZMCWxBoBRw5PBNI7IGnQuCSAIfE1oSB1oADF4WIXxAvHsoIFH4IvEdIJWEDg4vICRTuJSAwABxAcJF5A5C1ovKRwhgCwSQGF6CpEXxBeGMA59JZIIvGA4hhBLw+JF4xRFSBBNDFIhHFe4VfLxhgCAEguIMAJSB1oABSA4HEB4RwBAgQXHss6LxKRDPQTxBsovIRIdexCOGRpwwIr5gFAwbuEAoheBFyQwFRIrwDLwZuBdwgTBC4IuRYYowGRAq+BAoeCAoRABFyIABD4IsCGAgpFGoguBd4eIFyRiEFoIwCEoKJDRwYqCCAJcUGJICBK4JgDKgOtOIQtce4s6AAI2EBAgteAAizBGgYECwQsiAD4")) From 9f5cbc6022ee275ed40e6942cb69388f4d6c6e07 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 16:49:49 +0200 Subject: [PATCH 093/878] Update apps.json --- apps.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps.json b/apps.json index b58fad5ce..e55190ec0 100644 --- a/apps.json +++ b/apps.json @@ -1400,5 +1400,17 @@ {"name":"rclock.app.js","url":"rclock.app.js"}, {"name":"rclock.img","url":"app-icon.js","evaluate":true} ] + }, + { "id": "hamloc", + "name": "QTH Locator / Maidenhead Locator System", + "shortName": "QTH Locator", + "icon": "app.png", + "version":"0.01", + "description": "Convert your current GPS location to the Maidenhead locator system used by HAM amateur radio operators", + "tags": "tool,outdoors,gps", + "storage": [ + {"name":"hamloc.app.js","url":"app.js"}, + {"name":"hamloc.img","url":"app-icon.js","evaluate":true} + ] } ] From 02af1e4b1518b35d09e541df63f4130924df29d2 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 16:55:59 +0200 Subject: [PATCH 094/878] Create ChangeLog --- apps/hamloc/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/hamloc/ChangeLog diff --git a/apps/hamloc/ChangeLog b/apps/hamloc/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/hamloc/ChangeLog @@ -0,0 +1 @@ +0.01: New App! From e513031a8770146f7fbe34c672d283d177e31f4a Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 17:11:51 +0200 Subject: [PATCH 095/878] Create README.md --- apps/hamloc/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 apps/hamloc/README.md diff --git a/apps/hamloc/README.md b/apps/hamloc/README.md new file mode 100644 index 000000000..493afa899 --- /dev/null +++ b/apps/hamloc/README.md @@ -0,0 +1,14 @@ +# QTH Locator + +Convert your current GPS location to the [Maidenhead](https://en.wikipedia.org/wiki/Maidenhead_Locator_System) locator system used by HAM amateur radio operators. + +## Description + +A Maidenhead locator compresses latitude and longitude into a short string of characters, which is similar in concept to the World Geographic Reference System or GEOREF. This position information is presented in a limited level of precision to limit the number of characters needed for its transmission using voice, Morse code, or any other operating mode.[4] + +The chosen coding uses alternating pairs of letters and digits, like so: + +* BL11bh + +support Paul Brewer KI6CQ HamGridSquare.js +support Chris Veness 2002-2012 LatLon library From 5f9ee09daf8b9baf63e19d067efddd589da20648 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 17:13:07 +0200 Subject: [PATCH 096/878] Update README.md --- apps/hamloc/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/hamloc/README.md b/apps/hamloc/README.md index 493afa899..273e1f54b 100644 --- a/apps/hamloc/README.md +++ b/apps/hamloc/README.md @@ -4,11 +4,12 @@ Convert your current GPS location to the [Maidenhead](https://en.wikipedia.org/w ## Description -A Maidenhead locator compresses latitude and longitude into a short string of characters, which is similar in concept to the World Geographic Reference System or GEOREF. This position information is presented in a limited level of precision to limit the number of characters needed for its transmission using voice, Morse code, or any other operating mode.[4] +A Maidenhead locator compresses latitude and longitude into a short string of characters, which is similar in concept to the World Geographic Reference System or GEOREF. This position information is presented in a limited level of precision to limit the number of characters needed for its transmission using voice, Morse code, or any other operating mode. The chosen coding uses alternating pairs of letters and digits, like so: * BL11bh -support Paul Brewer KI6CQ HamGridSquare.js -support Chris Veness 2002-2012 LatLon library + +* support Paul Brewer KI6CQ HamGridSquare.js +* support Chris Veness 2002-2012 LatLon library From a47ebfaf4841be23a45f4b64533e1c7e55769a95 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 17:14:16 +0200 Subject: [PATCH 097/878] Update README.md --- apps/hamloc/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/hamloc/README.md b/apps/hamloc/README.md index 273e1f54b..5710493bb 100644 --- a/apps/hamloc/README.md +++ b/apps/hamloc/README.md @@ -9,7 +9,6 @@ A Maidenhead locator compresses latitude and longitude into a short string of ch The chosen coding uses alternating pairs of letters and digits, like so: * BL11bh - - +## * support Paul Brewer KI6CQ HamGridSquare.js * support Chris Veness 2002-2012 LatLon library From 4b512af0e2012986ea1d5f3e2f916cb2f88e47b8 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 20 Apr 2020 17:34:33 +0200 Subject: [PATCH 098/878] activepedom 0.03 --- apps/activepedom/ChangeLog | 3 +- apps/activepedom/README.md | 20 +++++- apps/activepedom/app.js | 133 +++++++++++++++++++++++++++++++++++++ apps/activepedom/widget.js | 51 +++++++++----- 4 files changed, 190 insertions(+), 17 deletions(-) create mode 100644 apps/activepedom/app.js diff --git a/apps/activepedom/ChangeLog b/apps/activepedom/ChangeLog index fb0bc78e5..c1b9ec011 100644 --- a/apps/activepedom/ChangeLog +++ b/apps/activepedom/ChangeLog @@ -1,2 +1,3 @@ 0.01: New Widget! -0.02: Distance calculation and display \ No newline at end of file +0.02: Distance calculation and display +0.03: Data logging and display \ No newline at end of file diff --git a/apps/activepedom/README.md b/apps/activepedom/README.md index 055a91f56..f45297e57 100644 --- a/apps/activepedom/README.md +++ b/apps/activepedom/README.md @@ -1,4 +1,4 @@ -# Active Pedometer +# Active Pedometer Pedometer that filters out arm movement and displays a step goal progress. I changed the step counting algorithm completely. @@ -6,6 +6,8 @@ Now every step is counted when in status 'active', if the time difference betwee To get in 'active' mode, you have to reach the step threshold before the active timer runs out. When you reach the step threshold, the steps needed to reach the threshold are counted as well. +Steps are saved to a datafile every 5 minutes. You can watch a graph using the app. + ## Screenshots * 600 steps ![](600.png) @@ -30,6 +32,22 @@ When you reach the step threshold, the steps needed to reach the threshold are c * Steps are saved to a file and read-in at start (to not lose step progress) * Settings can be changed in Settings - App/widget settings - Active Pedometer +## Data storage + +* Data is stored to a file +* Format: now,stepsCounted,active,stepsTooShort,stepsTooLong,stepsOutsideTime +* now is UNIX timestamp in ms +* You can chose the app to watch a steps graph +* You can import the file into Excel +* The file does not include a header +* You can convert UNIX timestamp to a date in Excel using this formula: =DATUM(1970;1;1)+(LINKS(A2;10)/86400) +* You have to format the cell with the formula to a date cell. Example: JJJJ-MM-TT-hh-mm-ss + +## App + +* The app accesses the data stored for the current day +* Timespan is choseable (1h, 4h, 8h, 12h, 16h, 20, 24h), standard is 24h, the whole current day + ## Settings * Max time (ms): Maximum time between two steps in milliseconds, steps will not be counted if exceeded. Standard: 1100 diff --git a/apps/activepedom/app.js b/apps/activepedom/app.js new file mode 100644 index 000000000..f966530d0 --- /dev/null +++ b/apps/activepedom/app.js @@ -0,0 +1,133 @@ +(() => { + +const storage = require("Storage"); +var history = 86400000; // 28800000=8h 43200000=12h //86400000=24h + +//Convert ms to time +function getTime(t) { + date = new Date(t); + offset = date.getTimezoneOffset() / 60; + //var milliseconds = parseInt((t % 1000) / 100), + seconds = Math.floor((t / 1000) % 60); + minutes = Math.floor((t / (1000 * 60)) % 60); + hours = Math.floor((t / (1000 * 60 * 60)) % 24); + hours = hours - offset; + hours = (hours < 10) ? "0" + hours : hours; + minutes = (minutes < 10) ? "0" + minutes : minutes; + seconds = (seconds < 10) ? "0" + seconds : seconds; + return hours + ":" + minutes + ":" + seconds; +} + +function getDate(t) { + date = new Date(t*1); + year = date.getFullYear(); + month = date.getMonth()+1; //month is zero-based + day = date.getDate(); + month = (month < 10) ? "0" + month : month; + day = (day < 10) ? "0" + day : day; + return year + "-" + month + "-" + day; +} + +//columns: 0=time, 1=stepsCounted, 2=active, 3=stepsTooShort, 4=stepsTooLong, 5=stepsOutsideTime +function getArrayFromCSV(file, column) { + i = 0; + array = []; + now = new Date(); + while ((nextLine = file.readLine())) { //as long as there is a next line + if(nextLine) { + dataSplitted = nextLine.split(','); //split line, + diff = now - dataSplitted[0]; //calculate difference between now and stored time + if (diff <= history) { //only entries from the last x ms + array.push(dataSplitted[column]); + } + } + i++; + } + return array; +} + +function drawGraph() { + //times + // actives = getArrayFromCSV(csvFile, 2); + // shorts = getArrayFromCSV(csvFile, 3); + // longs = getArrayFromCSV(csvFile, 4); + // outsides = getArrayFromCSV(csvFile, 5); //array.push(dataSplitted[5].slice(0,-1)); + now = new Date(); + month = now.getMonth() + 1; + if (month < 10) month = "0" + month; + filename = filename = "activepedom-" + now.getFullYear() + month + now.getDate() + ".data"; + var csvFile = storage.open(filename, "r"); + times = getArrayFromCSV(csvFile, 0); + first = getDate(times[0]) + " " + getTime(times[0]); + last = getDate (times[times.length-1]) + " " + getTime(times[times.length-1]); + //free memory + csvFile = undefined; + times = undefined; + + //steps + var csvFile = storage.open(filename, "r"); + steps = getArrayFromCSV(csvFile, 1); + //define y-axis grid labels + stepsLastEntry = steps[steps.length-1]; + if (stepsLastEntry < 1000) gridyValue = 100; + if (stepsLastEntry >= 1000 && stepsLastEntry < 10000) gridyValue = 500; + if (stepsLastEntry > 10000) gridyValue = 5000; + + //draw + drawMenu(); + g.drawString("First: " + first, 40, 30); + g.drawString(" Last: " + last, 40, 40); + require("graph").drawLine(g, steps, { + //title: "Steps Counted", + axes : true, + gridy : gridyValue, + y : 50, //offset on screen + x : 5, //offset on screen + }); + //free memory from big variables + allData = undefined; + allDataFile = undefined; + csvFile = undefined; + times = undefined; +} + +function drawMenu () { + g.clear(); + g.setFont("6x8", 1); + g.drawString("BTN1:Timespan | BTN2:Draw", 20, 10); + g.drawString("Timespan: " + history/1000/60/60 + " hours", 20, 20); +} + +setWatch(function() { //BTN1 + switch(history) { + case 3600000 : //1h + history = 14400000; //4h + break; + case 86400000 : //24 + history = 3600000; //1h + break; + default : + history = history + 14400000; //4h + break; + } + drawMenu(); +}, BTN1, {edge:"rising", debounce:50, repeat:true}); + +setWatch(function() { //BTN2 + g.setFont("6x8", 2); + g.drawString ("Drawing...",30,60); + drawGraph(); +}, BTN2, {edge:"rising", debounce:50, repeat:true}); + +setWatch(function() { //BTN3 +}, BTN3, {edge:"rising", debounce:50, repeat:true}); + +setWatch(function() { //BTN4 +}, BTN4, {edge:"rising", debounce:50, repeat:true}); + +setWatch(function() { //BTN5 +}, BTN5, {edge:"rising", debounce:50, repeat:true}); + +drawMenu(); + +})(); \ No newline at end of file diff --git a/apps/activepedom/widget.js b/apps/activepedom/widget.js index d569716ec..7879b2056 100644 --- a/apps/activepedom/widget.js +++ b/apps/activepedom/widget.js @@ -3,13 +3,14 @@ var startTimeStep = new Date(); //set start time var stopTimeStep = 0; //Time after one step var timerResetActive = 0; //timer to reset active + var timerStoreData = 0; //timer to store data var steps = 0; //steps taken var stepsCounted = 0; //active steps counted var active = 0; //x steps in y seconds achieved var stepGoalPercent = 0; //percentage of step goal var stepGoalBarLength = 0; //length og progress bar var lastUpdate = new Date(); //used to reset counted steps on new day - var width = 45; //width of widget + var width = 46; //width of widget //used for statistics and debugging var stepsTooShort = 0; @@ -18,13 +19,33 @@ var distance = 0; //distance travelled + const s = require('Storage'); const SETTINGS_FILE = 'activepedom.settings.json'; const PEDOMFILE = "activepedom.steps.json"; + var dataFile; + var storeDataInterval = 5*60*1000; //ms let settings; //load settings function loadSettings() { - settings = require('Storage').readJSON(SETTINGS_FILE, 1) || {}; + settings = s.readJSON(SETTINGS_FILE, 1) || {}; + } + + function storeData() { + now = new Date(); + month = now.getMonth() + 1; + if (month < 10) month = "0" + month; + filename = filename = "activepedom-" + now.getFullYear() + month + now.getDate() + ".data"; + dataFile = s.open(filename,"a"); + if (dataFile) dataFile.write([ + now.getTime(), + stepsCounted, + active, + stepsTooShort, + stepsTooLong, + stepsOutsideTime, + ].join(",")+"\n"); + dataFile = undefined; } //return setting @@ -77,20 +98,20 @@ //Remove step if time between first and second step is too long if (stepTimeDiff >= setting('cMaxTime')) { //milliseconds - stepsTooLong++; //count steps which are note counted, because time too long + stepsTooLong++; //count steps which are not counted, because time too long steps--; } - //Remove step if time between first and second step is too short if (stepTimeDiff <= setting('cMinTime')) { //milliseconds - stepsTooShort++; //count steps which are note counted, because time too short + stepsTooShort++; //count steps which are not counted, because time too short steps--; } + //Step threshold reached if (steps >= setting('stepThreshold')) { if (active == 0) { stepsCounted = stepsCounted + (setting('stepThreshold') -1) ; //count steps needed to reach active status, last step is counted anyway, so treshold -1 - stepsOutsideTime = stepsOutsideTime - 10; //substract steps needed to reac active status + stepsOutsideTime = stepsOutsideTime - 10; //substract steps needed to reach active status } active = 1; clearInterval(timerResetActive); //stop timer which resets active @@ -109,14 +130,17 @@ function draw() { var height = 23; //width is deined globally - distance = (stepsCounted * setting('stepLength')) / 100 /1000 //distance in km + distance = (stepsCounted * setting('stepLength')) / 100 /1000; //distance in km //Check if same day let date = new Date(); if (lastUpdate.getDate() == date.getDate()){ //if same day } - else { - stepsCounted = 1; //set stepcount to 1 + else { //different day, set all steps to 0 + stepsCounted = 0; + stepsTooShort = 0; + stepsTooLong = 0; + stepsOutsideTime = 0; } lastUpdate = date; @@ -166,7 +190,7 @@ stepsTooLong : stepsTooLong, stepsOutsideTime : stepsOutsideTime }; - require("Storage").write(PEDOMFILE,d); //write array to file + s.write(PEDOMFILE,d); //write array to file }); //When Step is registered by firmware @@ -182,8 +206,7 @@ }); //Read data from file and set variables - let pedomData = require("Storage").readJSON(PEDOMFILE,1); - + let pedomData = s.readJSON(PEDOMFILE,1); if (pedomData) { if (pedomData.lastUpdate) lastUpdate = new Date(pedomData.lastUpdate); stepsCounted = pedomData.stepsToday|0; @@ -191,12 +214,10 @@ stepsTooLong = pedomData.stepsTooLong; stepsOutsideTime = pedomData.stepsOutsideTime; } - pedomdata = 0; //reset pedomdata to save memory setStepSensitivity(setting('stepSensitivity')); //set step sensitivity (80 is standard, 400 is muss less sensitive) - + timerStoreData = setInterval(storeData, storeDataInterval); //store data regularly //Add widget WIDGETS["activepedom"]={area:"tl",width:width,draw:draw}; - })(); \ No newline at end of file From 35583eb8371551bc055dfd55316c8f2216aedb9e Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 20 Apr 2020 17:36:42 +0200 Subject: [PATCH 099/878] activepedom 0.03 --- apps.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps.json b/apps.json index 274a3a8b2..eda9203bc 100644 --- a/apps.json +++ b/apps.json @@ -1127,15 +1127,15 @@ "name": "Active Pedometer", "shortName":"Active Pedometer", "icon": "app.png", - "version":"0.02", - "description": "Pedometer that filters out arm movement and displays a step goal progress.", + "version":"0.03", + "description": "Pedometer that filters out arm movement and displays a step goal progress. Steps are saved to a daily file and can be viewed as graph.", "tags": "outdoors,widget", - "type":"widget", "readme": "README.md", "storage": [ {"name":"activepedom.wid.js","url":"widget.js"}, {"name":"activepedom.settings.js","url":"settings.js"}, - {"name":"activepedom.img","url":"app-icon.js","evaluate":true} + {"name":"activepedom.img","url":"app-icon.js","evaluate":true}, + {"name":"activepedom.app.js","url":"app.js"}, ] }, { "id": "chronowid", From 5d3264e51eb68116677838fc4d3c5e545448b729 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 20 Apr 2020 17:37:45 +0200 Subject: [PATCH 100/878] activepedom 0.03 --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index eda9203bc..36498423e 100644 --- a/apps.json +++ b/apps.json @@ -1135,7 +1135,7 @@ {"name":"activepedom.wid.js","url":"widget.js"}, {"name":"activepedom.settings.js","url":"settings.js"}, {"name":"activepedom.img","url":"app-icon.js","evaluate":true}, - {"name":"activepedom.app.js","url":"app.js"}, + {"name":"activepedom.app.js","url":"app.js"} ] }, { "id": "chronowid", From 3e9f581b9fb3adcf23421fff4956490f20fdc452 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Mon, 20 Apr 2020 17:09:27 +0100 Subject: [PATCH 101/878] Fix apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index bff5fe66b..7a1a3f5fb 100644 --- a/apps.json +++ b/apps.json @@ -1308,7 +1308,7 @@ {"name":"buffgym-set.js","url":"buffgym-set.js"}, {"name":"buffgym-exercise.js","url":"buffgym-exercise.js"}, {"name":"buffgym-program.js","url":"buffgym-program.js"}, - {"name":"buffgym-programs.json","url":"buffgym-program.json"}, + {"name":"buffgym-programs.json","url":"buffgym-programs.json"}, {"name":"buffgym.img","url":"buffgym-icon.js","evaluate":true} ] } From 900805e71b2a670ef5098f87a71525c0b7672c36 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Mon, 20 Apr 2020 17:20:23 +0100 Subject: [PATCH 102/878] Fix apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 7a1a3f5fb..4eeee4e32 100644 --- a/apps.json +++ b/apps.json @@ -1304,7 +1304,7 @@ "type": "app", "storage": [ {"name":"buffgym"}, - {"name":"buffgym.app.js"}, + {"name":"buffgym.app.js", "url": "buffgym.app.js"}, {"name":"buffgym-set.js","url":"buffgym-set.js"}, {"name":"buffgym-exercise.js","url":"buffgym-exercise.js"}, {"name":"buffgym-program.js","url":"buffgym-program.js"}, From fae5b02277014aae97e31109ffd01adc66f04430 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 20:39:59 +0200 Subject: [PATCH 103/878] Create osmpoi.html --- apps/osmpoi/osmpoi.html | 228 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 apps/osmpoi/osmpoi.html diff --git a/apps/osmpoi/osmpoi.html b/apps/osmpoi/osmpoi.html new file mode 100644 index 000000000..56a1f8eb6 --- /dev/null +++ b/apps/osmpoi/osmpoi.html @@ -0,0 +1,228 @@ + + + + + + + + +
+
+ +
+ +

Click

+

If ok, Click

+
+ + + + + + + + + From 83253aa5be1e48b6cfabe9fa77d4520e994067f2 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 20:40:28 +0200 Subject: [PATCH 104/878] Add files via upload --- apps/osmpoi/app.png | Bin 0 -> 1989 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/osmpoi/app.png diff --git a/apps/osmpoi/app.png b/apps/osmpoi/app.png new file mode 100644 index 0000000000000000000000000000000000000000..31f09b5316318426fe64e8e427541af999cc72ae GIT binary patch literal 1989 zcmV;$2RitPP)<|5#K+5}}kD(!|)9(u%gVg{sw(nl_lqL$MVQDH;j|7FN0}AX{0Khb+6W@0r<| zojY^q-h2AT?8590%RDZWH1V5EGWVSGdwkFDJbvdK_&QOkEyJ_by8*nGm+3wY})8rT{P> zXe?AmAq0ZJI#tug&41xVW858IoL;E0q43XN|EjkB^-WWO$AMP?D__}s2q?f$fG2MI z#=jzaCK2q2C_s3V*$yiJRo&es;M=lqE@xVsS@AofQ_b1=TDN`pq zbu<$f>gpPzT^)KN95%x(7mY|$lYRE!foa0FM*_2f1G#kMBCr^ES@n27l4MC_R;b>R z-bdg0#|&9f)MA`BV$taHcYoCf)Bv488_?1BzXR9~#B%9z<*45PoJl40ETTp{zP{_+ zx$~95V6af<0TfNs00G<$*v068+yr94?jh=QA@ZJUSx{8B8%O}9K)6^va?u`K2S~Eq z1C%+@aZ?G%E>{dFcckMw`BD_zUT+k*#fgqwbKr);TUH*|Bax~>#lwI~uB?zY5b676 zP4=4_f#IV^r+~2;MazJTD9XQ3l!Hi8J(6^k^b%{4USdy?PR$p=O^!fd`~*03Ff#&o zdB6XI1lt6j8t2#JYoi<$~eOw(7ftMt=`)f*hc{^^m zEc^VDYh2{UREj2;570G6`WjI}m9;znk==1^6bgUY&9K z33b}^S=W+FH5?bf5x6pm`+8GkhprD&X`qz!uDO`>3LzwfqbO*8pPO_9zKbMn7`AlT zx#7<|I~!TP)@_L}PoJJlI)}PUzyj)xrlzw)Nx6f;8G(lu#U)jJ5cmxsgzb!gyVS1% z6Og2Jfi=GmdFITWnM=m}@IN17Stf8SlK{Yb$zw;anf=Lu!05okk5nKl-vffCksLB& zc@gmXJb=f)Z24)|l&N_og}rZVZUeSn_9>%ohk5DJ;7uh9Qb|c!>4F7GBq^HGgy)}JNv&g3H%$&@>{W3doCreF=KC)-0lmhcsx~*$Ak5FJYK+a ztu`VakH*%$ycZ#a-PzGfDm4n&*I%DWzy@klr%s;9%evw+jJWP_2zkALB8=44JHocj z@baY}B(}aa%lzd0C;Iknr+~er({La=l{jpC^l@HJ$(lPE4|O|=fF#Qjpxe<%B&*Ui zjnG32>#UX*6ZmO(>5?*i%Nx^y^_k5ErxJUt_O>79WnA-^y`5b}pQQRByIftOt1Cgp zh$~l)mSu&OJW_A9x5a?(0C9xa0#pID1LOzkdtX@A2s;$I&|lE|?ymRD)=Q_d2zWhq zytBjcZmfDd5xb-F%IYVC9e!-dA?xDBDDZ6{-dEE+*!imwFoD16hiXm(#1Gc&PBxtQ zO3$W^n%UNNa)6-EM{hXf_-7Lhzmb^LvfIlP~8$TcU z^DFxkwTGqwv$5?}JsbX7VYXhnd~+t3_+&j4cKp8JtEe#SmSzLMI9z)yS+jo%aDP6| z4@ICJm~Vx{yMR0TzW;&{D|rY2(1qOMdj5g0qxwpyAck3K#|7-jg X&}z;-%?VoU00000NkvXXu0mjfBg)CA literal 0 HcmV?d00001 From 4bdedc08fbb7f12c67094666256953a6c2af5a24 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 20:46:00 +0200 Subject: [PATCH 105/878] Update apps.json --- apps.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps.json b/apps.json index e55190ec0..95669f250 100644 --- a/apps.json +++ b/apps.json @@ -1412,5 +1412,17 @@ {"name":"hamloc.app.js","url":"app.js"}, {"name":"hamloc.img","url":"app-icon.js","evaluate":true} ] + }, + { "id": "osmpoi", + "name": "POI Compass", + "icon": "app.png", + "version":"0.01", + "description": "Uploads all the points of interest in an area onto your watch, same as Beer Compass with more p.o.i.", + "tags": "tool,outdoors,gps", + "custom": "osmpoi.html", + "storage": [ + {"name":"osmpoi.app.js"}, + {"name":"osmpoi.img"} + ] } ] From 95ddcbf4670c1e50376b9c7640221f72dcb698d6 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 20:48:07 +0200 Subject: [PATCH 106/878] Create ChangeLog --- apps/osmpoi/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/osmpoi/ChangeLog diff --git a/apps/osmpoi/ChangeLog b/apps/osmpoi/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/osmpoi/ChangeLog @@ -0,0 +1 @@ +0.01: New App! From 3363999e806864910ecb252c636bf92eb2694bcd Mon Sep 17 00:00:00 2001 From: bengwalker <63957296+bengwalker@users.noreply.github.com> Date: Mon, 20 Apr 2020 20:49:54 +0200 Subject: [PATCH 107/878] add ChangeLog, attribute to source for icon --- apps/metronome/ChangeLog | 3 +++ apps/metronome/README.md | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 apps/metronome/ChangeLog diff --git a/apps/metronome/ChangeLog b/apps/metronome/ChangeLog new file mode 100644 index 000000000..a65efbaaf --- /dev/null +++ b/apps/metronome/ChangeLog @@ -0,0 +1,3 @@ +0.01: New App! +0.02: Watch vibrates with every beat +0.03: Uses mean of three time intervalls to calculate bmp diff --git a/apps/metronome/README.md b/apps/metronome/README.md index 19d489327..aab2d5a3f 100644 --- a/apps/metronome/README.md +++ b/apps/metronome/README.md @@ -8,3 +8,7 @@ This metronome makes your watch blink and vibrate with a given rate. * Use `BTN1` to increase the bmp value by one. * Use `BTN3` to decrease the bmp value by one. * You can change the bpm value any time by tapping the screen or using `BTN1` and `BTN3`. + +## Attributions + +"Icon made by Roundicons from www.flaticon.com" \ No newline at end of file From 7d8700a3e91e17bdccbdb940ffa2ec45627e772e Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Mon, 20 Apr 2020 20:50:55 +0200 Subject: [PATCH 108/878] Create README.md --- apps/osmpoi/README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 apps/osmpoi/README.md diff --git a/apps/osmpoi/README.md b/apps/osmpoi/README.md new file mode 100644 index 000000000..4c59e16f6 --- /dev/null +++ b/apps/osmpoi/README.md @@ -0,0 +1,5 @@ +# Points Of Interest Compass + +## Description + +Uploads all the points of interest in an area onto your watch, same as Beer Compass with more p.o.i. From 707f4a1ccdd4e3f89095529060de429d6d1fa827 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Mon, 20 Apr 2020 21:39:30 +0100 Subject: [PATCH 109/878] More fixes --- apps/buffgym/buffgym-exercise.js | 4 +- apps/buffgym/buffgym-program.js | 2 +- apps/buffgym/buffgym-programs.json | 102 +---- apps/buffgym/buffgym-programs.json.unminified | 101 +++++ apps/buffgym/buffgym-set.js | 2 +- apps/buffgym/buffgym.app.js | 420 +++++++++--------- 6 files changed, 313 insertions(+), 318 deletions(-) create mode 100644 apps/buffgym/buffgym-programs.json.unminified diff --git a/apps/buffgym/buffgym-exercise.js b/apps/buffgym/buffgym-exercise.js index b7a1e3e15..99d658571 100644 --- a/apps/buffgym/buffgym-exercise.js +++ b/apps/buffgym/buffgym-exercise.js @@ -2,10 +2,8 @@ const STARTED = 1; const RESTING = 2; const COMPLETED = 3; const ONE_SECOND = 1000; -const INCREMENT = "increment"; -const DECREMENT = "decrement"; -class Exercise { +exports = class Exercise { constructor(params /*{title, weight, unit, restPeriod}*/) { const DEFAULTS = { title: "Unknown", diff --git a/apps/buffgym/buffgym-program.js b/apps/buffgym/buffgym-program.js index 22f39f10b..956827f56 100644 --- a/apps/buffgym/buffgym-program.js +++ b/apps/buffgym/buffgym-program.js @@ -1,4 +1,4 @@ -class Program { +exports = class Program { constructor(params) { const DEFAULTS = { title: "Unknown", diff --git a/apps/buffgym/buffgym-programs.json b/apps/buffgym/buffgym-programs.json index bf5aa0e0d..7551c7a47 100644 --- a/apps/buffgym/buffgym-programs.json +++ b/apps/buffgym/buffgym-programs.json @@ -1,101 +1 @@ -[ - { - title: "Program A", - exercises: [ - { - title: "Squats", - weight: 40, - unit: "Kg", - sets: [ - 5, - 5, - 5, - 5, - 5 - ] - }, - { - title: "Overhead press", - weight: 20, - unit: "Kg", - sets: [ - 5, - 5, - 5, - 5, - 5 - ] - }, - { - title: "Deadlift", - weight: 20, - unit: "Kg", - sets: [ - 5 - ] - }, - { - title: "Pullups", - weight: 0, - unit: "Kg", - sets: [ - 10, - 10, - 10 - ] - } - ] - }, - { - title: "Program B", - exercises: [ - { - title: "Squats", - weight: 40, - unit: "Kg", - sets: [ - 5, - 5, - 5, - 5, - 5 - ] - }, - { - title: "Bench press", - weight: 20, - unit: "Kg", - sets: [ - 5, - 5, - 5, - 5, - 5 - ] - }, - { - title: "Row", - weight: 20, - unit:"Kg", - sets: [ - 5, - 5, - 5, - 5, - 5 - ] - - }, - { - title: "Tricep extension", - weight: 20, - unit: "Kg", - sets: [ - 10, - 10, - 10 - ] - } - ] - } -] \ No newline at end of file +[{"title":"Program A","exercises":[{"title":"Squats","weight":40,"unit":"Kg","sets":[5,5,5,5,5]},{"title":"Overhead press","weight":20,"unit":"Kg","sets":[5,5,5,5,5]},{"title":"Deadlift","weight":20,"unit":"Kg","sets":[5]},{"title":"Pullups","weight":0,"unit":"Kg","sets":[10,10,10]}]},{"title":"Program B","exercises":[{"title":"Squats","weight":40,"unit":"Kg","sets":[5,5,5,5,5]},{"title":"Bench press","weight":20,"unit":"Kg","sets":[5,5,5,5,5]},{"title":"Row","weight":20,"unit":"Kg","sets":[5,5,5,5,5]},{"title":"Tricep extension","weight":20,"unit":"Kg","sets":[10,10,10]}]}] \ No newline at end of file diff --git a/apps/buffgym/buffgym-programs.json.unminified b/apps/buffgym/buffgym-programs.json.unminified new file mode 100644 index 000000000..cd005eeab --- /dev/null +++ b/apps/buffgym/buffgym-programs.json.unminified @@ -0,0 +1,101 @@ +[ + { + "title": "Program A", + "exercises": [ + { + "title": "Squats", + "weight": 40, + "unit": "Kg", + "sets": [ + 5, + 5, + 5, + 5, + 5 + ] + }, + { + "title": "Overhead press", + "weight": 20, + "unit": "Kg", + "sets": [ + 5, + 5, + 5, + 5, + 5 + ] + }, + { + "title": "Deadlift", + "weight": 20, + "unit": "Kg", + "sets": [ + 5 + ] + }, + { + "title": "Pullups", + "weight": 0, + "unit": "Kg", + "sets": [ + 10, + 10, + 10 + ] + } + ] + }, + { + "title": "Program B", + "exercises": [ + { + "title": "Squats", + "weight": 40, + "unit": "Kg", + "sets": [ + 5, + 5, + 5, + 5, + 5 + ] + }, + { + "title": "Bench press", + "weight": 20, + "unit": "Kg", + "sets": [ + 5, + 5, + 5, + 5, + 5 + ] + }, + { + "title": "Row", + "weight": 20, + "unit":"Kg", + "sets": [ + 5, + 5, + 5, + 5, + 5 + ] + + }, + { + "title": "Tricep extension", + "weight": 20, + "unit": "Kg", + "sets": [ + 10, + 10, + 10 + ] + } + ] + } +] \ No newline at end of file diff --git a/apps/buffgym/buffgym-set.js b/apps/buffgym/buffgym-set.js index d7d610a78..aed6df260 100644 --- a/apps/buffgym/buffgym-set.js +++ b/apps/buffgym/buffgym-set.js @@ -1,4 +1,4 @@ -class Set { +exports = class Set { constructor(maxReps) { this._minReps = 0; this._maxReps = maxReps; diff --git a/apps/buffgym/buffgym.app.js b/apps/buffgym/buffgym.app.js index d3a4e6834..11005900a 100755 --- a/apps/buffgym/buffgym.app.js +++ b/apps/buffgym/buffgym.app.js @@ -1,230 +1,226 @@ -/* global g, setWatch, clearWatch, reset, BTN1, BTN2, BTN3 */ +const W = g.getWidth(); +const H = g.getHeight(); +const RED = "#d32e29"; +const PINK = "#f05a56"; +const WHITE = "#ffffff"; -(() => { - const W = g.getWidth(); - const H = g.getHeight(); - const RED = "#d32e29"; - const PINK = "#f05a56"; - const WHITE = "#ffffff"; +const Set = require("buffgym-set.js"); +const Exercise = require("buffgym-exercise.js"); +const Program = require("buffgym-program.js"); - const Set = require("set.js"); - const Exercise = require("exercise.js"); - const Program = require("program.js"); +function centerStringX(str) { + return (W - g.stringWidth(str)) / 2; +} - function centerStringX(str) { - return (W - g.stringWidth(str)) / 2; +function iconIncrement() { + const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglHA4IpJBYwTHA4RMJCY5oDJo4THKIQKET5IMGCaY7TMaKLTWajbTFJIlICgoVBFYXJYQYSGCggAGCRAVIBgw")); + return img; +} + +function iconDecrement() { + const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglKFJADBCRYABCYQmOFAhNMKIw6FTw4LHCaY7TMaKLTWajbTFJglFCgoVBFYXJYQYSGCggAGCRAVIBgw=")); + return img; +} + +function iconOk() { + const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglKFJADBCJQxCCYQmMIwZoDJpQMCKIg6KBYwTGFQgeHHYouCCRI7EMYTXFRhILEK5SfFRgYSIborbSbpglFCgoVBFYXJYQYSGCggAGCRAVIBgwA==")); + return img; +} + +function drawMenu(params) { + const DEFAULT_PARAMS = { + showBTN1: false, + showBTN2: false, + showBTN3: false, + }; + const p = Object.assign({}, DEFAULT_PARAMS, params); + if (p.showBTN1) g.drawImage(iconIncrement(), W - 30, 10); + if (p.showBTN2) g.drawImage(iconOk(), W - 30, 110); + if (p.showBTN3) g.drawImage(iconDecrement(), W - 30, 210); +} + +function clearScreen() { + g.setColor(RED); + g.fillRect(0,0,W,H); +} + +function drawTitle(exercise) { + const title = exercise.humanTitle; + + g.setFont("Vector",20); + g.setColor(WHITE); + g.drawString(title, centerStringX(title), 5); +} + +function drawReps(exercise) { + const set = exercise.currentSet; + if (set.isCompleted()) return; + + g.setColor(PINK); + g.fillCircle(W / 2, H / 2, 50); + g.setColor(WHITE); + g.setFont("Vector", 40); + g.drawString(set.reps, centerStringX(set.reps), (H - 45) / 2); + g.setFont("Vector", 15); + const note = `of ${set.maxReps}`; + g.drawString(note, centerStringX(note), (H / 2) + 25); +} + +function drawSets(exercise) { + const sets = exercise.subTitle; + + g.setColor(WHITE); + g.setFont("Vector", 15); + g.drawString(sets, centerStringX(sets), H - 25); +} + +function drawSetProgress(exercise) { + drawTitle(exercise); + drawReps(exercise); + drawSets(exercise); + drawMenu({showBTN1: true, showBTN2: true, showBTN3: true}); +} + +function drawStartNextExercise() { + const title = "Good work"; + const msg = "No need to rest\nmove straight on\nto the next exercise"; + + g.setColor(WHITE); + g.setFont("Vector", 35); + g.drawString(title, centerStringX(title), 10); + g.setFont("Vector", 15); + g.drawString(msg, 30, 150); + drawMenu({showBTN1: false, showBTN2: true, showBTN3: false}); +} + +function drawProgramCompleted() { + const title1 = "You did"; + const title2 = "GREAT!"; + const msg = "That's the program\ncompleted. Now eat\nsome food and\nget plenty of rest."; + + clearWatch(); + setWatch(reset, BTN2, {repeat: false}); + + g.setColor(WHITE); + g.setFont("Vector", 35); + g.drawString(title1, centerStringX(title1), 10); + g.setFont("Vector", 40); + g.drawString(title2, centerStringX(title2), 50); + g.setFont("Vector", 15); + g.drawString(msg, 30, 150); + drawMenu({showBTN1: false, showBTN2: true, showBTN3: false}); +} + +/* +function drawExerciseCompleted(program) { + const exercise = program.currentExercise(); + const title = exercise.canProgress? + "WELL DONE!" : + "NOT BAD!"; + const msg = exercise.canProgress? + `You weight is automatically increased\nfor ${exercise.title} to ${exercise.weight}${exercise.unit}` : + "It looks like you struggled\non a few sets, your weight will\nstay the same"; + const action = "Move straight on to the next exercise"; + + clearScreen(); + g.setColor(WHITE); + g.setFont("Vector", 20); + g.drawString(title, centerStringX(title), 10); + g.setFont("Vector", 10); + g.drawString(msg, centerStringX(msg), 180); + g.drawString(action, centerStringX(action), 210); + drawMenu({showBTN2: true}); + + clearWatch(); + setWatch(() => { + init(program); + }, BTN2, {repeat: false}); +} +*/ + +function drawRestTimer(program) { + const exercise = program.currentExercise(); + const motivation = "Take a breather.."; + clearScreen(); + drawMenu({showBTN2: true}); + + g.setColor(PINK); + g.fillCircle(W / 2, H / 2, 50); + g.setColor(WHITE); + g.setFont("Vector", 15); + g.drawString(motivation, centerStringX(motivation), 25); + g.setFont("Vector", 40); + g.drawString(exercise.restPeriod, centerStringX(exercise.restPeriod), (H - 45) / 2); + exercise.decRestPeriod(); + + if (exercise.restPeriod <= 0) { + exercise.resetRestTimer(); + redraw(program); + } +} + +function redraw(program) { + const exercise = program.currentExercise(); + + clearScreen(); + + if (program.isCompleted()) { + drawProgramCompleted(program); + return; } - function iconIncrement() { - const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglHA4IpJBYwTHA4RMJCY5oDJo4THKIQKET5IMGCaY7TMaKLTWajbTFJIlICgoVBFYXJYQYSGCggAGCRAVIBgw")); - return img; - } - - function iconDecrement() { - const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglKFJADBCRYABCYQmOFAhNMKIw6FTw4LHCaY7TMaKLTWajbTFJglFCgoVBFYXJYQYSGCggAGCRAVIBgw=")); - return img; - } - - function iconOk() { - const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglKFJADBCJQxCCYQmMIwZoDJpQMCKIg6KBYwTGFQgeHHYouCCRI7EMYTXFRhILEK5SfFRgYSIborbSbpglFCgoVBFYXJYQYSGCggAGCRAVIBgwA==")); - return img; - } - - function drawMenu(params) { - const DEFAULT_PARAMS = { - showBTN1: false, - showBTN2: false, - showBTN3: false, - }; - const p = Object.assign({}, DEFAULT_PARAMS, params); - if (p.showBTN1) g.drawImage(iconIncrement(), W - 30, 10); - if (p.showBTN2) g.drawImage(iconOk(), W - 30, 110); - if (p.showBTN3) g.drawImage(iconDecrement(), W - 30, 210); - } - - function clearScreen() { - g.setColor(RED); - g.fillRect(0,0,W,H); - } - - function drawTitle(exercise) { - const title = exercise.humanTitle; - - g.setFont("Vector",20); - g.setColor(WHITE); - g.drawString(title, centerStringX(title), 5); - } - - function drawReps(exercise) { - const set = exercise.currentSet; - if (set.isCompleted()) return; - - g.setColor(PINK); - g.fillCircle(W / 2, H / 2, 50); - g.setColor(WHITE); - g.setFont("Vector", 40); - g.drawString(set.reps, centerStringX(set.reps), (H - 45) / 2); - g.setFont("Vector", 15); - const note = `of ${set.maxReps}`; - g.drawString(note, centerStringX(note), (H / 2) + 25); - } - - function drawSets(exercise) { - const sets = exercise.subTitle; - - g.setColor(WHITE); - g.setFont("Vector", 15); - g.drawString(sets, centerStringX(sets), H - 25); - } - - function drawSetProgress(exercise) { - drawTitle(exercise); - drawReps(exercise); - drawSets(exercise); - drawMenu({showBTN1: true, showBTN2: true, showBTN3: true}); - } - - function drawStartNextExercise() { - const title = "Good work"; - const msg = "No need to rest\nmove straight on\nto the next exercise"; - - g.setColor(WHITE); - g.setFont("Vector", 35); - g.drawString(title, centerStringX(title), 10); - g.setFont("Vector", 15); - g.drawString(msg, 30, 150); - drawMenu({showBTN1: false, showBTN2: true, showBTN3: false}); - } - - function drawProgramCompleted() { - const title1 = "You did"; - const title2 = "GREAT!"; - const msg = "That's the program\ncompleted. Now eat\nsome food and\nget plenty of rest."; - - clearWatch(); - setWatch(reset, BTN2, {repeat: false}); - - g.setColor(WHITE); - g.setFont("Vector", 35); - g.drawString(title1, centerStringX(title1), 10); - g.setFont("Vector", 40); - g.drawString(title2, centerStringX(title2), 50); - g.setFont("Vector", 15); - g.drawString(msg, 30, 150); - drawMenu({showBTN1: false, showBTN2: true, showBTN3: false}); - } - - /* - function drawExerciseCompleted(program) { - const exercise = program.currentExercise(); - const title = exercise.canProgress? - "WELL DONE!" : - "NOT BAD!"; - const msg = exercise.canProgress? - `You weight is automatically increased\nfor ${exercise.title} to ${exercise.weight}${exercise.unit}` : - "It looks like you struggled\non a few sets, your weight will\nstay the same"; - const action = "Move straight on to the next exercise"; - - clearScreen(); - g.setColor(WHITE); - g.setFont("Vector", 20); - g.drawString(title, centerStringX(title), 10); - g.setFont("Vector", 10); - g.drawString(msg, centerStringX(msg), 180); - g.drawString(action, centerStringX(action), 210); - drawMenu({showBTN2: true}); - - clearWatch(); - setWatch(() => { - init(program); - }, BTN2, {repeat: false}); - } - */ - - function drawRestTimer(program) { - const exercise = program.currentExercise(); - const motivation = "Take a breather.."; - clearScreen(); - drawMenu({showBTN2: true}); - - g.setColor(PINK); - g.fillCircle(W / 2, H / 2, 50); - g.setColor(WHITE); - g.setFont("Vector", 15); - g.drawString(motivation, centerStringX(motivation), 25); - g.setFont("Vector", 40); - g.drawString(exercise.restPeriod, centerStringX(exercise.restPeriod), (H - 45) / 2); - exercise.decRestPeriod(); - - if (exercise.restPeriod <= 0) { - exercise.resetRestTimer(); - redraw(program); - } - } - - function redraw(program) { - const exercise = program.currentExercise(); - - clearScreen(); - - if (program.isCompleted()) { - drawProgramCompleted(program); - return; + if (exercise.isRestTimerRunning()) { + if (exercise.isLastSet()) { + drawStartNextExercise(program); + } else { + drawRestTimer(program); } - if (exercise.isRestTimerRunning()) { - if (exercise.isLastSet()) { - drawStartNextExercise(program); - } else { - drawRestTimer(program); - } - - return; - } - - drawSetProgress(exercise); + return; } - function init(program) { - clearWatch(); - program.next(); - } + drawSetProgress(exercise); +} - // Setup training program. This should come from file +function init(program) { + clearWatch(); + program.next(); +} - // Squats - function buildPrograms() { - const programsJSON = require("Storage").readJSON("buffgym-programs.json", 1); +// Setup training program. This should come from file - if (!programsJSON) throw "No programs JSON found"; +// Squats +function buildPrograms() { + const programsJSON = require("Storage").readJSON("buffgym-programs.json", 1); - const programs = []; + if (!programsJSON) throw "No programs JSON found"; - programsJSON.forEach(programJSON => { - const program = new Program({ - title: programJSON.title, - }); - const exercises = programJSON.exercises.map(exerciseJSON => { - const exercise = new Exercise({ - title: exerciseJSON.title, - weight: exerciseJSON.weight, - unit: exerciseJSON.unit, - }); - exerciseJSON.sets.forEach(setJSON => { - exercise.addSet(new Set(setJSON)); - }); + const programs = []; - return exercise; - }); - program.addExercises(exercises); - programs.push(program); + programsJSON.forEach(programJSON => { + const program = new Program({ + title: programJSON.title, }); + const exercises = programJSON.exercises.map(exerciseJSON => { + const exercise = new Exercise({ + title: exerciseJSON.title, + weight: exerciseJSON.weight, + unit: exerciseJSON.unit, + }); + exerciseJSON.sets.forEach(setJSON => { + exercise.addSet(new Set(setJSON)); + }); - return programs; - } + return exercise; + }); + program.addExercises(exercises); + programs.push(program); + }); - // For this spike, just run the first program, what will - // really happen is the user picks a program to do from - // some menu on a start page. - init(buildPrograms()[0]); -})(); \ No newline at end of file + return programs; +} + +// For this spike, just run the first program, what will +// really happen is the user picks a program to do from +// some menu on a start page. +init(buildPrograms()[0]); \ No newline at end of file From 6deb376d99b4dab29c9ec31bd78432e08b08510e Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Mon, 20 Apr 2020 22:02:55 +0100 Subject: [PATCH 110/878] Return to launcher on exit --- apps/buffgym/buffgym.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/buffgym/buffgym.app.js b/apps/buffgym/buffgym.app.js index 11005900a..e1ab3e66b 100755 --- a/apps/buffgym/buffgym.app.js +++ b/apps/buffgym/buffgym.app.js @@ -99,7 +99,7 @@ function drawProgramCompleted() { const msg = "That's the program\ncompleted. Now eat\nsome food and\nget plenty of rest."; clearWatch(); - setWatch(reset, BTN2, {repeat: false}); + setWatch(Bangle.showLauncher, BTN2, {repeat: false}); g.setColor(WHITE); g.setFont("Vector", 35); From 15a92c1b38006dfd908c91e69b060ca457d35e9b Mon Sep 17 00:00:00 2001 From: singintime Date: Tue, 21 Apr 2020 01:10:10 +0200 Subject: [PATCH 111/878] Minion clock v0.02 --- apps.json | 2 +- apps/minionclk/ChangeLog | 1 + apps/minionclk/app.js | 10 +++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps.json b/apps.json index b58fad5ce..924d2e75c 100644 --- a/apps.json +++ b/apps.json @@ -1126,7 +1126,7 @@ { "id": "minionclk", "name": "Minion clock", "icon": "minionclk.png", - "version": "0.01", + "version": "0.02", "description": "Minion themed clock.", "tags": "clock,minion", "type": "clock", diff --git a/apps/minionclk/ChangeLog b/apps/minionclk/ChangeLog index 7b83706bf..dbe920a80 100755 --- a/apps/minionclk/ChangeLog +++ b/apps/minionclk/ChangeLog @@ -1 +1,2 @@ 0.01: First release +0.02: Improved date readability, fixed drawing of widgets diff --git a/apps/minionclk/app.js b/apps/minionclk/app.js index 88fe446ae..7f00cd362 100755 --- a/apps/minionclk/app.js +++ b/apps/minionclk/app.js @@ -1,4 +1,4 @@ -const bob = require("heatshrink").decompress(atob("nk8hAaXlYLWAEsqvN/0gBBql5lQ2tquj1XV5wBJ52j0hACPsdP1QsBAQQAGBIIBF51/P8OkN5R1GIxF5HLmAFgoDLPZfOpzmZ6vPFwomCPaA6DAYOjeq2A1YyCdI4HGQJQ8F1T2SJ4Oq1XW1es1mtAQOrPoPUAIh3J54ZHIAR5S62s64cBwIBGQIOqHQK4HKQYVDAAIFC1g+BHh9VHAQAFDwQDDHoJ5E54BB6AaBKQ5YGqo6MwJzGHQ4BDeIj/BR4JxDABY8BvI6OOYgaEHwZADHgQ6BZA42GAIusPJNW64eFqzJDlcrERA8BHQI2FqwaBDYYGBPI45GCoIgCLoVWQ5NWXA2rKhaiGLAwOGEAmADxJPDVA51ElQaMC4ouEWALdEHRg8Dc4woCDJo8EAIYxCHQQIFHiwaRegJ5EcYWsHgbrKbBA8GDSrNDO4wfRKgR3FDSh3CN4UrdwZbSHYZ5DHajMFHYQGCHalWO4jtQDQwABwAGCAAQfTKoK0EHahwCeARdFHakASIZWVZ4Q8CO4YgWO4QbCO6hWGEIKYZKzZ3DLog7UG4I6C1lWDSdWO4bpCO4bwUwKYEHajMDwOAlUkLojTUd4gaTZoRWC0YIB1eJLqo4EWiqRE0mjlcr1QkEeKFWOooBCHiB2CC4WA5wzB52rEQgfPHQwABAYJXOHQ2iO4XO6omFEJh1BEAgBGPJlWDIQbC0ej50qgHV1XPEwohKcwRbEvJ3EBQTrLFomkOwOjlR3C5w8GMAR8ClYuBLIgOCvN4HgIZFDQYbBlaOBR4YNCwA5B0XOpzvBHgWqTw4AFxB1EvQ6BAAI8GDZILEdgQBCqp3DPIRfIEQwABvJ1CvGkvGiwA6IAYoBCv6wCAAVOlQ6DAIWkL5ABEwN40Z1CAYJfCv7zEAJNWOYZ3KAIWq5yYHFYLOBLIrVCAIh7BOIzpECoYDDpw7BHAQDG1WqwGkAIN/CwIABLY4LDAAZ9BwAABvLCBC5IBBvOrO44BEAAmjAIPN0XOAJyHIAAgPEquBHBi4BAId+HwWiHxqJDRpYBDq2I1R3LIAQ6BAAOpPogABGgIDDOomk0nP5pIGd42Aq1ewI8CeZI6CHAJhCEAIDCdIo2B0er1esAQIZBC4Z9JlVW1leeKGp0es5+s6+s6ABB0oFBAIervWr0ulub7OqtWmdexJ4BGxB5G0V6pF6wItB0t6p9PvQABvINBudJudPzwXCHQwBDlY6BO4WIwPPPJbvDvA0BFgNzAAIDGugGCzrtHdYh1DAIOBrzxBPIgAIeIXNHgoBCGwYADzoVB0fNOpMyHQdW5+Bro7BHgQAB6jxJAAOjOYhxCAIukOoPN5ujdZFWqyyD0d6AwUrquBwAuB1I1FHgRJBMoQ9BWg1zzw0BDYI6B0R3DAAJ1BvMyp8rAAV4IQWBIodewAeCHAZ5IAAJoBAAXHHAJWDO4TtEdYQvEHgejAwIKClcqIQRdDXYbzFeoQBIGwIDDOot/VgQ6FAAIGBlgBCAAMzmZPBF4LzDACB1FAAOi1WjvFVr0zGYQ7GAAMAAYpPBwNeAIOIwOrfYOA1eA1WkAIWjAIekv4PBwCVBruBq5eBEYIABlcBF4wCEHw55CHwQABIQQBBABkzAILlCHQR1CFYavEPgsAAAIDEDQNdAwQAaHQNWEwQ0DHAh3KleBLoI7dHQKuFWQo0EAIsISoKdBHbyyHNgwADlVVpwEBDANWro7fd4Q6HO495vF5QgIYCd75eBHYUINAN5lQ3EA")); +const bob = require("heatshrink").decompress(atob("nk8hAaXlYLWAEsqvN/0gBBql5lQ2tquj1XV5wBJ52j0hACPsdP1QsBAQQAGBIIBF51/P8OkN5R1GIxF5HLmAFgoDLPZfOpzmZ6vPFwomCPaA6DAYOjeq2A1YyCdI4HGQJQ8F1T2SJ4Oq1XW1es1mtAQOrPoPUAIh3J54ZHIAR5S62s64cBwIBGQIOqHQK4HKQYVDAAIFC1g+BHh9VHAQAFDwQDDHoJ5E54BB6AaBKQ5YGqo6MwJzGHQ4BDeIj/BR4JxDABY8BvI6OOYgaEHwZADHgQ6BZA42GAIusPJNW64eFqzJDlcrERA8BHQI2FqwaBDYYGBPI45GCoIgCLoVWQ5NWXA2rKhaiGLAwOGEAmADxJPDVA51ElQaMC4ouEWALdEHRg8Dc4woCDJo8EAIYxCHQQIFHiwaRegJ5EcYWsHgbrKbBA8GDSrNDO4wfRKgR3FDSh3CN4UrdwZbSHYZ5DHajMFHYQGCHalWO4jtQDQwABwAGCAAQfTKoK0EHahwCeARdFHakASIZWVZ4Q8CO4YgWO4QbCO6hWGEIKYZKzZ3DLog7UG4I6C1lWDSdWO4bpCO4bwUwKYEHajMDwOAlUkLojTUd4gaTZoRWC0YIB1eJLqo4EWiqRE0mjlcr1QkEeKFWOooBCHiB2CC4WA5wzB52rEQgfPHQwABAYJXOHQ2iO4XO6omFEJh1BEAgBGPJlWDIQbC0ej50qgHV1XPEwohKcwRbEvJ3EBQTrLFomkOwOjlR3C5w8GMAR8ClYuBLIgOCvN4HgIZFDQYbBlaOBR4YNCwA5B0XOpzvBHgWqTw4AFxB1EvQ6BAAI8GDZILEdgQBCqp3DPIRfIEQwABvJ1CvGkvGiwA6IAYoBCv6wCAAVOlQ6DAIWkL5ABEwN40Z1CAYJfCv7zEAJNWOYZ3KAIWq5yYHFYLOBLIrVCAIh7BOIzpECoYDDpw7BHAQDG1WqwGkAIN/CwIABLY4LDAAZ9BwAABvLCBC5IBBvOrO44BEAAmjAIPN0XOAJyHIAAgPEquBHBi4BAId+HwWiHxqJDRpYBDq2I1R3LIAQ6BAAOpPogABGgIDDOomk0nP5pIGd42Aq1ewI8CeZI6CHAJhCEAIDCdIo2B0er1esAQIZBC4Z9JlVW1leeKGp0es5+s6+s6ABB0oFBAIervWr0ultr7OqtWmdexJ4BGxB5G0V6pF6wItB0t6p9PvQABvINBttJttPzwXCHQwBDlY6BO4WIwPPPJbvDvA0BFgNtAAIDGtwGCzrtHdYh1DAIOBrzxBPIgAIeIXNHgoBCGwYADzoVB0fNOpMOHQdW5+Bro7BHgQAB6jxJAAOjOYhxCAIukOoPN5ujdZFWqyyD0d6AwUrquBwAuB1I1FHgRJBMoQ9BWg1tzw0BDYI6B0R3DAAJ1BvMOp8rAAV4IQWBIodewAeCHAZ5IAAJoBAAXHHAJWDO4TtEdYQvEHgejAwIKClcqIQRdDXYbzFeoQBIGwIDDOot/VgQ6FAAIGBlgBCAAMzmZPBF4LzDACB1FAAOi1WjvFVr0zGYQ7GAAMAAYpPBwNeAIOIwOrfYOA1eA1WkAIWjAIekv4PBwCVBruBq5eBEYIABlcBF4wCEHw8zgAAiFYivEPgoSEAYo9jGgY4EO5Q7kVwiyFGggBFhASBHkhsKAAcqqtOAgMzd8o6HO495vF5QgMzrw7lhBoBvMqG4g")); const locale = require("locale"); @@ -37,7 +37,7 @@ function draw() { } if (newDate !== date) { - g.setFontVector(12); + g.setFont('6x8', 2); g.setColor(black); g.drawString(date, 120, 228); g.setColor(0xFFFF); @@ -51,6 +51,8 @@ function drawAll() { minute = ''; date = ''; g.drawImage(bob, 0, 0, { scale: 4 }); + Bangle.loadWidgets(); + Bangle.drawWidgets(); draw(); } @@ -60,9 +62,7 @@ Bangle.on('lcdPower', function(on) { } }); -Bangle.loadWidgets(); -Bangle.drawWidgets(); setInterval(draw, 1000); drawAll(); -setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); +setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: 'falling' }); From bc4a05e314c1efd71d66a44788ee04ac81bb9cc8 Mon Sep 17 00:00:00 2001 From: singintime Date: Tue, 21 Apr 2020 10:43:54 +0200 Subject: [PATCH 112/878] Addressing review comments --- apps/minionclk/app.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/minionclk/app.js b/apps/minionclk/app.js index 7f00cd362..0f92b28bc 100755 --- a/apps/minionclk/app.js +++ b/apps/minionclk/app.js @@ -9,6 +9,8 @@ let hour; let minute; let date; +let timer; + function draw() { const d = new Date(); @@ -51,7 +53,6 @@ function drawAll() { minute = ''; date = ''; g.drawImage(bob, 0, 0, { scale: 4 }); - Bangle.loadWidgets(); Bangle.drawWidgets(); draw(); } @@ -59,10 +60,13 @@ function drawAll() { Bangle.on('lcdPower', function(on) { if (on) { drawAll(); + timer = setInterval(draw, 1000); + } else if (timer) { + clearInterval(timer); } }); -setInterval(draw, 1000); +Bangle.loadWidgets(); drawAll(); setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: 'falling' }); From a8cf48c794706420404136190fbdfede3e6080b4 Mon Sep 17 00:00:00 2001 From: singintime Date: Tue, 21 Apr 2020 11:52:36 +0200 Subject: [PATCH 113/878] Addressing review comments 2 --- apps/minionclk/app.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/apps/minionclk/app.js b/apps/minionclk/app.js index 0f92b28bc..0725f8fa6 100755 --- a/apps/minionclk/app.js +++ b/apps/minionclk/app.js @@ -48,25 +48,30 @@ function draw() { } } -function drawAll() { +function startDrawing() { hour = ''; minute = ''; date = ''; g.drawImage(bob, 0, 0, { scale: 4 }); Bangle.drawWidgets(); draw(); + setInterval(draw, 1000); +} + +function stopDrawing() { + if (timer) { + clearInterval(timer); + } } Bangle.on('lcdPower', function(on) { + stopDrawing(); if (on) { - drawAll(); - timer = setInterval(draw, 1000); - } else if (timer) { - clearInterval(timer); + startDrawing(); } }); Bangle.loadWidgets(); -drawAll(); +startDrawing(); setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: 'falling' }); From 7735a2ba97d6156c79450869a7f716d52cd9cffb Mon Sep 17 00:00:00 2001 From: fredericrous Date: Tue, 21 Apr 2020 11:18:29 +0100 Subject: [PATCH 114/878] =?UTF-8?q?New=20game:=20Pong=F0=9F=95=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps.json | 14 +++ apps/pong/ChangeLog | 1 + apps/pong/app-icon.js | 1 + apps/pong/app.js | 282 ++++++++++++++++++++++++++++++++++++++++++ apps/pong/pong.png | Bin 0 -> 894 bytes 5 files changed, 298 insertions(+) create mode 100644 apps/pong/ChangeLog create mode 100644 apps/pong/app-icon.js create mode 100644 apps/pong/app.js create mode 100644 apps/pong/pong.png diff --git a/apps.json b/apps.json index 95669f250..9b381e6f4 100644 --- a/apps.json +++ b/apps.json @@ -1424,5 +1424,19 @@ {"name":"osmpoi.app.js"}, {"name":"osmpoi.img"} ] + }, + { "id": "pong", + "name": "Pong", + "shortName": "Pong", + "icon": "pong.png", + "version": "0.01", + "description": "A clone of the Atari game Pong", + "tags": "game", + "type": "app", + "allow_emulator": true, + "storage": [ + {"name":"pong.app.js","url":"app.js"}, + {"name":"pong.img","url":"app-icon.js","evaluate":true} + ] } ] diff --git a/apps/pong/ChangeLog b/apps/pong/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/pong/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/pong/app-icon.js b/apps/pong/app-icon.js new file mode 100644 index 000000000..881e60ba9 --- /dev/null +++ b/apps/pong/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgIEBgOABQYFD8AUEApoXFDqIXV4BYGKZIANsIRE+IFE/IFEvCIFGrgXLDqIAOgc/9/2hv+g8///3AoUwvE3xuABYP4m3NzwFB7E2tu/CIMYm09wYFDjoFCj4pB/8HkEP+EBFII7EAosDJxYA=")) diff --git a/apps/pong/app.js b/apps/pong/app.js new file mode 100644 index 000000000..4531b3af8 --- /dev/null +++ b/apps/pong/app.js @@ -0,0 +1,282 @@ +/** + * BangleJS Pong game + * + * Original Author: Frederic Rousseau https://github.com/fredericrous + * Created: April 2020 + * + * Inspired by: + * - Let's make pong, One Man Army Studios, Youtube + * - Pong.js, KanoComputing, Github + * - Coding Challenge #67: Pong!, The Coding Train, Youtube + */ + +const SCREEN_WIDTH = 240; +const FPS = 16; +const MAX_SCORE = 11; +let scores = [0, 0]; +let aiSpeedRandom = 0; + +function Vector(x, y) { + this.x = x; + this.y = y; +} +Vector.prototype.add = function (x) { + this.x += x.x || 0; + this.y += x.y || 0; + return this; +}; + +const constrain = (n, low, high) => Math.max(Math.min(n, high), low); +const random = (min, max) => Math.random() * (max - min) + min; +const intersects = (circ, rect) => { + var c1 = circ.pos, c2 = {x: circ.pos.x+circ.r, y: circ.pos.y+circ.r}; + var r1 = rect.pos, r2 = {x: rect.pos.x+rect.width*2, y: rect.pos.y+rect.height}; + return !(c1.x > r2.x || c2.x < r1.x || + c1.y > r2.y || c2.y < r1.y); +}; + +///////////////////////////// Ball ////////////////////////////////////////// + +function Ball() { + this.r = 4; + this.prevPos = null; + this.originalSpeed = 4; + this.maxSpeed = 6; + + this.reset(); +} +Ball.prototype.show = function () { + if (this.prevPos != null) { + g.setColor(0); + g.fillCircle(this.prevPos.x, this.prevPos.y, this.prevPos.r); + } + g.setColor(-1); + g.fillCircle(this.pos.x, this.pos.y, this.r); + this.prevPos = { + x: this.pos.x, + y: this.pos.y, + r: this.r + }; +}; +Ball.prototype.bouncePlayer = function (multiplyX, multiplyY, player) { + this.speed = constrain(this.speed + 2, this.originalSpeed, this.maxSpeed); + var relativeIntersectY = (player.pos.y+(player.height/2)) - this.pos.y; + var normalizedRelativeIntersectionY = (relativeIntersectY/(player.height/2)); + var MAX_BOUNCE_ANGLE = 4 * Math.PI/12; + var bounceAngle = normalizedRelativeIntersectionY * MAX_BOUNCE_ANGLE; + this.velocity.x = this.speed * Math.cos(bounceAngle) * multiplyX; + this.velocity.y = this.speed * -Math.sin(bounceAngle) * multiplyY; +}; +Ball.prototype.bounce = function (multiplyX, multiplyY, player) { + if (player) + return this.bouncePlayer(multiplyX, multiplyY, player); + + if (multiplyX) { + this.velocity.x = Math.abs(this.velocity.x) * multiplyX; + } + if (multiplyY) { + this.velocity.y = Math.abs(this.velocity.y) * multiplyY; + } +}; +Ball.prototype.checkWallsCollision = function () { + if (this.pos.y < 0) { + this.bounce(0, 1); + } else if (this.pos.y > SCREEN_WIDTH) { + this.bounce(0, -1); + } else if (this.pos.x < 0) { + scores[1]++; + if (scores[1] >= MAX_SCORE) { + this.restart(); + state = 3; + winnerMessage = "AI Wins!"; + } else { + this.reset(); + } + } else if (this.pos.x > SCREEN_WIDTH) { + scores[0]++; + if (scores[0] >= MAX_SCORE) { + this.restart(); + state = 3; + winnerMessage = "You Win!"; + } else { + this.reset(); + } + } else { + return false; + } + return true; +}; +Ball.prototype.checkPlayerCollision = function (player) { + if (intersects(this, player)) { + if (this.pos.x < SCREEN_WIDTH/2) { + this.bounce(1, 1, player); + this.pos.add(new Vector(this.width, 0)); + aiSpeedRandom = random(-1.6, 1.6); + } else { + this.bounce(-1, 1, player); + this.pos.add(new Vector(-(this.width / 2 + 1), 0)); + } + return true; + } + return false; +}; +Ball.prototype.checkCollisions = function () { + return this.checkWallsCollision() || this.checkPlayerCollision(player) || this.checkPlayerCollision(ai); +}; +Ball.prototype.updatePosition = function () { + var elapsed = new Date().getTime() - this.lastUpdate; + var x = (elapsed / 50) * this.velocity.x; + var y = (elapsed / 50) * this.velocity.y; + this.pos.add(new Vector(x, y)); +}; +Ball.prototype.update = function () { + this.updatePosition(); + this.lastUpdate = new Date().getTime(); + this.checkCollisions(); +}; +Ball.prototype.reset = function() { + this.speed = this.originalSpeed; + var x = scores[0] < scores[1] || (scores[0] === 0 && scores[1] === 0) ? -this.speed : this.speed; + var bounceAngle = Math.PI/6; + this.velocity = new Vector(x * Math.cos(bounceAngle), this.speed * -Math.sin(bounceAngle)); + this.pos = new Vector(SCREEN_WIDTH/2, random(0, SCREEN_WIDTH)); +}; +Ball.prototype.restart = function() { + ai.pos = new Vector(SCREEN_WIDTH - ai.width*2, SCREEN_WIDTH/2 - ai.height/2); + player.pos = new Vector(player.width*2, SCREEN_WIDTH/2 - player.height/2); + this.pos = new Vector(SCREEN_WIDTH/2, SCREEN_WIDTH/2); +}; + +//////////////////////////// Player ///////////////////////////////////////// + +function Player() { + this.width = 4; + this.height = 30; + this.pos = new Vector(this.width*2, SCREEN_WIDTH/2 - this.height/2); + this.acc = new Vector(0, 0); + this.speed = 15; + this.maxSpeed = 25; + this.prevPos = null; +} +Player.prototype.show = function () { + if (this.prevPos != null) { + g.setColor(0); + g.fillRect(this.prevPos.x1, this.prevPos.y1, this.prevPos.x2, this.prevPos.y2); + } + g.setColor(-1); + g.fillRect(this.pos.x, this.pos.y, this.pos.x+this.width, this.pos.y+this.height); + this.prevPos = { + x1: this.pos.x, + y1: this.pos.y, + x2: this.pos.x+this.width, + y2: this.pos.y+this.height + }; +}; +Player.prototype.up = function () { + this.acc.y -= this.speed; +}; +Player.prototype.down = function () { + this.acc.y += this.speed; +}; +Player.prototype.stop = function () { + this.acc.y = 0; +}; +Player.prototype.update = function () { + this.acc.y = constrain(this.acc.y, -this.maxSpeed, this.maxSpeed); + this.pos.add(this.acc); + this.pos.y = constrain(this.pos.y, 0, SCREEN_WIDTH-this.height); +}; + +////////////////////////////// AI /////////////////////////////////////////// + +function AI() { + Player.call(this); + this.pos = new Vector(SCREEN_WIDTH-this.width*2, SCREEN_WIDTH/2 - this.height/2); +} +AI.prototype = Object.create(Player.prototype); +AI.prototype.constructor = Player; +AI.prototype.update = function () { + var y = ball.pos.y - (this.height/2 * aiSpeedRandom); + var yConstrained = constrain(y, 0, SCREEN_WIDTH-this.height); + this.pos = new Vector(this.pos.x, yConstrained); +}; + +function net() { + var dashSize = 5; + for (let y = dashSize/2; y < SCREEN_WIDTH; y += dashSize*2) { + g.setColor(-1); + let halfScreen = SCREEN_WIDTH/2; + g.fillRect(halfScreen-dashSize/2, y, halfScreen+dashSize/2, y+dashSize); + } +} + +var player = new Player(); +var ai = new AI(); +var ball = new Ball(); +var state = 0; +var prevScores = [0, 0]; + +function drawScores() { + let x1 = SCREEN_WIDTH/4-5; + let x2 = SCREEN_WIDTH*3/4-5; + + g.setColor(0); + g.setFont('Vector', 20); + g.drawString(prevScores[0], x1, 7); + g.drawString(prevScores[1], x2, 7); + g.setColor(-1); + g.setFont('Vector', 20); + g.drawString(scores[0], x1, 7); + g.drawString(scores[1], x2, 7); + prevScores = scores.slice(); +} + +function drawGameOver() { + g.setFont("Vector", 20); + g.drawString(winnerMessage, 75, SCREEN_WIDTH/2 - 10); +} + +function draw() { + if (state === 1) { + ball.update(); + player.update(); + ai.update(); + ball.show(); + player.show(); + ai.show(); + net(); + ball.show(); + } else if (state === 3) { + g.clear(); + g.setColor(0); + g.fillRect(0,0,240,240); + state++; + } else if (state === 4) { + drawGameOver(); + } else { + player.show(); + ai.show(); + net(); + } + drawScores(); +} + +g.clear(); +g.setColor(0); +g.fillRect(0,0,240,240); + +setInterval(draw, 1000 / FPS); + +setWatch(o => o.state ? player.up() : player.stop(), BTN1, {repeat: true, edge: 'both'}); +setWatch(o => o.state ? player.down() : player.stop(), BTN3, {repeat: true, edge: 'both'}); +//setWatch(o => o.state ? player.down() : player.stop(), BTN5, {repeat: true, edge: 'both'}); +setWatch(o => { + state++; + if (state >= 2) { + ball.restart(); + g.setColor(0); + g.fillRect(0,0,240,240); + scores = [0, 0]; + state = 1; + } +}, BTN2, {repeat: true}); diff --git a/apps/pong/pong.png b/apps/pong/pong.png new file mode 100644 index 0000000000000000000000000000000000000000..cc97f58f7826efaf0e2fafa1b7322a4d17d86f2c GIT binary patch literal 894 zcmV-^1A+XBP)fQkj&A4+ z8^a&FIPdd5`=9@LKc4dekPw)j2~5u*kvfUS5ju7aCH~Xa(S0~!hr{V`I8pjKq9KH! znX*PhOQWF$i4+<`YPCwORw0qfyG4B(iOThBSCQ!C@wPuAgMA0;}Q^Gn(3nfI?o>1%Xt0A&)LYqt!7?yz6xjKWMe}S#5neaHCKt872;E z#Khzj7th(EcDr2*!9@VT-|cOJIRCcy9gMG1^eROoF?1NlyZQ zrf1JvxtK<)(`a>h;tdpdVLXLIg^9C%zyJI45)!pS1Yu!B^MH0yMk3KcW+<0c@t9*$ zI02g^DI*AJdbi89^M0dL3V%p&xtt^^0|3x8#g7XH_oLC!0zXtF-^WQ(_B$3!2w^l? zYU}C+yAp|nQmGpF@Nqp9PB|A0lB8@s6c+r|*41;#Z5`cE4K{bSJwZstIR2)`8jVD_ zJQ0RHe)JFkfMG=dfYujne^{35JtL7kxPK2Gi^cfFl>g?9@)TPHAuTH{ne+uVH-FO9 zp3z!f+V>`ttV7XAq`9eqYbup0Xb3Xqal`3@7)=)LI2L18R#w+TVTD|tK26?nFJCqz zNkbL4Dn!^zI1C~TlSm}lt9ZvgVHjpKTSiBQ?e_lk1fA~grOQ{iX29>`Uml;Nq2jZW z;;Kr1Unso6vT-Og zb*`**@!Jy1vPDH$N@BC2!Dj7+$DLiB2k2ybFT-)1zxhR2>M0?bJJoKFr>wLj6yD&+ zX`0Hi3S?_&U?8if3!0`Ba=FoL;fji0U!&L8@N>jsJcFUNwIBAup@82fm=W;%Oy;M8 zT`rds$MLz@Jx|j#O^uEW&&|$2S;0Sk_Ks(|wA>+37<0?7t*z;=v-vw<`2_&rA3^G( Uj#*TE-v9sr07*qoM6N<$g3p|vv;Y7A literal 0 HcmV?d00001 From 6f00f0ee0b25d504a69be770ed70d3af0bb7d830 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 21 Apr 2020 11:35:32 +0100 Subject: [PATCH 115/878] minor tweaks --- apps/minionclk/app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/minionclk/app.js b/apps/minionclk/app.js index 0725f8fa6..3453f49e1 100755 --- a/apps/minionclk/app.js +++ b/apps/minionclk/app.js @@ -1,5 +1,3 @@ -const bob = require("heatshrink").decompress(atob("nk8hAaXlYLWAEsqvN/0gBBql5lQ2tquj1XV5wBJ52j0hACPsdP1QsBAQQAGBIIBF51/P8OkN5R1GIxF5HLmAFgoDLPZfOpzmZ6vPFwomCPaA6DAYOjeq2A1YyCdI4HGQJQ8F1T2SJ4Oq1XW1es1mtAQOrPoPUAIh3J54ZHIAR5S62s64cBwIBGQIOqHQK4HKQYVDAAIFC1g+BHh9VHAQAFDwQDDHoJ5E54BB6AaBKQ5YGqo6MwJzGHQ4BDeIj/BR4JxDABY8BvI6OOYgaEHwZADHgQ6BZA42GAIusPJNW64eFqzJDlcrERA8BHQI2FqwaBDYYGBPI45GCoIgCLoVWQ5NWXA2rKhaiGLAwOGEAmADxJPDVA51ElQaMC4ouEWALdEHRg8Dc4woCDJo8EAIYxCHQQIFHiwaRegJ5EcYWsHgbrKbBA8GDSrNDO4wfRKgR3FDSh3CN4UrdwZbSHYZ5DHajMFHYQGCHalWO4jtQDQwABwAGCAAQfTKoK0EHahwCeARdFHakASIZWVZ4Q8CO4YgWO4QbCO6hWGEIKYZKzZ3DLog7UG4I6C1lWDSdWO4bpCO4bwUwKYEHajMDwOAlUkLojTUd4gaTZoRWC0YIB1eJLqo4EWiqRE0mjlcr1QkEeKFWOooBCHiB2CC4WA5wzB52rEQgfPHQwABAYJXOHQ2iO4XO6omFEJh1BEAgBGPJlWDIQbC0ej50qgHV1XPEwohKcwRbEvJ3EBQTrLFomkOwOjlR3C5w8GMAR8ClYuBLIgOCvN4HgIZFDQYbBlaOBR4YNCwA5B0XOpzvBHgWqTw4AFxB1EvQ6BAAI8GDZILEdgQBCqp3DPIRfIEQwABvJ1CvGkvGiwA6IAYoBCv6wCAAVOlQ6DAIWkL5ABEwN40Z1CAYJfCv7zEAJNWOYZ3KAIWq5yYHFYLOBLIrVCAIh7BOIzpECoYDDpw7BHAQDG1WqwGkAIN/CwIABLY4LDAAZ9BwAABvLCBC5IBBvOrO44BEAAmjAIPN0XOAJyHIAAgPEquBHBi4BAId+HwWiHxqJDRpYBDq2I1R3LIAQ6BAAOpPogABGgIDDOomk0nP5pIGd42Aq1ewI8CeZI6CHAJhCEAIDCdIo2B0er1esAQIZBC4Z9JlVW1leeKGp0es5+s6+s6ABB0oFBAIervWr0ultr7OqtWmdexJ4BGxB5G0V6pF6wItB0t6p9PvQABvINBttJttPzwXCHQwBDlY6BO4WIwPPPJbvDvA0BFgNtAAIDGtwGCzrtHdYh1DAIOBrzxBPIgAIeIXNHgoBCGwYADzoVB0fNOpMOHQdW5+Bro7BHgQAB6jxJAAOjOYhxCAIukOoPN5ujdZFWqyyD0d6AwUrquBwAuB1I1FHgRJBMoQ9BWg1tzw0BDYI6B0R3DAAJ1BvMOp8rAAV4IQWBIodewAeCHAZ5IAAJoBAAXHHAJWDO4TtEdYQvEHgejAwIKClcqIQRdDXYbzFeoQBIGwIDDOot/VgQ6FAAIGBlgBCAAMzmZPBF4LzDACB1FAAOi1WjvFVr0zGYQ7GAAMAAYpPBwNeAIOIwOrfYOA1eA1WkAIWjAIekv4PBwCVBruBq5eBEYIABlcBF4wCEHw8zgAAiFYivEPgoSEAYo9jGgY4EO5Q7kVwiyFGggBFhASBHkhsKAAcqqtOAgMzd8o6HO495vF5QgMzrw7lhBoBvMqG4g")); - const locale = require("locale"); const black = 0x0000; @@ -52,15 +50,17 @@ function startDrawing() { hour = ''; minute = ''; date = ''; + var bob = require("heatshrink").decompress(atob("nk8hAaXlYLWAEsqvN/0gBBql5lQ2tquj1XV5wBJ52j0hACPsdP1QsBAQQAGBIIBF51/P8OkN5R1GIxF5HLmAFgoDLPZfOpzmZ6vPFwomCPaA6DAYOjeq2A1YyCdI4HGQJQ8F1T2SJ4Oq1XW1es1mtAQOrPoPUAIh3J54ZHIAR5S62s64cBwIBGQIOqHQK4HKQYVDAAIFC1g+BHh9VHAQAFDwQDDHoJ5E54BB6AaBKQ5YGqo6MwJzGHQ4BDeIj/BR4JxDABY8BvI6OOYgaEHwZADHgQ6BZA42GAIusPJNW64eFqzJDlcrERA8BHQI2FqwaBDYYGBPI45GCoIgCLoVWQ5NWXA2rKhaiGLAwOGEAmADxJPDVA51ElQaMC4ouEWALdEHRg8Dc4woCDJo8EAIYxCHQQIFHiwaRegJ5EcYWsHgbrKbBA8GDSrNDO4wfRKgR3FDSh3CN4UrdwZbSHYZ5DHajMFHYQGCHalWO4jtQDQwABwAGCAAQfTKoK0EHahwCeARdFHakASIZWVZ4Q8CO4YgWO4QbCO6hWGEIKYZKzZ3DLog7UG4I6C1lWDSdWO4bpCO4bwUwKYEHajMDwOAlUkLojTUd4gaTZoRWC0YIB1eJLqo4EWiqRE0mjlcr1QkEeKFWOooBCHiB2CC4WA5wzB52rEQgfPHQwABAYJXOHQ2iO4XO6omFEJh1BEAgBGPJlWDIQbC0ej50qgHV1XPEwohKcwRbEvJ3EBQTrLFomkOwOjlR3C5w8GMAR8ClYuBLIgOCvN4HgIZFDQYbBlaOBR4YNCwA5B0XOpzvBHgWqTw4AFxB1EvQ6BAAI8GDZILEdgQBCqp3DPIRfIEQwABvJ1CvGkvGiwA6IAYoBCv6wCAAVOlQ6DAIWkL5ABEwN40Z1CAYJfCv7zEAJNWOYZ3KAIWq5yYHFYLOBLIrVCAIh7BOIzpECoYDDpw7BHAQDG1WqwGkAIN/CwIABLY4LDAAZ9BwAABvLCBC5IBBvOrO44BEAAmjAIPN0XOAJyHIAAgPEquBHBi4BAId+HwWiHxqJDRpYBDq2I1R3LIAQ6BAAOpPogABGgIDDOomk0nP5pIGd42Aq1ewI8CeZI6CHAJhCEAIDCdIo2B0er1esAQIZBC4Z9JlVW1leeKGp0es5+s6+s6ABB0oFBAIervWr0ultr7OqtWmdexJ4BGxB5G0V6pF6wItB0t6p9PvQABvINBttJttPzwXCHQwBDlY6BO4WIwPPPJbvDvA0BFgNtAAIDGtwGCzrtHdYh1DAIOBrzxBPIgAIeIXNHgoBCGwYADzoVB0fNOpMOHQdW5+Bro7BHgQAB6jxJAAOjOYhxCAIukOoPN5ujdZFWqyyD0d6AwUrquBwAuB1I1FHgRJBMoQ9BWg1tzw0BDYI6B0R3DAAJ1BvMOp8rAAV4IQWBIodewAeCHAZ5IAAJoBAAXHHAJWDO4TtEdYQvEHgejAwIKClcqIQRdDXYbzFeoQBIGwIDDOot/VgQ6FAAIGBlgBCAAMzmZPBF4LzDACB1FAAOi1WjvFVr0zGYQ7GAAMAAYpPBwNeAIOIwOrfYOA1eA1WkAIWjAIekv4PBwCVBruBq5eBEYIABlcBF4wCEHw8zgAAiFYivEPgoSEAYo9jGgY4EO5Q7kVwiyFGggBFhASBHkhsKAAcqqtOAgMzd8o6HO495vF5QgMzrw7lhBoBvMqG4g")); g.drawImage(bob, 0, 0, { scale: 4 }); Bangle.drawWidgets(); draw(); - setInterval(draw, 1000); + timer = setInterval(draw, 1000); } function stopDrawing() { if (timer) { clearInterval(timer); + timer = undefined; } } From 4a53e768d60837f2554e0b1935529aadc16e8662 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Tue, 21 Apr 2020 14:03:17 +0200 Subject: [PATCH 116/878] change img_nofix --- apps/osmpoi/osmpoi.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/osmpoi/osmpoi.html b/apps/osmpoi/osmpoi.html index 56a1f8eb6..e0275784e 100644 --- a/apps/osmpoi/osmpoi.html +++ b/apps/osmpoi/osmpoi.html @@ -141,7 +141,7 @@ }); document.getElementById("upload").addEventListener("click", function() { var app = `var features = ${JSON.stringify(features)}; -var img_nofix = require("heatshrink").decompress(atob("mEwxH+AH4A0PgYurg9kr0rGM4nBg9dsgADmUHGUYtHAAddGIJcgFpIxEMTsAlYtMAAZiaLh4AFmQwXLiSTaLiosBnMymUrGCYTBAAgvPCgjwaMh4raF/4v/F/4vUg4vulZgDgAAIF8EyEQUAh0cAAkVisHGA4+HF6gVBiwwFjkONo0HAAMOAAIvTnIhEiovMFQQADNgYvQroUDg4uGjj9EF448DF6a+HAAS+EF5CQCF6SMIeAQvFXYYwHF59eLpSOBF4hgKGAIvPskAFxKOFF80VM4KOFSBs5F6EWRY4xBF43+F5UyF6DuEizZBKwIuHSBQvXdIwvKMYsHlYvQW4IuPYAYRBMggvRgIvCFxwwCTYZlEg4vPlcHjkVFx6WJF6YuXMoTwCF58yVgIvXY4YvQrqqDGDAvvPYIvPsguaYQYv/F7owBF/4vfg4AGTIIAHF7gA/AH4AwA=")); +var img_nofix = require("heatshrink").decompress(atob("mEwxH+6+s6/+AB4TB1gGFq1WlYABAgOBEQQnH68rlQRBD4orGwIkDleBAwQoBEgIABCAY4CgAjGwNbw1bmJFCDYIrGB4OwAIUAGIIrDCIICBA4WBlcxquBF4uslex2AABGYgrE2GxB4WAFoY8ClS0BPwJLCBgUAqyAGlYuCAAmGxgqDF4ZdBEIJSBHoWGwACBAANbTwRqBAYIwFqxTCAAmMF4+GlSDBq0qqotEGYQxDlVWGATBFYAJgIFYIvEJoSKBE4gADxgFESgIwC67AFF51VDQKMBFxAAErg0BGATQBYBy7D2OrlRJBgCGFLgVcGZEqOoKRFYBOGF4WymIXCqovCAQmwrYDBxgJGI4RgEYBQvBGAKlBUILnHdQaPEYQhgGwMxBgQuDRQIvCwCnBqwQCEwY/BFQeAFgQvEmJJBwOBR4dcLIQAD2J6BF4KODEAQhBwA0CSwoMBBAIxClcASAgeCRo2rDIICBOQKOBWoTLBFYYDBrdVG4NVFgK/EDQIrBF4IeCAApbBEgOydwIvBmJuFAAYJBFwIVBAAeMrlWRoIvDwNVF5AeB62xUgVVBAIsGPIRpBHoovBFwIvEXwYvHd4SPDb4ThEAob4DZoQvBDAIvEXwQkBFwpIBAQKPDCILeBwGAEYQnCdQIGDGAcq69WX4YdBKgQAE2GM1YDB2NVIgS0CABFcXwZnDFQJ6Cqy+HMQZeCGoLWBI4KDDAA46EF4VVC4LaCwK+BwBaDAAi+DAgIVCMAJeJAooGBXwusF4JMBQwLAFA4srCwVVCgK4DAQOwrYDErgQBFQJIBAQSPBra3BGIL/CF4ICBA4QoBMAhXCYg2AFwI0CR4MqI4NWRwLvDLQQAB1erD4IuBM4cxDAUxLYKDCFIdVNYT0DmJeF/x8BRgoABdwQAEmLZBGAMrQAIoBLIoAEFwi9BAATwDE4gwBAwlVDIIACq0qFwYRBLQZqClRDCbAIuDYARbCMAgZCqqnBFwgABYYMxBoIwBMAZqBFQJdCqwuEYAQsCFwexrcACYMqgAtFEAIxCAAKGBAAYMEUwIvFM4OMFoY0Bw0AC4RGCLgokD1msG4OBAgIVDler2LtDYAi3FFwgACVQQuBCQOAEQNWFYJrEfgMrwBSCdwrACqouLa4QAB2DKBCIVbRosxagOx2SuDd4ovBmLSBFxRhCrYuBAASmBAAQ4DVoeG1eGqrAGq1cCQLqBFxPXP4ImBOIYADAoOMFoIrBBAWwmKPFP4LKBLpYvCmIlBaQheDNA4ABd4z7B2OAFxmsgBVCF4xbBFo4SBla+GrZdNFwL/BWoYvHAwruCXw8xFyBeIFAIKDFoYABXw3+lYuRF44lCBQIEDXxWBFyQvJFwa+MEAIuNqx7EF4oqC2OrFwy+HqxdOFoewwAvBGwjuHAAWMla+FAwIuKlVb2OMwFVlcrqwCBqozCMAeML4WGrgTDXwsrL5IuBldbC4WBIIKmCwIzFAAI/ECYi/GMA4uBlQXKDQYzCIQITNAAOBGAwuBNIIXLGYwTRGAouCFqIAVGAJyBwIupGATRBewIrmA==")); var img_fix = require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AG2JnYv/FzovBGFgvuFwIvCGFQvuFwQvDGFAvuFwYvEGEwvuFwgvFGEgvuFwovGGEQvuFwwvHGEAvuFw4vIGDwvuFxAvJGDgvuFxIvKGDQvuFxQvLGDAvuFxYvMGCwvuFxgvNGCgvuFxovOGCQvuFxwvPGCAvuFx4vQGBwtOCQYvbFRwAJGCwqTGh4uMFS40LEcIA/AH4A/ACQA=")); // https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js From 2814e367c0dda1cb3787f1f151416372d16f5c65 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Tue, 21 Apr 2020 14:09:03 +0200 Subject: [PATCH 117/878] Update ChangeLog --- apps/osmpoi/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/osmpoi/ChangeLog b/apps/osmpoi/ChangeLog index 5560f00bc..8e73a192e 100644 --- a/apps/osmpoi/ChangeLog +++ b/apps/osmpoi/ChangeLog @@ -1 +1,2 @@ 0.01: New App! +0.02: Change img when no fix From 25f2e3d99732017e64b86e3dfcca212d19f3684a Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Tue, 21 Apr 2020 14:32:55 +0200 Subject: [PATCH 118/878] Update osmpoi.html --- apps/osmpoi/osmpoi.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/osmpoi/osmpoi.html b/apps/osmpoi/osmpoi.html index e0275784e..b4a954c24 100644 --- a/apps/osmpoi/osmpoi.html +++ b/apps/osmpoi/osmpoi.html @@ -142,7 +142,7 @@ document.getElementById("upload").addEventListener("click", function() { var app = `var features = ${JSON.stringify(features)}; var img_nofix = require("heatshrink").decompress(atob("mEwxH+6+s6/+AB4TB1gGFq1WlYABAgOBEQQnH68rlQRBD4orGwIkDleBAwQoBEgIABCAY4CgAjGwNbw1bmJFCDYIrGB4OwAIUAGIIrDCIICBA4WBlcxquBF4uslex2AABGYgrE2GxB4WAFoY8ClS0BPwJLCBgUAqyAGlYuCAAmGxgqDF4ZdBEIJSBHoWGwACBAANbTwRqBAYIwFqxTCAAmMF4+GlSDBq0qqotEGYQxDlVWGATBFYAJgIFYIvEJoSKBE4gADxgFESgIwC67AFF51VDQKMBFxAAErg0BGATQBYBy7D2OrlRJBgCGFLgVcGZEqOoKRFYBOGF4WymIXCqovCAQmwrYDBxgJGI4RgEYBQvBGAKlBUILnHdQaPEYQhgGwMxBgQuDRQIvCwCnBqwQCEwY/BFQeAFgQvEmJJBwOBR4dcLIQAD2J6BF4KODEAQhBwA0CSwoMBBAIxClcASAgeCRo2rDIICBOQKOBWoTLBFYYDBrdVG4NVFgK/EDQIrBF4IeCAApbBEgOydwIvBmJuFAAYJBFwIVBAAeMrlWRoIvDwNVF5AeB62xUgVVBAIsGPIRpBHoovBFwIvEXwYvHd4SPDb4ThEAob4DZoQvBDAIvEXwQkBFwpIBAQKPDCILeBwGAEYQnCdQIGDGAcq69WX4YdBKgQAE2GM1YDB2NVIgS0CABFcXwZnDFQJ6Cqy+HMQZeCGoLWBI4KDDAA46EF4VVC4LaCwK+BwBaDAAi+DAgIVCMAJeJAooGBXwusF4JMBQwLAFA4srCwVVCgK4DAQOwrYDErgQBFQJIBAQSPBra3BGIL/CF4ICBA4QoBMAhXCYg2AFwI0CR4MqI4NWRwLvDLQQAB1erD4IuBM4cxDAUxLYKDCFIdVNYT0DmJeF/x8BRgoABdwQAEmLZBGAMrQAIoBLIoAEFwi9BAATwDE4gwBAwlVDIIACq0qFwYRBLQZqClRDCbAIuDYARbCMAgZCqqnBFwgABYYMxBoIwBMAZqBFQJdCqwuEYAQsCFwexrcACYMqgAtFEAIxCAAKGBAAYMEUwIvFM4OMFoY0Bw0AC4RGCLgokD1msG4OBAgIVDler2LtDYAi3FFwgACVQQuBCQOAEQNWFYJrEfgMrwBSCdwrACqouLa4QAB2DKBCIVbRosxagOx2SuDd4ovBmLSBFxRhCrYuBAASmBAAQ4DVoeG1eGqrAGq1cCQLqBFxPXP4ImBOIYADAoOMFoIrBBAWwmKPFP4LKBLpYvCmIlBaQheDNA4ABd4z7B2OAFxmsgBVCF4xbBFo4SBla+GrZdNFwL/BWoYvHAwruCXw8xFyBeIFAIKDFoYABXw3+lYuRF44lCBQIEDXxWBFyQvJFwa+MEAIuNqx7EF4oqC2OrFwy+HqxdOFoewwAvBGwjuHAAWMla+FAwIuKlVb2OMwFVlcrqwCBqozCMAeML4WGrgTDXwsrL5IuBldbC4WBIIKmCwIzFAAI/ECYi/GMA4uBlQXKDQYzCIQITNAAOBGAwuBNIIXLGYwTRGAouCFqIAVGAJyBwIupGATRBewIrmA==")); -var img_fix = require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AG2JnYv/FzovBGFgvuFwIvCGFQvuFwQvDGFAvuFwYvEGEwvuFwgvFGEgvuFwovGGEQvuFwwvHGEAvuFw4vIGDwvuFxAvJGDgvuFxIvKGDQvuFxQvLGDAvuFxYvMGCwvuFxgvNGCgvuFxovOGCQvuFxwvPGCAvuFx4vQGBwtOCQYvbFRwAJGCwqTGh4uMFS40LEcIA/AH4A/ACQA=")); +var img_fix = require("heatshrink").decompress(atob("mEwxH+6+s6/+AB4TB1gGFq1WlYABAgOBEQQnH68rlQRBD4orGwIkDleBAwQoBEgIABCAY4CgAjGwNbw1bmJFCDYIrGB4OwAIUAGIIrDCIICBA4WBlcxquBF4uslex2AABGYgrE2GxB4WAFoY8ClS0BPwJLCBgUAqyAGlYuCAAmGxgqDF4ZdBEIJSBHoWGwACBAANbTwRqBAYIwFqxTCAAmMF4+GlSDBq0qqotEGYQxDlVWGATBFYAJgIFYIvEJoSKBE4gADxgFESgIwC67AFF51VDQKMBFxAAErg0BGATQBYBy7D2OrlRJBgCGFLgVcGZEqOoKRFYBOGF4WymIXCqovCAQmwrYDBxgJGI4RgEYBQvBGAKlBUILnHdQaPEYQhgGwMxBgQuDRQIvCwCnBqwQCEwY/BFQeAFgQvEmJJBwOBR4dcLIQAD2J6BF4KODEAQhBwA0CSwoMBBAIxClcASAgeCRo2rDIICBOQKOBWoTLBFYYDBrdVG4NVFgK/EDQIrBF4IeCAApbBEgOydwIvBmJuFAAYJBFwIVBAAeMrlWRoIvDwNVF5AeB62xUgVVBAIsGPIRpBHoovBFwIvEXwYvHd4SPDb4ThEAob4DZoQvBDAIvEXwQkBFwpIBAQKPDCILeBwGAEYQnCdQIGDGAcq69WX4YdBKgQAE2GM1YDB2NVIgS0CABFcXwZnDFQJ6Cqy+HMQZeCGoLWBI4KDDAA46EF4VVC4LaCwK+BwBaDAAi+DAgIVCMAJeJAooGBXwusF4JMBQwLAFA4srCwVVCgK4DAQOwrYDErgQBFQJIBAQSPBra3BGIL/CF4ICBA4QoBMAhXCYg2AFwI0CR4MqI4NWRwLvDLQQAB1erD4IuBM4cxDAUxLYKDCFIdVNYT0DmJeF/x8BRgoABdwQAEmLZBGAMrQAIoBLIoAEFwi9BAATwDE4gwBAwlVDIIACq0qFwYRBLQZqClRDCbAIuDYARbCMAgZCqqnBFwgABYYMxBoIwBMAZqBFQJdCqwuEYAQsCFwexrcACYMqgAtFEAIxCAAKGBAAYMEUwIvFM4OMFoY0Bw0AC4RGCLgokD1msG4OBAgIVDler2LtDYAi3FFwgACVQQuBCQOAEQNWFYJrEfgMrwBSCdwrACqouLa4QAB2DKBCIVbRosxagOx2SuDd4ovBmLSBFxRhCrYuBAASmBAAQ4DVoeG1eGqrAGq1cCQLqBFxPXP4ImBOIYADAoOMFoIrBBAWwmKPFP4LKBLpYvCmIlBaQheDNA4ABd4z7B2OAFxmsgBVCF4xbBFo4SBla+GrZdNFwL/BWoYvHAwruCXw8xFyBeIFAIKDFoYABXw3+lYuRF44lCBQIEDXxWBFyQvJFwa+MEAIuNqx7EF4oqC2OrFwy+HqxdOFoewwAvBGwjuHAAWMla+FAwIuKlVb2OMwFVlcrqwCBqozCMAeML4WGrgTDXwsrL5IuBldbC4WBIIKmCwIzFAAI/ECYi/GMA4uBlQXKDQYzCIQITNAAOBGAwuBNIIXLGYwTRGAouCFqIAVGAJyBwIupGATRBewIrmA==")); // https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js function project(latlong) { From c23c11eb51b9411772a52e048761c779a89bbdb9 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Tue, 21 Apr 2020 14:50:44 +0200 Subject: [PATCH 119/878] Update osmpoi.html --- apps/osmpoi/osmpoi.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/osmpoi/osmpoi.html b/apps/osmpoi/osmpoi.html index b4a954c24..fa22bead5 100644 --- a/apps/osmpoi/osmpoi.html +++ b/apps/osmpoi/osmpoi.html @@ -141,8 +141,8 @@ }); document.getElementById("upload").addEventListener("click", function() { var app = `var features = ${JSON.stringify(features)}; -var img_nofix = require("heatshrink").decompress(atob("mEwxH+6+s6/+AB4TB1gGFq1WlYABAgOBEQQnH68rlQRBD4orGwIkDleBAwQoBEgIABCAY4CgAjGwNbw1bmJFCDYIrGB4OwAIUAGIIrDCIICBA4WBlcxquBF4uslex2AABGYgrE2GxB4WAFoY8ClS0BPwJLCBgUAqyAGlYuCAAmGxgqDF4ZdBEIJSBHoWGwACBAANbTwRqBAYIwFqxTCAAmMF4+GlSDBq0qqotEGYQxDlVWGATBFYAJgIFYIvEJoSKBE4gADxgFESgIwC67AFF51VDQKMBFxAAErg0BGATQBYBy7D2OrlRJBgCGFLgVcGZEqOoKRFYBOGF4WymIXCqovCAQmwrYDBxgJGI4RgEYBQvBGAKlBUILnHdQaPEYQhgGwMxBgQuDRQIvCwCnBqwQCEwY/BFQeAFgQvEmJJBwOBR4dcLIQAD2J6BF4KODEAQhBwA0CSwoMBBAIxClcASAgeCRo2rDIICBOQKOBWoTLBFYYDBrdVG4NVFgK/EDQIrBF4IeCAApbBEgOydwIvBmJuFAAYJBFwIVBAAeMrlWRoIvDwNVF5AeB62xUgVVBAIsGPIRpBHoovBFwIvEXwYvHd4SPDb4ThEAob4DZoQvBDAIvEXwQkBFwpIBAQKPDCILeBwGAEYQnCdQIGDGAcq69WX4YdBKgQAE2GM1YDB2NVIgS0CABFcXwZnDFQJ6Cqy+HMQZeCGoLWBI4KDDAA46EF4VVC4LaCwK+BwBaDAAi+DAgIVCMAJeJAooGBXwusF4JMBQwLAFA4srCwVVCgK4DAQOwrYDErgQBFQJIBAQSPBra3BGIL/CF4ICBA4QoBMAhXCYg2AFwI0CR4MqI4NWRwLvDLQQAB1erD4IuBM4cxDAUxLYKDCFIdVNYT0DmJeF/x8BRgoABdwQAEmLZBGAMrQAIoBLIoAEFwi9BAATwDE4gwBAwlVDIIACq0qFwYRBLQZqClRDCbAIuDYARbCMAgZCqqnBFwgABYYMxBoIwBMAZqBFQJdCqwuEYAQsCFwexrcACYMqgAtFEAIxCAAKGBAAYMEUwIvFM4OMFoY0Bw0AC4RGCLgokD1msG4OBAgIVDler2LtDYAi3FFwgACVQQuBCQOAEQNWFYJrEfgMrwBSCdwrACqouLa4QAB2DKBCIVbRosxagOx2SuDd4ovBmLSBFxRhCrYuBAASmBAAQ4DVoeG1eGqrAGq1cCQLqBFxPXP4ImBOIYADAoOMFoIrBBAWwmKPFP4LKBLpYvCmIlBaQheDNA4ABd4z7B2OAFxmsgBVCF4xbBFo4SBla+GrZdNFwL/BWoYvHAwruCXw8xFyBeIFAIKDFoYABXw3+lYuRF44lCBQIEDXxWBFyQvJFwa+MEAIuNqx7EF4oqC2OrFwy+HqxdOFoewwAvBGwjuHAAWMla+FAwIuKlVb2OMwFVlcrqwCBqozCMAeML4WGrgTDXwsrL5IuBldbC4WBIIKmCwIzFAAI/ECYi/GMA4uBlQXKDQYzCIQITNAAOBGAwuBNIIXLGYwTRGAouCFqIAVGAJyBwIupGATRBewIrmA==")); -var img_fix = require("heatshrink").decompress(atob("mEwxH+6+s6/+AB4TB1gGFq1WlYABAgOBEQQnH68rlQRBD4orGwIkDleBAwQoBEgIABCAY4CgAjGwNbw1bmJFCDYIrGB4OwAIUAGIIrDCIICBA4WBlcxquBF4uslex2AABGYgrE2GxB4WAFoY8ClS0BPwJLCBgUAqyAGlYuCAAmGxgqDF4ZdBEIJSBHoWGwACBAANbTwRqBAYIwFqxTCAAmMF4+GlSDBq0qqotEGYQxDlVWGATBFYAJgIFYIvEJoSKBE4gADxgFESgIwC67AFF51VDQKMBFxAAErg0BGATQBYBy7D2OrlRJBgCGFLgVcGZEqOoKRFYBOGF4WymIXCqovCAQmwrYDBxgJGI4RgEYBQvBGAKlBUILnHdQaPEYQhgGwMxBgQuDRQIvCwCnBqwQCEwY/BFQeAFgQvEmJJBwOBR4dcLIQAD2J6BF4KODEAQhBwA0CSwoMBBAIxClcASAgeCRo2rDIICBOQKOBWoTLBFYYDBrdVG4NVFgK/EDQIrBF4IeCAApbBEgOydwIvBmJuFAAYJBFwIVBAAeMrlWRoIvDwNVF5AeB62xUgVVBAIsGPIRpBHoovBFwIvEXwYvHd4SPDb4ThEAob4DZoQvBDAIvEXwQkBFwpIBAQKPDCILeBwGAEYQnCdQIGDGAcq69WX4YdBKgQAE2GM1YDB2NVIgS0CABFcXwZnDFQJ6Cqy+HMQZeCGoLWBI4KDDAA46EF4VVC4LaCwK+BwBaDAAi+DAgIVCMAJeJAooGBXwusF4JMBQwLAFA4srCwVVCgK4DAQOwrYDErgQBFQJIBAQSPBra3BGIL/CF4ICBA4QoBMAhXCYg2AFwI0CR4MqI4NWRwLvDLQQAB1erD4IuBM4cxDAUxLYKDCFIdVNYT0DmJeF/x8BRgoABdwQAEmLZBGAMrQAIoBLIoAEFwi9BAATwDE4gwBAwlVDIIACq0qFwYRBLQZqClRDCbAIuDYARbCMAgZCqqnBFwgABYYMxBoIwBMAZqBFQJdCqwuEYAQsCFwexrcACYMqgAtFEAIxCAAKGBAAYMEUwIvFM4OMFoY0Bw0AC4RGCLgokD1msG4OBAgIVDler2LtDYAi3FFwgACVQQuBCQOAEQNWFYJrEfgMrwBSCdwrACqouLa4QAB2DKBCIVbRosxagOx2SuDd4ovBmLSBFxRhCrYuBAASmBAAQ4DVoeG1eGqrAGq1cCQLqBFxPXP4ImBOIYADAoOMFoIrBBAWwmKPFP4LKBLpYvCmIlBaQheDNA4ABd4z7B2OAFxmsgBVCF4xbBFo4SBla+GrZdNFwL/BWoYvHAwruCXw8xFyBeIFAIKDFoYABXw3+lYuRF44lCBQIEDXxWBFyQvJFwa+MEAIuNqx7EF4oqC2OrFwy+HqxdOFoewwAvBGwjuHAAWMla+FAwIuKlVb2OMwFVlcrqwCBqozCMAeML4WGrgTDXwsrL5IuBldbC4WBIIKmCwIzFAAI/ECYi/GMA4uBlQXKDQYzCIQITNAAOBGAwuBNIIXLGYwTRGAouCFqIAVGAJyBwIupGATRBewIrmA==")); +var img_nofix = require("heatshrink").decompress(atob("mEwxH+h8dj3+AB8eCYsejkYhEVAAMIjEcBwQTBh4bE/8ViUVCAgrIjMWifX68VjMHjETi8bHAMPCAIJChATBiMdEAsZxlH0nsD4IzDNYIrB6/WB4NGAIURicb///FgUcjhYBBAMHinsx0aF4sd61FowABGYOP68UiYrDo1FrwDB0nXjIkChETiURiMS60Tiw6CjMRhCAG64uCAAkao4qDAAIEBLoMH/8cinW0kZjOko4ACxgyBB4MdiccGAsWKYQAHF4tHiUd/8YiWOFAIwBjQCBAwICBxkSi//j0TYIrABFo44BF4aeB65NBjHXLAYACMQIWBo8aGIPWixhCcQLAEF5tex0YVoIuDjSgBGAYDD0gbB6xhBjbCEh7AIF4tGiUPjsRW4SIEfIIGDHIIFCiT1BiqREi0aGBDwCruPjX/imOxhTCX4YvBBIIzDBITDBI4MWF4caxovIrwwC68PjiNBFoaRCAQQIDAgiRBJALBEg+PBgQwFdYNe0jYBhGPcoJQBQYLpCMYQABF4aQCx8Ta4MaF4UYZoIZEGYZeBRwLQBP4WkEYIwBAoQJBGQg0D60Rj0deIUPihcGGoQ5C60cj3WWIKiBSIeMAYOkxwDBAQTJDiTuBh8VF4Me64tGLYIhBrtd9hEBx5uFX4ZCCAYR8EVAMaYAIvCg+OF5NGrpfBj0cx1FFwooCCoKsDXgQvCjMHjIvDi4RCdgteo9er1FF4Md6xUCXoQjBSYUZxhkBY4QMBJAMdjZfDXwJYCLwgGCAQKPBjsd69HxrhEdAQCDd4gwBiUPjEcX4UeiZXBAAlFRwQDBr2OjRBBL4SCDAAh9BY4T7DFQMVPQMWXxKnCr5hC0kI/8WxotBQoLuDF4YDCS4VHx0YI4P/UgK+BjRZCF4yOBeYUTh8bSAMaWoQnCFwQJESoS+BFgK+Bjv+izuCr7BFX4YAB60bh8Tx2NXAsZowGCAYLOBx2k68cicej0Vh/+jONLASjCGoRiDEgUT/8HMAIqBQgTEDXYOMxg7Dx0SLwMIg/+/0d6wmCeQIsCPAJkFx4YBi+PL4QkBAQONxmOLQIzCJAPsiv/jpeC/x8BK4YAEBA2Pi3/h8I62M64oBxmNRIJjCYIUZFwMPjyQBFwIABhDwBFwxfFxwZB/4wCiTDBXYaVBLQJqCiUWh8PiiNCAAUaxqNBGIYFBDIONx0ZFwgACjUT9iLBxsaXYJcBxvW68a/5dBjAuEYAgqBGQNFoukiMVKwMRFwkZEAMPjUV6/Wx/WAAUVjITBjcTx8IF4rABF4QtBAgMZiIkBIwUIFwfXV4McBgUcjQ4BjkeBALpBKgXXdoTAEjK3EFwMbLIceiUIh4uBXAOk60UjAqBNgQ0BjEU60aVwXWjovFjWOFxRhDiZMCfYTNB9gzBBgXsxwMBrqBBr2NjIvFjePo4QBFxBhDxgrBAAR1EHAbZBb4IGCxzwGi+kBYLqBFxAABjBfCFIY0EFAVfBQYGB9iPFh8UIAJdKF4fsEoZdGM47vCjwvEj3Xr0aFxkdiMZF5FGRIIAHo8VXw2No4uOf4QvHXAgAEoukXw+PFzIvFr1eeILyBXw3+iYuRLxIvDSQy+GjguSF44pCo9fFwy+GEAMHFxmlPYJUBr4vFBQLsIXxEIjJdNFgIlCjQvBGoRYDrzJI6y+FicdFxUSxgrB0mO68ThEVienGYS+EMYVHCYcXh4vEisaFxXXxnWFYMajoZCj0cjEU6+OGYIABFYgTEdwxgHFwMSFYoAHGYcSFZYAEjYwGFwMZC5gzGCaIwFFwQtRACowBjZ6BF1LDCisTikbFcwA==")); +var img_fix = require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AG1Omwv/FzovBGFgvuFwIvCGFQvuFwQvDGFAvuFwYvEGEwvuFwgvFGEgvuFwovGGEQvuFwwvHGEAvuFw4vIGDwvuFxAvJGDgvuFxIvKGDQvuFxQvLGDAvuFxYvMGCwvuFxgvNGCgvuFxovOGCQvuFxwvPGCAvuFx4vQGBwtOCQYvbFRwAJGCwpEprTPGhouLFTA0LEcIA/AH4A/ACQA=")); // https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js function project(latlong) { From f938dc3de0933f3b81f9f25a7fff50e9ae57ac5f Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Tue, 21 Apr 2020 14:59:52 +0200 Subject: [PATCH 120/878] Update osmpoi.html --- apps/osmpoi/osmpoi.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/osmpoi/osmpoi.html b/apps/osmpoi/osmpoi.html index fa22bead5..e0275784e 100644 --- a/apps/osmpoi/osmpoi.html +++ b/apps/osmpoi/osmpoi.html @@ -141,8 +141,8 @@ }); document.getElementById("upload").addEventListener("click", function() { var app = `var features = ${JSON.stringify(features)}; -var img_nofix = require("heatshrink").decompress(atob("mEwxH+h8dj3+AB8eCYsejkYhEVAAMIjEcBwQTBh4bE/8ViUVCAgrIjMWifX68VjMHjETi8bHAMPCAIJChATBiMdEAsZxlH0nsD4IzDNYIrB6/WB4NGAIURicb///FgUcjhYBBAMHinsx0aF4sd61FowABGYOP68UiYrDo1FrwDB0nXjIkChETiURiMS60Tiw6CjMRhCAG64uCAAkao4qDAAIEBLoMH/8cinW0kZjOko4ACxgyBB4MdiccGAsWKYQAHF4tHiUd/8YiWOFAIwBjQCBAwICBxkSi//j0TYIrABFo44BF4aeB65NBjHXLAYACMQIWBo8aGIPWixhCcQLAEF5tex0YVoIuDjSgBGAYDD0gbB6xhBjbCEh7AIF4tGiUPjsRW4SIEfIIGDHIIFCiT1BiqREi0aGBDwCruPjX/imOxhTCX4YvBBIIzDBITDBI4MWF4caxovIrwwC68PjiNBFoaRCAQQIDAgiRBJALBEg+PBgQwFdYNe0jYBhGPcoJQBQYLpCMYQABF4aQCx8Ta4MaF4UYZoIZEGYZeBRwLQBP4WkEYIwBAoQJBGQg0D60Rj0deIUPihcGGoQ5C60cj3WWIKiBSIeMAYOkxwDBAQTJDiTuBh8VF4Me64tGLYIhBrtd9hEBx5uFX4ZCCAYR8EVAMaYAIvCg+OF5NGrpfBj0cx1FFwooCCoKsDXgQvCjMHjIvDi4RCdgteo9er1FF4Md6xUCXoQjBSYUZxhkBY4QMBJAMdjZfDXwJYCLwgGCAQKPBjsd69HxrhEdAQCDd4gwBiUPjEcX4UeiZXBAAlFRwQDBr2OjRBBL4SCDAAh9BY4T7DFQMVPQMWXxKnCr5hC0kI/8WxotBQoLuDF4YDCS4VHx0YI4P/UgK+BjRZCF4yOBeYUTh8bSAMaWoQnCFwQJESoS+BFgK+Bjv+izuCr7BFX4YAB60bh8Tx2NXAsZowGCAYLOBx2k68cicej0Vh/+jONLASjCGoRiDEgUT/8HMAIqBQgTEDXYOMxg7Dx0SLwMIg/+/0d6wmCeQIsCPAJkFx4YBi+PL4QkBAQONxmOLQIzCJAPsiv/jpeC/x8BK4YAEBA2Pi3/h8I62M64oBxmNRIJjCYIUZFwMPjyQBFwIABhDwBFwxfFxwZB/4wCiTDBXYaVBLQJqCiUWh8PiiNCAAUaxqNBGIYFBDIONx0ZFwgACjUT9iLBxsaXYJcBxvW68a/5dBjAuEYAgqBGQNFoukiMVKwMRFwkZEAMPjUV6/Wx/WAAUVjITBjcTx8IF4rABF4QtBAgMZiIkBIwUIFwfXV4McBgUcjQ4BjkeBALpBKgXXdoTAEjK3EFwMbLIceiUIh4uBXAOk60UjAqBNgQ0BjEU60aVwXWjovFjWOFxRhDiZMCfYTNB9gzBBgXsxwMBrqBBr2NjIvFjePo4QBFxBhDxgrBAAR1EHAbZBb4IGCxzwGi+kBYLqBFxAABjBfCFIY0EFAVfBQYGB9iPFh8UIAJdKF4fsEoZdGM47vCjwvEj3Xr0aFxkdiMZF5FGRIIAHo8VXw2No4uOf4QvHXAgAEoukXw+PFzIvFr1eeILyBXw3+iYuRLxIvDSQy+GjguSF44pCo9fFwy+GEAMHFxmlPYJUBr4vFBQLsIXxEIjJdNFgIlCjQvBGoRYDrzJI6y+FicdFxUSxgrB0mO68ThEVienGYS+EMYVHCYcXh4vEisaFxXXxnWFYMajoZCj0cjEU6+OGYIABFYgTEdwxgHFwMSFYoAHGYcSFZYAEjYwGFwMZC5gzGCaIwFFwQtRACowBjZ6BF1LDCisTikbFcwA==")); -var img_fix = require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AG1Omwv/FzovBGFgvuFwIvCGFQvuFwQvDGFAvuFwYvEGEwvuFwgvFGEgvuFwovGGEQvuFwwvHGEAvuFw4vIGDwvuFxAvJGDgvuFxIvKGDQvuFxQvLGDAvuFxYvMGCwvuFxgvNGCgvuFxovOGCQvuFxwvPGCAvuFx4vQGBwtOCQYvbFRwAJGCwpEprTPGhouLFTA0LEcIA/AH4A/ACQA=")); +var img_nofix = require("heatshrink").decompress(atob("mEwxH+6+s6/+AB4TB1gGFq1WlYABAgOBEQQnH68rlQRBD4orGwIkDleBAwQoBEgIABCAY4CgAjGwNbw1bmJFCDYIrGB4OwAIUAGIIrDCIICBA4WBlcxquBF4uslex2AABGYgrE2GxB4WAFoY8ClS0BPwJLCBgUAqyAGlYuCAAmGxgqDF4ZdBEIJSBHoWGwACBAANbTwRqBAYIwFqxTCAAmMF4+GlSDBq0qqotEGYQxDlVWGATBFYAJgIFYIvEJoSKBE4gADxgFESgIwC67AFF51VDQKMBFxAAErg0BGATQBYBy7D2OrlRJBgCGFLgVcGZEqOoKRFYBOGF4WymIXCqovCAQmwrYDBxgJGI4RgEYBQvBGAKlBUILnHdQaPEYQhgGwMxBgQuDRQIvCwCnBqwQCEwY/BFQeAFgQvEmJJBwOBR4dcLIQAD2J6BF4KODEAQhBwA0CSwoMBBAIxClcASAgeCRo2rDIICBOQKOBWoTLBFYYDBrdVG4NVFgK/EDQIrBF4IeCAApbBEgOydwIvBmJuFAAYJBFwIVBAAeMrlWRoIvDwNVF5AeB62xUgVVBAIsGPIRpBHoovBFwIvEXwYvHd4SPDb4ThEAob4DZoQvBDAIvEXwQkBFwpIBAQKPDCILeBwGAEYQnCdQIGDGAcq69WX4YdBKgQAE2GM1YDB2NVIgS0CABFcXwZnDFQJ6Cqy+HMQZeCGoLWBI4KDDAA46EF4VVC4LaCwK+BwBaDAAi+DAgIVCMAJeJAooGBXwusF4JMBQwLAFA4srCwVVCgK4DAQOwrYDErgQBFQJIBAQSPBra3BGIL/CF4ICBA4QoBMAhXCYg2AFwI0CR4MqI4NWRwLvDLQQAB1erD4IuBM4cxDAUxLYKDCFIdVNYT0DmJeF/x8BRgoABdwQAEmLZBGAMrQAIoBLIoAEFwi9BAATwDE4gwBAwlVDIIACq0qFwYRBLQZqClRDCbAIuDYARbCMAgZCqqnBFwgABYYMxBoIwBMAZqBFQJdCqwuEYAQsCFwexrcACYMqgAtFEAIxCAAKGBAAYMEUwIvFM4OMFoY0Bw0AC4RGCLgokD1msG4OBAgIVDler2LtDYAi3FFwgACVQQuBCQOAEQNWFYJrEfgMrwBSCdwrACqouLa4QAB2DKBCIVbRosxagOx2SuDd4ovBmLSBFxRhCrYuBAASmBAAQ4DVoeG1eGqrAGq1cCQLqBFxPXP4ImBOIYADAoOMFoIrBBAWwmKPFP4LKBLpYvCmIlBaQheDNA4ABd4z7B2OAFxmsgBVCF4xbBFo4SBla+GrZdNFwL/BWoYvHAwruCXw8xFyBeIFAIKDFoYABXw3+lYuRF44lCBQIEDXxWBFyQvJFwa+MEAIuNqx7EF4oqC2OrFwy+HqxdOFoewwAvBGwjuHAAWMla+FAwIuKlVb2OMwFVlcrqwCBqozCMAeML4WGrgTDXwsrL5IuBldbC4WBIIKmCwIzFAAI/ECYi/GMA4uBlQXKDQYzCIQITNAAOBGAwuBNIIXLGYwTRGAouCFqIAVGAJyBwIupGATRBewIrmA==")); +var img_fix = require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AG2JnYv/FzovBGFgvuFwIvCGFQvuFwQvDGFAvuFwYvEGEwvuFwgvFGEgvuFwovGGEQvuFwwvHGEAvuFw4vIGDwvuFxAvJGDgvuFxIvKGDQvuFxQvLGDAvuFxYvMGCwvuFxgvNGCgvuFxovOGCQvuFxwvPGCAvuFx4vQGBwtOCQYvbFRwAJGCwqTGh4uMFS40LEcIA/AH4A/ACQA=")); // https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js function project(latlong) { From 9a64b8aa35a4108b1745c812dac119b0943290f8 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Tue, 21 Apr 2020 15:17:57 +0200 Subject: [PATCH 121/878] Update osmpoi.html --- apps/osmpoi/osmpoi.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/osmpoi/osmpoi.html b/apps/osmpoi/osmpoi.html index e0275784e..3b1fc5ba8 100644 --- a/apps/osmpoi/osmpoi.html +++ b/apps/osmpoi/osmpoi.html @@ -141,8 +141,8 @@ }); document.getElementById("upload").addEventListener("click", function() { var app = `var features = ${JSON.stringify(features)}; -var img_nofix = require("heatshrink").decompress(atob("mEwxH+6+s6/+AB4TB1gGFq1WlYABAgOBEQQnH68rlQRBD4orGwIkDleBAwQoBEgIABCAY4CgAjGwNbw1bmJFCDYIrGB4OwAIUAGIIrDCIICBA4WBlcxquBF4uslex2AABGYgrE2GxB4WAFoY8ClS0BPwJLCBgUAqyAGlYuCAAmGxgqDF4ZdBEIJSBHoWGwACBAANbTwRqBAYIwFqxTCAAmMF4+GlSDBq0qqotEGYQxDlVWGATBFYAJgIFYIvEJoSKBE4gADxgFESgIwC67AFF51VDQKMBFxAAErg0BGATQBYBy7D2OrlRJBgCGFLgVcGZEqOoKRFYBOGF4WymIXCqovCAQmwrYDBxgJGI4RgEYBQvBGAKlBUILnHdQaPEYQhgGwMxBgQuDRQIvCwCnBqwQCEwY/BFQeAFgQvEmJJBwOBR4dcLIQAD2J6BF4KODEAQhBwA0CSwoMBBAIxClcASAgeCRo2rDIICBOQKOBWoTLBFYYDBrdVG4NVFgK/EDQIrBF4IeCAApbBEgOydwIvBmJuFAAYJBFwIVBAAeMrlWRoIvDwNVF5AeB62xUgVVBAIsGPIRpBHoovBFwIvEXwYvHd4SPDb4ThEAob4DZoQvBDAIvEXwQkBFwpIBAQKPDCILeBwGAEYQnCdQIGDGAcq69WX4YdBKgQAE2GM1YDB2NVIgS0CABFcXwZnDFQJ6Cqy+HMQZeCGoLWBI4KDDAA46EF4VVC4LaCwK+BwBaDAAi+DAgIVCMAJeJAooGBXwusF4JMBQwLAFA4srCwVVCgK4DAQOwrYDErgQBFQJIBAQSPBra3BGIL/CF4ICBA4QoBMAhXCYg2AFwI0CR4MqI4NWRwLvDLQQAB1erD4IuBM4cxDAUxLYKDCFIdVNYT0DmJeF/x8BRgoABdwQAEmLZBGAMrQAIoBLIoAEFwi9BAATwDE4gwBAwlVDIIACq0qFwYRBLQZqClRDCbAIuDYARbCMAgZCqqnBFwgABYYMxBoIwBMAZqBFQJdCqwuEYAQsCFwexrcACYMqgAtFEAIxCAAKGBAAYMEUwIvFM4OMFoY0Bw0AC4RGCLgokD1msG4OBAgIVDler2LtDYAi3FFwgACVQQuBCQOAEQNWFYJrEfgMrwBSCdwrACqouLa4QAB2DKBCIVbRosxagOx2SuDd4ovBmLSBFxRhCrYuBAASmBAAQ4DVoeG1eGqrAGq1cCQLqBFxPXP4ImBOIYADAoOMFoIrBBAWwmKPFP4LKBLpYvCmIlBaQheDNA4ABd4z7B2OAFxmsgBVCF4xbBFo4SBla+GrZdNFwL/BWoYvHAwruCXw8xFyBeIFAIKDFoYABXw3+lYuRF44lCBQIEDXxWBFyQvJFwa+MEAIuNqx7EF4oqC2OrFwy+HqxdOFoewwAvBGwjuHAAWMla+FAwIuKlVb2OMwFVlcrqwCBqozCMAeML4WGrgTDXwsrL5IuBldbC4WBIIKmCwIzFAAI/ECYi/GMA4uBlQXKDQYzCIQITNAAOBGAwuBNIIXLGYwTRGAouCFqIAVGAJyBwIupGATRBewIrmA==")); -var img_fix = require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AG2JnYv/FzovBGFgvuFwIvCGFQvuFwQvDGFAvuFwYvEGEwvuFwgvFGEgvuFwovGGEQvuFwwvHGEAvuFw4vIGDwvuFxAvJGDgvuFxIvKGDQvuFxQvLGDAvuFxYvMGCwvuFxgvNGCgvuFxovOGCQvuFxwvPGCAvuFx4vQGBwtOCQYvbFRwAJGCwqTGh4uMFS40LEcIA/AH4A/ACQA=")); +var img_nofix = require("heatshrink").decompress(atob("mEwhHX1nX/wAPCYOsAwtWq0rAAIEBwIiCE4/XlcqCIIfFFY2BEgcrwIGCFAIkBAAIQDHAUAEY2BreGrcxIoQbBFYwPB2ABCgAxBFYYRBAQIHCwMrmNVwIvF1kr2OwAAIzEFYmw2IPCwAtDHgUqWYJ+BJYQMCgFWQA0rFwQAEw2MFQYvDLoIhBKQI9Cw2AAQIABraeCNQIDBGAtWKYQAExgvHw0qQYNWlVVFogzCGIcqqwwCYIrABMBArBF4hNCRQInEAAeMAoiUBGAXXYAovOqoaBRgIuIAAlcGgIwCaALAOXYex1cqJIMAQwpcCrgzIlR1BSIrAJwwvC2UxC4VVF4QCE2FbAYOMBIxHCMAjAKF4IwBUoKhBc47qDR4jCEMA2BmIMCFwaKBF4WAU4NWCAQmDH4IqDwAsCF4kxJIOBwKPDrhZCAAexPQIvBRwYgCEIOAGgSWFBgIIBGIUrgCQEDwSNG1YZBAQJyBRwK1CZYIrDAYNbqo3BqosBX4gaBFYIvBDwQAFLYIkB2TuBF4MxNwoADBIIuBCoIADxlcqyNBF4eBqovIDwPW2KkCqoIBFgx5CNII9FF4IuBF4i+DF47vCR4bfCcIgFDfAbNCF4IYBF4i+CEgIuFJAICBR4YRBbwOAwAjCE4TqBAwYwDlXXqy/DDoJUCAAmwxmrAYOxqpECWgQAIri+DM4YqBPQVWXw5iDLwQ1BawJHBQYYAHHQgvCqoXBbQWBXwOALQYAEXwYEBCoRgBLxIFFAwK+F1gvBJgKGBYAoHFlYWCqoUBXAYCB2FbAYlcCAIqBJAICCR4NbW4IxBf4QvBAQIHCFAJgEK4TEGwAuBGgSPBlRHBqyOBd4ZaCAAOr1YfBFwJnDmIYCmJbBQYQpDqprCegcxLwv+PgKMFAALuCAAkxbIIwBlaABFAJZFAAguEXoIACeAYnEGAIGEqoZBAAVWlQuDCIJaDNQUqIYTYBFwbACLYRgEDIVVU4IuEAALDBmINBGAJgDNQIqBLoVWFwjACFgQuD2NbgATBlUAFoogBGIQABQwIADBgimBF4pnBxgtDGgOGgAXCIwRcFEges1g3BwIEBCocr1exdobAEW4ouEAASqCFwISBwAiBqwrBNYj8BleAKQTuFYAVVFxbXCAAOwZQIRCraNFmLUB2OyVwbvFF4MxaQIuKMIVbFwIACUwIACHAatDw2rw1VYA1WrgSBdQIuJ65/BEwJxDAAYFBxgtBFYIIC2ExR4p/BZQJdLF4UxEoLSELwZoHAALvGfYOxwAuM1kAKoQvGLYItHCQMrXw1bLpouBf4K1DF44GFdwS+HmIuQLxAoBBQYtDAAK+G/0rFyIvHEoQKBAga+KwIuSF5IuDXxggBFxtWPYgvFFQWx1YuGXw9WLpwtD2GAF4I2Edw4ACxkrXwoGBFxUqrexxmAqsrldWAQNVGYRgDxhfCw1cCYa+FlZfJFwMrrYXCwJBBUwWBGYoABH4gTEX4xgHFwMqC5QaDGYRCBCZoABwIwGFwJpBC5YzGCaIwFFwQtRACowBOQOBF1IwCaIL2BFcw")); +var img_fix = require("heatshrink").decompress(atob("mEwhH+AH4A/AH4A/AGuJnYv/FzovBGFgvuFwIvCGFQvuFwQvDGFAvuFwYvEGEwvuFwgvFGEgvuFwovGGEQvuFwwvHGEAvuFw4vIGDwvuFxAvJGDgvuFxIvKGDQvuFxQvLGDAvuFxYvMGCwvuFxgvNGCgvuFxovOGCQvuFxwvPGCAvuFx4vQGBwtOCQYvbFRwAJGCwqTGh4uMFS40LEcIA/AH4A/ACQA=")); // https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js function project(latlong) { From b711e10d4f09293bb9a9e0bbe615777268cd1321 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Tue, 21 Apr 2020 15:31:26 +0200 Subject: [PATCH 122/878] Update osmpoi.html --- apps/osmpoi/osmpoi.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/osmpoi/osmpoi.html b/apps/osmpoi/osmpoi.html index 3b1fc5ba8..58a182721 100644 --- a/apps/osmpoi/osmpoi.html +++ b/apps/osmpoi/osmpoi.html @@ -141,8 +141,8 @@ }); document.getElementById("upload").addEventListener("click", function() { var app = `var features = ${JSON.stringify(features)}; -var img_nofix = require("heatshrink").decompress(atob("mEwhHX1nX/wAPCYOsAwtWq0rAAIEBwIiCE4/XlcqCIIfFFY2BEgcrwIGCFAIkBAAIQDHAUAEY2BreGrcxIoQbBFYwPB2ABCgAxBFYYRBAQIHCwMrmNVwIvF1kr2OwAAIzEFYmw2IPCwAtDHgUqWYJ+BJYQMCgFWQA0rFwQAEw2MFQYvDLoIhBKQI9Cw2AAQIABraeCNQIDBGAtWKYQAExgvHw0qQYNWlVVFogzCGIcqqwwCYIrABMBArBF4hNCRQInEAAeMAoiUBGAXXYAovOqoaBRgIuIAAlcGgIwCaALAOXYex1cqJIMAQwpcCrgzIlR1BSIrAJwwvC2UxC4VVF4QCE2FbAYOMBIxHCMAjAKF4IwBUoKhBc47qDR4jCEMA2BmIMCFwaKBF4WAU4NWCAQmDH4IqDwAsCF4kxJIOBwKPDrhZCAAexPQIvBRwYgCEIOAGgSWFBgIIBGIUrgCQEDwSNG1YZBAQJyBRwK1CZYIrDAYNbqo3BqosBX4gaBFYIvBDwQAFLYIkB2TuBF4MxNwoADBIIuBCoIADxlcqyNBF4eBqovIDwPW2KkCqoIBFgx5CNII9FF4IuBF4i+DF47vCR4bfCcIgFDfAbNCF4IYBF4i+CEgIuFJAICBR4YRBbwOAwAjCE4TqBAwYwDlXXqy/DDoJUCAAmwxmrAYOxqpECWgQAIri+DM4YqBPQVWXw5iDLwQ1BawJHBQYYAHHQgvCqoXBbQWBXwOALQYAEXwYEBCoRgBLxIFFAwK+F1gvBJgKGBYAoHFlYWCqoUBXAYCB2FbAYlcCAIqBJAICCR4NbW4IxBf4QvBAQIHCFAJgEK4TEGwAuBGgSPBlRHBqyOBd4ZaCAAOr1YfBFwJnDmIYCmJbBQYQpDqprCegcxLwv+PgKMFAALuCAAkxbIIwBlaABFAJZFAAguEXoIACeAYnEGAIGEqoZBAAVWlQuDCIJaDNQUqIYTYBFwbACLYRgEDIVVU4IuEAALDBmINBGAJgDNQIqBLoVWFwjACFgQuD2NbgATBlUAFoogBGIQABQwIADBgimBF4pnBxgtDGgOGgAXCIwRcFEges1g3BwIEBCocr1exdobAEW4ouEAASqCFwISBwAiBqwrBNYj8BleAKQTuFYAVVFxbXCAAOwZQIRCraNFmLUB2OyVwbvFF4MxaQIuKMIVbFwIACUwIACHAatDw2rw1VYA1WrgSBdQIuJ65/BEwJxDAAYFBxgtBFYIIC2ExR4p/BZQJdLF4UxEoLSELwZoHAALvGfYOxwAuM1kAKoQvGLYItHCQMrXw1bLpouBf4K1DF44GFdwS+HmIuQLxAoBBQYtDAAK+G/0rFyIvHEoQKBAga+KwIuSF5IuDXxggBFxtWPYgvFFQWx1YuGXw9WLpwtD2GAF4I2Edw4ACxkrXwoGBFxUqrexxmAqsrldWAQNVGYRgDxhfCw1cCYa+FlZfJFwMrrYXCwJBBUwWBGYoABH4gTEX4xgHFwMqC5QaDGYRCBCZoABwIwGFwJpBC5YzGCaIwFFwQtRACowBOQOBF1IwCaIL2BFcw")); -var img_fix = require("heatshrink").decompress(atob("mEwhH+AH4A/AH4A/AGuJnYv/FzovBGFgvuFwIvCGFQvuFwQvDGFAvuFwYvEGEwvuFwgvFGEgvuFwovGGEQvuFwwvHGEAvuFw4vIGDwvuFxAvJGDgvuFxIvKGDQvuFxQvLGDAvuFxYvMGCwvuFxgvNGCgvuFxovOGCQvuFxwvPGCAvuFx4vQGBwtOCQYvbFRwAJGCwqTGh4uMFS40LEcIA/AH4A/ACQA=")); +var img_nofix = require("heatshrink").decompress(atob("mEwhBC/AH4AS6+sq0AgMrBo8rgICB1mBgIABAoNWAAusDYOBwWBF5IPBldWwAhCGQQJBgOBwNWqsxmIoF64AC1g2ClcGmIvKgGAwGwrcxqtWwItBFYdbw2x2APBG4IqBKgI0CLQIIBDISCBABAlBmOxAAOww1bqtVrY5BBIPVBYMxlYkBKoIFBAAJHBAoI6BQQSwIAANWmJQBAAIyCxmx6xbCBANbFwIhCwuGAAZHCBQKZBSgQvIgNWQQYACDgIHD6tcFwKBBSwIADrgFEGIJiBqASBSBFWrYvGMAIIB2OGJwJdBrYMBwArEAAWAxgwBewQvJwNVF4uMM4IvCquA68rqoqHGgQ3DUIT8BeJNVRAhgCfAWGmPXwExRoIlB2AsB2FbSwSTBAIOwQYLCBSBWFFwgvErYZBXgS+FLgoDCSIRFBwIvLC4WMMoIACqusbIKACEoYCCeAYLDwEAwLBBX5ExXgmG1eGwoCBRwL+BEQVcEYKMCAQxKBqovBC4LvOLYLwC1aoCwqGEIAR1BL4QLEqtWF5RQBF4+M62GF4QnCAAoHBeQILFrmBR5VVKwIvFA4PVw1VR4eAAAIkDA4L3CTIILBwtW1mAL48r1kxc4YADF4KPBF4gpCF4TmCeoYECraOBR5C+DAAjyB1YDB2NV1gPBQQgxDBA8xq1QF5EBV4KOEVIQvBAANbVAMrQoQAKRwREBSAJhBX4y+CLgQACFwewVQJIBmKRD2C4BxlbAwKLBrlbRwQVC1gvGq2FLIWGxiKB1YCBJwUrwRgDeAmMAYQsBrYKBlbkBMIK/Ira2CFgIyBGoOrGoQcB6+BmOAKgIyBFQVbqr0CGwMGXoReHd4aLBRQbuCBAVbJYIcBlcxSYIADYAgRBwARBCQIvGGANV1fVFIiPBTAJeCFwIABwIwBQ4SPCCIJiBKIIuBqAuIF4NWSAKRDAAJIBAAQuDAAKuBmIKBrcxqoCBDwJvCgwuJSAYtEFwMAwOBqEBFgY1D1mBqxZBFgOBBIJsBMYKOJgEBJQJdFgBaDDAIDBUIJWBFAZoEGwMxwvWwC/BMBVWWwK6BrcBEAowBJwLNCwpTBKgIABqqSBDgPV6uGL5TADFwS4GGAUGc4WMfYQABwuFAYJ5CPwOGTQIvJIgOMdQQuHXoWGL4WwGgQzCFgOr1Y8BDwKPKd4XWFxTeCLoYyEFQI6EL4IvBL5MrwGGwC7GLwkBToIlFEwKHBBAqtCRxMBwFVFxkxV4IvLX4QGBq1QF5UGgAuKlYuBKo7oCdobuDq2BFxLJBFxrlCFwwnBFgSOEXxTeBFxdVKAbuEK4erFwgEBriOKqGBFxHXFwerfoOAMAKGEXwmwxmGrdVRxMALxSMBDQNcqtWPgICBGYOFMIaaBCAIRBqAPBF5ILBRg8BgFcFYeBA4IGCA4IoCHoYsBwItKF4UrSAq7BLAgXIwErgIQDwArLGBQuBDYIZPLQIsQGAqSBLoQbUGCquDF1IA/AH4AKA==")); +var img_fix = require("heatshrink").decompress(atob("mEwhBC/AH4A/AH4A/AE0rg4vtq8PF1kHxM7gJesF4Jgrg+IF4M6MFReBF4JgqXoIvDMFJeCF4RgoLwYvDnZgmLwYvEMEpeEF4jBlmYvIMEheFF4pgjXogvGMEReGF407MEBeGF45gfg+IF5rBfLw4vHMDxeIF5BgdLxAvIMDkHFxAvJMDZeJF5JgaLxQvKnZgYLxQvLMC5eLF5bBXmYvWMCxeMF5hgVXpYvNMCheNF5s7MCReNF5xgRg+IFZNersylcHhEPmjBbLw1er1XlkHIhI0CnRgUmQqEKwKnRgIzBiBpBnUICpszryCCFiIyGM4TBRAH4A/AH4A/AH4AFA")); // https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js function project(latlong) { From 3e55bc973ca9c95cb4887eec26bd9650e3af13a1 Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Tue, 21 Apr 2020 15:38:52 +0200 Subject: [PATCH 123/878] Update osmpoi.html --- apps/osmpoi/osmpoi.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/osmpoi/osmpoi.html b/apps/osmpoi/osmpoi.html index 58a182721..651e34e7a 100644 --- a/apps/osmpoi/osmpoi.html +++ b/apps/osmpoi/osmpoi.html @@ -141,7 +141,7 @@ }); document.getElementById("upload").addEventListener("click", function() { var app = `var features = ${JSON.stringify(features)}; -var img_nofix = require("heatshrink").decompress(atob("mEwhBC/AH4AS6+sq0AgMrBo8rgICB1mBgIABAoNWAAusDYOBwWBF5IPBldWwAhCGQQJBgOBwNWqsxmIoF64AC1g2ClcGmIvKgGAwGwrcxqtWwItBFYdbw2x2APBG4IqBKgI0CLQIIBDISCBABAlBmOxAAOww1bqtVrY5BBIPVBYMxlYkBKoIFBAAJHBAoI6BQQSwIAANWmJQBAAIyCxmx6xbCBANbFwIhCwuGAAZHCBQKZBSgQvIgNWQQYACDgIHD6tcFwKBBSwIADrgFEGIJiBqASBSBFWrYvGMAIIB2OGJwJdBrYMBwArEAAWAxgwBewQvJwNVF4uMM4IvCquA68rqoqHGgQ3DUIT8BeJNVRAhgCfAWGmPXwExRoIlB2AsB2FbSwSTBAIOwQYLCBSBWFFwgvErYZBXgS+FLgoDCSIRFBwIvLC4WMMoIACqusbIKACEoYCCeAYLDwEAwLBBX5ExXgmG1eGwoCBRwL+BEQVcEYKMCAQxKBqovBC4LvOLYLwC1aoCwqGEIAR1BL4QLEqtWF5RQBF4+M62GF4QnCAAoHBeQILFrmBR5VVKwIvFA4PVw1VR4eAAAIkDA4L3CTIILBwtW1mAL48r1kxc4YADF4KPBF4gpCF4TmCeoYECraOBR5C+DAAjyB1YDB2NV1gPBQQgxDBA8xq1QF5EBV4KOEVIQvBAANbVAMrQoQAKRwREBSAJhBX4y+CLgQACFwewVQJIBmKRD2C4BxlbAwKLBrlbRwQVC1gvGq2FLIWGxiKB1YCBJwUrwRgDeAmMAYQsBrYKBlbkBMIK/Ira2CFgIyBGoOrGoQcB6+BmOAKgIyBFQVbqr0CGwMGXoReHd4aLBRQbuCBAVbJYIcBlcxSYIADYAgRBwARBCQIvGGANV1fVFIiPBTAJeCFwIABwIwBQ4SPCCIJiBKIIuBqAuIF4NWSAKRDAAJIBAAQuDAAKuBmIKBrcxqoCBDwJvCgwuJSAYtEFwMAwOBqEBFgY1D1mBqxZBFgOBBIJsBMYKOJgEBJQJdFgBaDDAIDBUIJWBFAZoEGwMxwvWwC/BMBVWWwK6BrcBEAowBJwLNCwpTBKgIABqqSBDgPV6uGL5TADFwS4GGAUGc4WMfYQABwuFAYJ5CPwOGTQIvJIgOMdQQuHXoWGL4WwGgQzCFgOr1Y8BDwKPKd4XWFxTeCLoYyEFQI6EL4IvBL5MrwGGwC7GLwkBToIlFEwKHBBAqtCRxMBwFVFxkxV4IvLX4QGBq1QF5UGgAuKlYuBKo7oCdobuDq2BFxLJBFxrlCFwwnBFgSOEXxTeBFxdVKAbuEK4erFwgEBriOKqGBFxHXFwerfoOAMAKGEXwmwxmGrdVRxMALxSMBDQNcqtWPgICBGYOFMIaaBCAIRBqAPBF5ILBRg8BgFcFYeBA4IGCA4IoCHoYsBwItKF4UrSAq7BLAgXIwErgIQDwArLGBQuBDYIZPLQIsQGAqSBLoQbUGCquDF1IA/AH4AKA==")); +var img_nofix = require("heatshrink").decompress(atob("mEwhBC/AH4A/AGnXwMrgMrBg4KBgOBwIOBldWwNWAAmBCIOB1kBF5mBlVVCwInBqwzBAQIcBEQNVqtcFwIRB64AD1gPBlcGGYIAMFIOG2FbrdcFgVWrgHBw2x2Owqss1h0Bq0slcsGoIIClR8IQQ2BrYjBEgOGwwrC2AIB6uwlVWEgMxqo6BAAcxq2s1hsBGB1b2AAExg1CGAUxRQNWlQ9BAA1blQOCqzBMQ4KQBAAYFBF4aYBD4NVNoQAIGAJhOBoIvFxhgBAgOrmJdJwAwGeoRgMqyQGdYReBJoMqZAIBBAQ1cAgOwrZxCeZlWrmMF5ExPgIuEXYiRHMAOBL5oVDGYItB6uGqxeBFBCPDBQcqMAQuKlgvBXAWMw2rDIOxraOBLwaMEwAHCBQhQBF5jvGLoIZB6wvBwKwBLopABXgIAFq2BF5krqy+FF4OxF5ItBIgJaBBQlcCYLUBFxMBq1VRwRfEX4IvCqqCBRISSFSAQEBqumL5krwNc6orBAARMBAYOAJQIvBAB0xWAIvMXwIqBFweMAgSrB1kxwCLCABVbXwKPMgCOBFoYABLwQGBmIaBmKyCR5UxwJeBGIK/KQAOw1ereQIsCLwOMYAPXlQnBF4VcMoIFBXwdbWAKOBR5mAdgerw+G1YuBBIJgBwMxrdcGQQrCqo3C2AvBFwOBgLvMRoRdCw6XElRNBwMqmNVFoVbwDtEFwKiBXxZgCXwgECJoStB64ABGASICBoWGqsqFwUrlYuLgA9BdIex6orBlcxgwuD1gABegIyBAAaJBHgMGLpgvDraJFlgnCqwuB0wqBwIyCwIACHIdVMgOBGB1cRoQuBFQQABGAOmmLjCLAWmGQQsBFoJJBBYJgPEIIuGGAUAWwQOBwzABFYLEC6p5Cra/NF4Nb2GMFw4ABlYvCxgxCAAYrB1b2CqrANd4YuJF4YAExg2BBIIEBBAS/OF4SuBFxFWlQkELYZmBBAmGLxsAldcLpVWgxXCF44EDAANcF55hBFxSbBKwooCBQIABBASOOlcrFxuxFw+MFoYACmJQBXxouK2PV6pWEFQWx1aVGRx4uIwLqBDoNVqtWquAGIhnBGgOGwFVmOsgIvN1hdHgFbrcxq2BAwIDCmNbwwACBwI8BwMsRxodBMA2BZAWmDYJMFlgmCVAIPJGCIFBwJ3OwIpQGBCSBAYJ2OADYsCAQIupAH4A/AH4AoA")); var img_fix = require("heatshrink").decompress(atob("mEwhBC/AH4A/AH4A/AE0rg4vtq8PF1kHxM7gJesF4Jgrg+IF4M6MFReBF4JgqXoIvDMFJeCF4RgoLwYvDnZgmLwYvEMEpeEF4jBlmYvIMEheFF4pgjXogvGMEReGF407MEBeGF45gfg+IF5rBfLw4vHMDxeIF5BgdLxAvIMDkHFxAvJMDZeJF5JgaLxQvKnZgYLxQvLMC5eLF5bBXmYvWMCxeMF5hgVXpYvNMCheNF5s7MCReNF5xgRg+IFZNersylcHhEPmjBbLw1er1XlkHIhI0CnRgUmQqEKwKnRgIzBiBpBnUICpszryCCFiIyGM4TBRAH4A/AH4A/AH4AFA")); // https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js From 00c37da578024838586fbbb0b78e91da12e2b93b Mon Sep 17 00:00:00 2001 From: RenaudG <34276398+renaudgweb@users.noreply.github.com> Date: Tue, 21 Apr 2020 15:45:31 +0200 Subject: [PATCH 124/878] Update osmpoi.html --- apps/osmpoi/osmpoi.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/osmpoi/osmpoi.html b/apps/osmpoi/osmpoi.html index 651e34e7a..0096b78a0 100644 --- a/apps/osmpoi/osmpoi.html +++ b/apps/osmpoi/osmpoi.html @@ -141,7 +141,7 @@ }); document.getElementById("upload").addEventListener("click", function() { var app = `var features = ${JSON.stringify(features)}; -var img_nofix = require("heatshrink").decompress(atob("mEwhBC/AH4A/AGnXwMrgMrBg4KBgOBwIOBldWwNWAAmBCIOB1kBF5mBlVVCwInBqwzBAQIcBEQNVqtcFwIRB64AD1gPBlcGGYIAMFIOG2FbrdcFgVWrgHBw2x2Owqss1h0Bq0slcsGoIIClR8IQQ2BrYjBEgOGwwrC2AIB6uwlVWEgMxqo6BAAcxq2s1hsBGB1b2AAExg1CGAUxRQNWlQ9BAA1blQOCqzBMQ4KQBAAYFBF4aYBD4NVNoQAIGAJhOBoIvFxhgBAgOrmJdJwAwGeoRgMqyQGdYReBJoMqZAIBBAQ1cAgOwrZxCeZlWrmMF5ExPgIuEXYiRHMAOBL5oVDGYItB6uGqxeBFBCPDBQcqMAQuKlgvBXAWMw2rDIOxraOBLwaMEwAHCBQhQBF5jvGLoIZB6wvBwKwBLopABXgIAFq2BF5krqy+FF4OxF5ItBIgJaBBQlcCYLUBFxMBq1VRwRfEX4IvCqqCBRISSFSAQEBqumL5krwNc6orBAARMBAYOAJQIvBAB0xWAIvMXwIqBFweMAgSrB1kxwCLCABVbXwKPMgCOBFoYABLwQGBmIaBmKyCR5UxwJeBGIK/KQAOw1ereQIsCLwOMYAPXlQnBF4VcMoIFBXwdbWAKOBR5mAdgerw+G1YuBBIJgBwMxrdcGQQrCqo3C2AvBFwOBgLvMRoRdCw6XElRNBwMqmNVFoVbwDtEFwKiBXxZgCXwgECJoStB64ABGASICBoWGqsqFwUrlYuLgA9BdIex6orBlcxgwuD1gABegIyBAAaJBHgMGLpgvDraJFlgnCqwuB0wqBwIyCwIACHIdVMgOBGB1cRoQuBFQQABGAOmmLjCLAWmGQQsBFoJJBBYJgPEIIuGGAUAWwQOBwzABFYLEC6p5Cra/NF4Nb2GMFw4ABlYvCxgxCAAYrB1b2CqrANd4YuJF4YAExg2BBIIEBBAS/OF4SuBFxFWlQkELYZmBBAmGLxsAldcLpVWgxXCF44EDAANcF55hBFxSbBKwooCBQIABBASOOlcrFxuxFw+MFoYACmJQBXxouK2PV6pWEFQWx1aVGRx4uIwLqBDoNVqtWquAGIhnBGgOGwFVmOsgIvN1hdHgFbrcxq2BAwIDCmNbwwACBwI8BwMsRxodBMA2BZAWmDYJMFlgmCVAIPJGCIFBwJ3OwIpQGBCSBAYJ2OADYsCAQIupAH4A/AH4AoA")); +var img_nofix = require("heatshrink").decompress(atob("mEwhBC/AH4A/AH4A/AC2swMllcrBQoHBktWwIEBlYEBqwAEgAICF6FWldbrgDBAIMrFIIhBrlbAAIIBwOsAAgsClcxF6ErrmG2GGw1cqsxrmAwuG2OxxkxFoOCq1VFANVLgIyBPI4vLq2F2OwAAQrCAgPVw0xEgVVMoQ7BwsxmOm1iUCMCIuD2GM2AvC2IuDFQIACwADCrZrCGCOBqovI2NcEAIuBTwQAHlZhCL6FVYAKQG2NV1i3BZYIpDrZiFlb1BYSFWwAvG6tbwOCmIuFF4YAC2FVwOBMCFWraBCRwReDBYIpELQOAAQQ5CqpgBF57RBFYK+C2IcBw4vBEQIwDrYEDrlbGYOMmMr64vQd4hcBX4VcF4LsGOIYGCxhMBYAKORGAhhBF4TtBAAzvFwuAwIvPlbuBXIQAE2BMBHgIoBE4QvEricBqtWF4KPOF4KICAAReCd4WBdoYAJmKPCF50lrhYCYIuxreBwUxR5RrBrmCwIABF54pCFwrkBJoMxFAKGBF4lcFwNbR4JxBX6GGFYeHSoOGSQJgBGARVBFoIqCMIWMlS+ClbvRMIbFEJ4PXwMrmIqBAARjDleB67ABFxowCYAgDBQQVbFwIAB00xGAQMDA4OCNoJdOAAWBYAex6uGNAIcBFwSvB1mCq1VFYMxqwICA4IvRDgKKDw0qwQrBPgIuBX4IoCAAmBDILQCF6AwBwBgBFwgwCldVTQKJBqtcwB1BSgXV6uAXyAvCrYuHAAMrrYuBGIQABwoGBOgWxF6SEBFwWmFwpgBF4IADxgyC2IFCR6Z5BLpHX1krLoQADLYQHEqrvRWQMrFxKOEF4eMxgyBGgVWkovRgCMH1kqZIInBLwwtCRwZfQqxdLEYQuFAQYHCraORq2BXZPVKwIABEoIGBFoYCCRwNWRyIuIquGrgfBldWwGAwqMBFYVbrlcqovSL42sksrwCsBD4QDBkoyBqsxFQINBmItRL4UrGAZdBLIIABCQ8lgAsBH4IsSGA4uBDq4wTq0xmIuqAH4A/AH4A/AH4AHA=")); var img_fix = require("heatshrink").decompress(atob("mEwhBC/AH4A/AH4A/AE0rg4vtq8PF1kHxM7gJesF4Jgrg+IF4M6MFReBF4JgqXoIvDMFJeCF4RgoLwYvDnZgmLwYvEMEpeEF4jBlmYvIMEheFF4pgjXogvGMEReGF407MEBeGF45gfg+IF5rBfLw4vHMDxeIF5BgdLxAvIMDkHFxAvJMDZeJF5JgaLxQvKnZgYLxQvLMC5eLF5bBXmYvWMCxeMF5hgVXpYvNMCheNF5s7MCReNF5xgRg+IFZNersylcHhEPmjBbLw1er1XlkHIhI0CnRgUmQqEKwKnRgIzBiBpBnUICpszryCCFiIyGM4TBRAH4A/AH4A/AH4AFA")); // https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js From 9d678772943b6e19cdfa53113b18933f31524911 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Tue, 21 Apr 2020 16:04:56 +0200 Subject: [PATCH 125/878] ActivePedom 0.03 --- apps/activepedom/app.js | 44 ++++++++++++++++++++++++++++++++------ apps/activepedom/widget.js | 26 ++++++++++++++-------- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/apps/activepedom/app.js b/apps/activepedom/app.js index f966530d0..0680e2d1a 100644 --- a/apps/activepedom/app.js +++ b/apps/activepedom/app.js @@ -1,8 +1,31 @@ (() => { +//Graph module, as long as modules are not added by the app loader +Modules.addCached("graph",function(){exports.drawAxes=function(b,c,a){function h(a){return e+m*(a-t)/x}function l(a){return f+g-g*(a-n)/u}var k=a.padx||0,d=a.pady||0,t=-k,w=c.length+k-1,n=(void 0!==a.miny?a.miny:a.miny=c.reduce(function(a,b){return Math.min(a,b)},c[0]))-d;c=(void 0!==a.maxy?a.maxy:a.maxy=c.reduce(function(a,b){return Math.max(a,b)},c[0]))+d;a.gridy&&(d=a.gridy,n=d*Math.floor(n/d),c=d*Math.ceil(c/d));var e=a.x||0,f=a.y||0,m=a.width||b.getWidth()-(e+1),g=a.height||b.getHeight()-(f+1);a.axes&&(null!==a.ylabel&& + (e+=6,m-=6),null!==a.xlabel&&(g-=6));a.title&&(f+=6,g-=6);a.axes&&(b.drawLine(e,f,e,f+g),b.drawLine(e,f+g,e+m,f+g));a.title&&(b.setFontAlign(0,-1),b.drawString(a.title,e+m/2,f-6));var x=w-t,u=c-n;u||(u=1);if(a.gridx){b.setFontAlign(0,-1,0);var v=a.gridx;for(d=Math.ceil((t+k)/v)*v;d<=w-k;d+=v){var r=h(d),p=a.xlabel?a.xlabel(d):d;b.setPixel(r,f+g-1);var q=b.stringWidth(p)/2;null!==a.xlabel&&r>q&&b.getWidth()>r+q&&b.drawString(p,r,f+g+2)}}if(a.gridy)for(b.setFontAlign(0,0,1),d=n;d<=c;d+=a.gridy)k=l(d), + p=a.ylabel?a.ylabel(d):d,b.setPixel(e+1,k),q=b.stringWidth(p)/2,null!==a.ylabel&&k>q&&b.getHeight()>k+q&&b.drawString(p,e-5,k+1);b.setFontAlign(-1,-1,0);return{x:e,y:f,w:m,h:g,getx:h,gety:l}};exports.drawLine=function(b,c,a){a=a||{};a=exports.drawAxes(b,c,a);var h=!0,l;for(l in c)h?b.moveTo(a.getx(l),a.gety(c[l])):b.lineTo(a.getx(l),a.gety(c[l])),h=!1;return a};exports.drawBar=function(b,c,a){a=a||{};a.padx=1;a=exports.drawAxes(b,c,a);for(var h in c)b.fillRect(a.getx(h-.5)+1,a.gety(c[h]),a.getx(h+ + .5)-1,a.gety(0));return a}}); + const storage = require("Storage"); +const SETTINGS_FILE = 'activepedom.settings.json'; var history = 86400000; // 28800000=8h 43200000=12h //86400000=24h +//return setting +function setting(key) { +//define default settings +const DEFAULTS = { + 'cMaxTime' : 1100, + 'cMinTime' : 240, + 'stepThreshold' : 30, + 'intervalResetActive' : 30000, + 'stepSensitivity' : 80, + 'stepGoal' : 10000, + 'stepLength' : 75, +}; +if (!settings) { loadSettings(); } +return (key in settings) ? settings[key] : DEFAULTS[key]; +} + //Convert ms to time function getTime(t) { date = new Date(t); @@ -58,8 +81,8 @@ function drawGraph() { filename = filename = "activepedom-" + now.getFullYear() + month + now.getDate() + ".data"; var csvFile = storage.open(filename, "r"); times = getArrayFromCSV(csvFile, 0); - first = getDate(times[0]) + " " + getTime(times[0]); - last = getDate (times[times.length-1]) + " " + getTime(times[times.length-1]); + first = getDate(times[0]) + " " + getTime(times[0]); //first entry in datafile + last = getDate (times[times.length-1]) + " " + getTime(times[times.length-1]); //last entry in datafile //free memory csvFile = undefined; times = undefined; @@ -67,21 +90,24 @@ function drawGraph() { //steps var csvFile = storage.open(filename, "r"); steps = getArrayFromCSV(csvFile, 1); + first = first + " " + steps[0] + "/" + setting('stepGoal'); + last = last + " " + steps[steps.length-1] + "/" + setting('stepGoal'); + //define y-axis grid labels stepsLastEntry = steps[steps.length-1]; if (stepsLastEntry < 1000) gridyValue = 100; - if (stepsLastEntry >= 1000 && stepsLastEntry < 10000) gridyValue = 500; + if (stepsLastEntry >= 1000 && stepsLastEntry < 10000) gridyValue = 1000; if (stepsLastEntry > 10000) gridyValue = 5000; //draw drawMenu(); - g.drawString("First: " + first, 40, 30); - g.drawString(" Last: " + last, 40, 40); + g.drawString("First: " + first, 10, 30); + g.drawString(" Last: " + last, 10, 40); require("graph").drawLine(g, steps, { //title: "Steps Counted", axes : true, gridy : gridyValue, - y : 50, //offset on screen + y : 60, //offset on screen x : 5, //offset on screen }); //free memory from big variables @@ -128,6 +154,12 @@ setWatch(function() { //BTN4 setWatch(function() { //BTN5 }, BTN5, {edge:"rising", debounce:50, repeat:true}); +//load settings +let settings; +function loadSettings() { +settings = storage.readJSON(SETTINGS_FILE, 1) || {}; +} + drawMenu(); })(); \ No newline at end of file diff --git a/apps/activepedom/widget.js b/apps/activepedom/widget.js index 7879b2056..c6bd410ce 100644 --- a/apps/activepedom/widget.js +++ b/apps/activepedom/widget.js @@ -35,16 +35,24 @@ now = new Date(); month = now.getMonth() + 1; if (month < 10) month = "0" + month; - filename = filename = "activepedom-" + now.getFullYear() + month + now.getDate() + ".data"; + filename = filename = "activepedom" + now.getFullYear() + month + now.getDate() + ".data"; dataFile = s.open(filename,"a"); - if (dataFile) dataFile.write([ - now.getTime(), - stepsCounted, - active, - stepsTooShort, - stepsTooLong, - stepsOutsideTime, - ].join(",")+"\n"); + if (dataFile) { + if (dataFile.getLength() == 0) { + stepsToWrite = 0; + } + else { + stepsToWrite = stepsCounted; + } + dataFile.write([ + now.getTime(), + stepsToWrite, + active, + stepsTooShort, + stepsTooLong, + stepsOutsideTime, + ].join(",")+"\n"); + } dataFile = undefined; } From 8dd71947bdc0f791717add161121d053e423e91c Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Tue, 21 Apr 2020 16:32:15 +0200 Subject: [PATCH 126/878] Fix typo --- apps/activepedom/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/activepedom/app.js b/apps/activepedom/app.js index 0680e2d1a..0a9b3b93f 100644 --- a/apps/activepedom/app.js +++ b/apps/activepedom/app.js @@ -78,7 +78,7 @@ function drawGraph() { now = new Date(); month = now.getMonth() + 1; if (month < 10) month = "0" + month; - filename = filename = "activepedom-" + now.getFullYear() + month + now.getDate() + ".data"; + filename = filename = "activepedom" + now.getFullYear() + month + now.getDate() + ".data"; var csvFile = storage.open(filename, "r"); times = getArrayFromCSV(csvFile, 0); first = getDate(times[0]) + " " + getTime(times[0]); //first entry in datafile @@ -162,4 +162,4 @@ settings = storage.readJSON(SETTINGS_FILE, 1) || {}; drawMenu(); -})(); \ No newline at end of file +})(); From 8272b19bb6517b96950502ff3f422cab8e6fecea Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Tue, 21 Apr 2020 19:38:02 +0100 Subject: [PATCH 127/878] Finish BuffGym app --- apps/buffgym/buffgym-exercise.js | 115 ++---- apps/buffgym/buffgym-icon.js | 2 +- apps/buffgym/buffgym-program-a.json | 33 ++ apps/buffgym/buffgym-program-b.json | 33 ++ apps/buffgym/buffgym-program-index.json | 10 + apps/buffgym/buffgym-program.js | 62 ++- apps/buffgym/buffgym-programs.json | 1 - apps/buffgym/buffgym-programs.json.unminified | 101 ----- apps/buffgym/buffgym-set.js | 42 +- apps/buffgym/buffgym.app.js | 373 ++++++++++-------- apps/buffgym/buffgym.png | Bin 1800 -> 7576 bytes 11 files changed, 363 insertions(+), 409 deletions(-) create mode 100644 apps/buffgym/buffgym-program-a.json create mode 100644 apps/buffgym/buffgym-program-b.json create mode 100644 apps/buffgym/buffgym-program-index.json delete mode 100644 apps/buffgym/buffgym-programs.json delete mode 100644 apps/buffgym/buffgym-programs.json.unminified mode change 100644 => 100755 apps/buffgym/buffgym.png diff --git a/apps/buffgym/buffgym-exercise.js b/apps/buffgym/buffgym-exercise.js index 99d658571..68e49be84 100644 --- a/apps/buffgym/buffgym-exercise.js +++ b/apps/buffgym/buffgym-exercise.js @@ -1,116 +1,76 @@ -const STARTED = 1; -const RESTING = 2; -const COMPLETED = 3; -const ONE_SECOND = 1000; - exports = class Exercise { - constructor(params /*{title, weight, unit, restPeriod}*/) { - const DEFAULTS = { - title: "Unknown", - weight: 0, - unit: "Kg", - restPeriod: 90, - weightIncrement: 2.5, - }; - const p = Object.assign({}, DEFAULTS, params); - - this._title = p.title; - this._weight = p.weight; - this._unit = p.unit; - this._originalRestPeriod = p.restPeriod; // Used when reseting _restPeriod - this._restPeriod = p.restPeriod; - this._weightIncrement = p.weightIncrement; - this._started = new Date(); - this._completed = false; - this._sets = []; + constructor(params) { + this.title = params.title; + this.weight = params.weight; + this.unit = params.unit; + this.restPeriod = params.restPeriod; + this.completed = false; + this.sets = []; this._restTimeout = null; this._restInterval = null; this._state = null; - } - - get title() { - return this._title; + this._originalRestPeriod = params.restPeriod; + this._weightIncrement = params.weightIncrement || 2.5; } get humanTitle() { - return `${this._title} ${this._weight}${this._unit}`; + return `${this.title} ${this.weight}${this.unit}`; } get subTitle() { - const totalSets = this._sets.length; - const uncompletedSets = this._sets.filter((set) => !set.isCompleted()).length; + const totalSets = this.sets.length; + const uncompletedSets = this.sets.filter((set) => !set.isCompleted()).length; const currentSet = (totalSets - uncompletedSets) + 1; return `Set ${currentSet} of ${totalSets}`; } - get restPeriod() { - return this._restPeriod; - } - decRestPeriod() { - this._restPeriod--; - } - - get weight() { - return this._weight; - } - - get unit() { - return this._unit; - } - - get started() { - return this._started; + this.restPeriod--; } addSet(set) { - this._sets.push(set); + this.sets.push(set); } - addSets(sets) { - sets.forEach(set => this.addSet(set)); - } - - get currentSet() { - return this._sets.filter(set => !set.isCompleted())[0]; + currentSet() { + return this.sets.filter(set => !set.isCompleted())[0]; } isLastSet() { - return this._sets.filter(set => !set.isCompleted()).length === 1; + return this.sets.filter(set => !set.isCompleted()).length === 1; } isCompleted() { - return !!this._completed; + return !!this.completed; } canSetCompleted() { - return this._sets.filter(set => set.isCompleted()).length === this._sets.length; + return this.sets.filter(set => set.isCompleted()).length === this.sets.length; } setCompleted() { if (!this.canSetCompleted()) throw "All sets must be completed"; - if (this.canProgress) this._weight += this._weightIncrement; - this._completed = true; + if (this.canProgress()) this.weight += this._weightIncrement; + this.completed = true; } - get canProgress() { + canProgress() { let completedRepsTotalSum = 0; let targetRepsTotalSum = 0; - - const completedRepsTotal = this._sets.forEach(set => completedRepsTotalSum += set.reps); - const targetRepsTotal = this._sets.forEach(set => targetRepsTotalSum += set.maxReps); + this.sets.forEach(set => completedRepsTotalSum += set.reps); + this.sets.forEach(set => targetRepsTotalSum += set.maxReps); return (targetRepsTotalSum - completedRepsTotalSum) === 0; } startRestTimer(program) { this._restTimeout = setTimeout(() => { - this.next(); - }, ONE_SECOND * this._restPeriod); + this.next(program); + }, 1000 * this.restPeriod); this._restInterval = setInterval(() => { program.emit("redraw"); - }, ONE_SECOND); + }, 1000 ); } resetRestTimer() { @@ -118,7 +78,7 @@ exports = class Exercise { clearInterval(this._restInterval); this._restTimeout = null; this._restInterval = null; - this._restPeriod = this._originalRestPeriod; + this.restPeriod = this._originalRestPeriod; } isRestTimerRunning() { @@ -129,52 +89,51 @@ exports = class Exercise { clearWatch(); setWatch(() => { - this.currentSet.incReps(); + this.currentSet().incReps(); program.emit("redraw"); }, BTN1, {repeat: true}); setWatch(program.next.bind(program), BTN2, {repeat: false}); setWatch(() => { - this.currentSet.decReps(); + this.currentSet().decReps(); program.emit("redraw"); }, BTN3, {repeat: true}); } setupRestingButtons(program) { clearWatch(); - setWatch(program.next.bind(program), BTN2, {repeat: true}); + setWatch(program.next.bind(program), BTN2, {repeat: false}); } next(program) { - global.poo = this; + const STARTED = 1; + const RESTING = 2; + const COMPLETED = 3; + switch(this._state) { case null: - console.log("XXX 1 moving null -> STARTED"); this._state = STARTED; this.setupStartedButtons(program); break; case STARTED: - console.log("XXX 2 moving STARTED -> RESTING"); this._state = RESTING; this.startRestTimer(program); this.setupRestingButtons(program); break; case RESTING: this.resetRestTimer(); - this.currentSet.setCompleted(); + this.currentSet().setCompleted(); if (this.canSetCompleted()) { - console.log("XXX 3b moving RESTING -> COMPLETED"); this._state = COMPLETED; this.setCompleted(); } else { - console.log("XXX 3a moving RESTING -> null"); this._state = null; } // As we are changing state and require it to be reprocessed // invoke the next step of program - program.next(program); + program.next(); break; default: throw "Exercise: Attempting to move to an unknown state"; diff --git a/apps/buffgym/buffgym-icon.js b/apps/buffgym/buffgym-icon.js index 949b0e45b..31764acbb 100644 --- a/apps/buffgym/buffgym-icon.js +++ b/apps/buffgym/buffgym-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwhC/AFEEolAC6lN7vdDCcECwPd6guVGCYuDC4cCBQMikQXQJAMjkECmcyIx4XDmUjmYvLC4XUDARHBIoIWLgATCGQdA7tEonQC5ouDDYg0BOxgSEAggwKRwgUCC6ZIDSwoXNogWDDgNCAgIWIkUEoUk6kiCgMkokipsiBIQXIki2CAgNCAoYADC5Eic4Mic4ICCAIIJCC5MzAAcykYGEAAIXOABAXTmUzGoIXVAIIXLB4SICDIovjO76PZbYR3PDI4XiI6530MIh3SC6R33C/oAOC48CCxsgC44A/ADY=")) +require("heatshrink").decompress(atob("mEwxH+ACPI5AUSADAtB5vNGFQtBAIfNF95hoF4wwoF5AwmF5BhmXYbAEF/6QbF1QwIF04qB54ADAwIwoF4oRKBoIvsB4gvZ58kkgCDFxoxaF5wuHGDQcMF5IwXDZwLDGDmlDIWlkgJDSwIABCRAwPDQohCFgIABDQIOCFwYABr4RCCQIvQDYguEAAwtFF5owJDZAvHFw4vFOYQvKFAowMBxIvFMQwvPAB4wFUQ4vJGDYvUGC4vNdgyuEGDIsNFwYwGNAgAPExAvMGIdfTIovfTpYvrfRCOkZ44ugF44NGF05gUFyQvKGIoueGKIufGJ4uhG5oupGItfr4vvAAgvlGAQvt/wrEF9oEGF841IF9QGHX0oGIAD8kAAYJOFzwEBBQoMFACA=")); \ No newline at end of file diff --git a/apps/buffgym/buffgym-program-a.json b/apps/buffgym/buffgym-program-a.json new file mode 100644 index 000000000..7ebaf3741 --- /dev/null +++ b/apps/buffgym/buffgym-program-a.json @@ -0,0 +1,33 @@ +{ + "title": "Program A", + "exercises": [ + { + "title": "Squats", + "weight": 40, + "unit": "Kg", + "sets": [5, 5, 5, 5, 5], + "restPeriod": 90 + }, + { + "title": "Overhead press", + "weight": 20, + "unit": "Kg", + "sets": [5, 5, 5, 5, 5], + "restPeriod": 90 + }, + { + "title": "Deadlift", + "weight": 20, + "unit": "Kg", + "sets": [5], + "restPeriod": 90 + }, + { + "title": "Pullups", + "weight": 0, + "unit": "Kg", + "sets": [10, 10, 10], + "restPeriod": 90 + } + ] +} \ No newline at end of file diff --git a/apps/buffgym/buffgym-program-b.json b/apps/buffgym/buffgym-program-b.json new file mode 100644 index 000000000..b93348621 --- /dev/null +++ b/apps/buffgym/buffgym-program-b.json @@ -0,0 +1,33 @@ +{ + "title": "Program B", + "exercises": [ + { + "title": "Squats", + "weight": 40, + "unit": "Kg", + "sets": [5, 5, 5, 5, 5], + "restPeriod": 90 + }, + { + "title": "Bench press", + "weight": 20, + "unit": "Kg", + "sets": [5, 5, 5, 5, 5], + "restPeriod": 90 + }, + { + "title": "Row", + "weight": 20, + "unit":"Kg", + "sets": [5, 5, 5, 5, 5], + "restPeriod": 90 + }, + { + "title": "Tricep extension", + "weight": 20, + "unit": "Kg", + "sets": [10, 10, 10], + "restPeriod": 90 + } + ] +} \ No newline at end of file diff --git a/apps/buffgym/buffgym-program-index.json b/apps/buffgym/buffgym-program-index.json new file mode 100644 index 000000000..3bb51f1b5 --- /dev/null +++ b/apps/buffgym/buffgym-program-index.json @@ -0,0 +1,10 @@ +[ + { + "title": "Program A", + "file": "buffgym-program-a.json" + }, + { + "title": "Program B", + "file": "buffgym-program-b.json" + } +] \ No newline at end of file diff --git a/apps/buffgym/buffgym-program.js b/apps/buffgym/buffgym-program.js index 956827f56..68a069da5 100644 --- a/apps/buffgym/buffgym-program.js +++ b/apps/buffgym/buffgym-program.js @@ -1,68 +1,56 @@ exports = class Program { constructor(params) { - const DEFAULTS = { - title: "Unknown", - trainDay: "", // Day of week - }; - const p = Object.assign({}, DEFAULTS, params); - - this._title = p.title; - this._trainDay = p.trainDay; - this._exercises = []; - + this.title = params.title; + this.exercises = []; + this.completed = false; this.on("redraw", redraw.bind(null, this)); } - get title() { - return `${this._title} - ${this._trainDay}`; - } - - addExercise(exercise) { - this._exercises.push(exercise); - } - addExercises(exercises) { - exercises.forEach(exercise => this.addExercise(exercise)); + exercises.forEach(exercise => this.exercises.push(exercise)); } currentExercise() { - return ( - this._exercises - .filter(exercise => !exercise.isCompleted())[0] - ); + return this.exercises.filter(exercise => !exercise.isCompleted())[0]; } canComplete() { - return ( - this._exercises - .filter(exercise => exercise.isCompleted()) - .length === this._exercises.length - ); + return this.exercises.filter(exercise => exercise.isCompleted()).length === this.exercises.length; } setCompleted() { if (!this.canComplete()) throw "All exercises must be completed"; - this._completed = true; + this.completed = true; } isCompleted() { - return !!this._completed; + return !!this.completed; + } + + toJSON() { + return { + title: this.title, + exercises: this.exercises.map(exercise => { + return { + title: exercise.title, + weight: exercise.weight, + unit: exercise.unit, + sets: exercise.sets.map(set => set.maxReps), + restPeriod: exercise.restPeriod, + }; + }), + }; } // State machine next() { - console.log("XXX Program.next"); - const exercise = this.currentExercise(); - - // All exercises are completed so mark the - // Program as comleted if (this.canComplete()) { this.setCompleted(); this.emit("redraw"); - return; } - exercise.next(this); + // Call current exercise state machine + this.currentExercise().next(this); } } \ No newline at end of file diff --git a/apps/buffgym/buffgym-programs.json b/apps/buffgym/buffgym-programs.json deleted file mode 100644 index 7551c7a47..000000000 --- a/apps/buffgym/buffgym-programs.json +++ /dev/null @@ -1 +0,0 @@ -[{"title":"Program A","exercises":[{"title":"Squats","weight":40,"unit":"Kg","sets":[5,5,5,5,5]},{"title":"Overhead press","weight":20,"unit":"Kg","sets":[5,5,5,5,5]},{"title":"Deadlift","weight":20,"unit":"Kg","sets":[5]},{"title":"Pullups","weight":0,"unit":"Kg","sets":[10,10,10]}]},{"title":"Program B","exercises":[{"title":"Squats","weight":40,"unit":"Kg","sets":[5,5,5,5,5]},{"title":"Bench press","weight":20,"unit":"Kg","sets":[5,5,5,5,5]},{"title":"Row","weight":20,"unit":"Kg","sets":[5,5,5,5,5]},{"title":"Tricep extension","weight":20,"unit":"Kg","sets":[10,10,10]}]}] \ No newline at end of file diff --git a/apps/buffgym/buffgym-programs.json.unminified b/apps/buffgym/buffgym-programs.json.unminified deleted file mode 100644 index cd005eeab..000000000 --- a/apps/buffgym/buffgym-programs.json.unminified +++ /dev/null @@ -1,101 +0,0 @@ -[ - { - "title": "Program A", - "exercises": [ - { - "title": "Squats", - "weight": 40, - "unit": "Kg", - "sets": [ - 5, - 5, - 5, - 5, - 5 - ] - }, - { - "title": "Overhead press", - "weight": 20, - "unit": "Kg", - "sets": [ - 5, - 5, - 5, - 5, - 5 - ] - }, - { - "title": "Deadlift", - "weight": 20, - "unit": "Kg", - "sets": [ - 5 - ] - }, - { - "title": "Pullups", - "weight": 0, - "unit": "Kg", - "sets": [ - 10, - 10, - 10 - ] - } - ] - }, - { - "title": "Program B", - "exercises": [ - { - "title": "Squats", - "weight": 40, - "unit": "Kg", - "sets": [ - 5, - 5, - 5, - 5, - 5 - ] - }, - { - "title": "Bench press", - "weight": 20, - "unit": "Kg", - "sets": [ - 5, - 5, - 5, - 5, - 5 - ] - }, - { - "title": "Row", - "weight": 20, - "unit":"Kg", - "sets": [ - 5, - 5, - 5, - 5, - 5 - ] - - }, - { - "title": "Tricep extension", - "weight": 20, - "unit": "Kg", - "sets": [ - 10, - 10, - 10 - ] - } - ] - } -] \ No newline at end of file diff --git a/apps/buffgym/buffgym-set.js b/apps/buffgym/buffgym-set.js index aed6df260..4bd12d7ec 100644 --- a/apps/buffgym/buffgym-set.js +++ b/apps/buffgym/buffgym-set.js @@ -1,46 +1,28 @@ exports = class Set { constructor(maxReps) { - this._minReps = 0; - this._maxReps = maxReps; - this._reps = 0; - this._completed = false; - } - - get title() { - return this._title; - } - - get weight() { - return this._weight; + this.minReps = 0; + this.maxReps = maxReps; + this.reps = 0; + this.completed = false; } isCompleted() { - return !!this._completed; + return !!this.completed; } setCompleted() { - this._completed = true; - } - - get reps() { - return this._reps; - } - - get maxReps() { - return this._maxReps; + this.completed = true; } incReps() { - if (this._completed) return; - if (this._reps >= this._maxReps) return; - - this._reps++; + if (this.completed) return; + if (this.reps >= this.maxReps) return; + this.reps++; } decReps() { - if (this._completed) return; - if (this._reps <= this._minReps) return; - - this._reps--; + if (this.completed) return; + if (this.reps <= this.minReps) return; + this.reps--; } } \ No newline at end of file diff --git a/apps/buffgym/buffgym.app.js b/apps/buffgym/buffgym.app.js index e1ab3e66b..eeabd5c29 100755 --- a/apps/buffgym/buffgym.app.js +++ b/apps/buffgym/buffgym.app.js @@ -1,177 +1,135 @@ +Bangle.setLCDMode("120x120"); + const W = g.getWidth(); const H = g.getHeight(); const RED = "#d32e29"; const PINK = "#f05a56"; const WHITE = "#ffffff"; -const Set = require("buffgym-set.js"); -const Exercise = require("buffgym-exercise.js"); -const Program = require("buffgym-program.js"); - -function centerStringX(str) { - return (W - g.stringWidth(str)) / 2; -} - -function iconIncrement() { - const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglHA4IpJBYwTHA4RMJCY5oDJo4THKIQKET5IMGCaY7TMaKLTWajbTFJIlICgoVBFYXJYQYSGCggAGCRAVIBgw")); - return img; -} - -function iconDecrement() { - const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglKFJADBCRYABCYQmOFAhNMKIw6FTw4LHCaY7TMaKLTWajbTFJglFCgoVBFYXJYQYSGCggAGCRAVIBgw=")); - return img; -} - -function iconOk() { - const img = require("heatshrink").decompress(atob("ikUxH+AA3XAAgNHCJIVMBYXQ5PC4XJ6AUJCIQQBAAoVCCQwjCAA/JCgglKFJADBCJQxCCYQmMIwZoDJpQMCKIg6KBYwTGFQgeHHYouCCRI7EMYTXFRhILEK5SfFRgYSIborbSbpglFCgoVBFYXJYQYSGCggAGCRAVIBgwA==")); - return img; -} - function drawMenu(params) { + const hs = require("heatshrink"); + const incImg = hs.decompress(atob("gsFwMAkM+oUA")); + const decImg = hs.decompress(atob("gsFwIEBnwCBA")); + const okImg = hs.decompress(atob("gsFwMAhGFo0A")); const DEFAULT_PARAMS = { showBTN1: false, showBTN2: false, showBTN3: false, }; const p = Object.assign({}, DEFAULT_PARAMS, params); - if (p.showBTN1) g.drawImage(iconIncrement(), W - 30, 10); - if (p.showBTN2) g.drawImage(iconOk(), W - 30, 110); - if (p.showBTN3) g.drawImage(iconDecrement(), W - 30, 210); + if (p.showBTN1) g.drawImage(incImg, W - 10, 10); + if (p.showBTN2) g.drawImage(okImg, W - 10, 60); + if (p.showBTN3) g.drawImage(decImg, W - 10, 110); } -function clearScreen() { - g.setColor(RED); - g.fillRect(0,0,W,H); -} - -function drawTitle(exercise) { - const title = exercise.humanTitle; - - g.setFont("Vector",20); - g.setColor(WHITE); - g.drawString(title, centerStringX(title), 5); -} - -function drawReps(exercise) { - const set = exercise.currentSet; +function drawSet(exercise) { + const set = exercise.currentSet(); if (set.isCompleted()) return; + g.clear(); + + // Draw exercise title g.setColor(PINK); - g.fillCircle(W / 2, H / 2, 50); + g.fillRect(15, 0, W - 15, 18); + g.setFontAlign(0, -1); + g.setFont("6x8", 1); g.setColor(WHITE); - g.setFont("Vector", 40); - g.drawString(set.reps, centerStringX(set.reps), (H - 45) / 2); - g.setFont("Vector", 15); - const note = `of ${set.maxReps}`; - g.drawString(note, centerStringX(note), (H / 2) + 25); -} - -function drawSets(exercise) { - const sets = exercise.subTitle; - + g.drawString(exercise.title, W / 2, 5); + g.setFont("6x8", 1); + g.drawString(exercise.weight + " " + exercise.unit, W / 2, 27); + // Draw completed reps counter + g.setFontAlign(0, 0); + g.setColor(PINK); + g.fillRect(15, 42, W - 15, 80); g.setColor(WHITE); - g.setFont("Vector", 15); - g.drawString(sets, centerStringX(sets), H - 25); -} + g.setFont("6x8", 5); + g.drawString(set.reps, (W / 2) + 2, (H / 2) + 1); + g.setFont("6x8", 1); + const note = `Target reps: ${set.maxReps}`; + g.drawString(note, W / 2, H - 24); + // Draw sets monitor + g.drawString(exercise.subTitle, W / 2, H - 12); -function drawSetProgress(exercise) { - drawTitle(exercise); - drawReps(exercise); - drawSets(exercise); drawMenu({showBTN1: true, showBTN2: true, showBTN3: true}); + + g.flip(); } -function drawStartNextExercise() { - const title = "Good work"; - const msg = "No need to rest\nmove straight on\nto the next exercise"; - - g.setColor(WHITE); - g.setFont("Vector", 35); - g.drawString(title, centerStringX(title), 10); - g.setFont("Vector", 15); - g.drawString(msg, 30, 150); - drawMenu({showBTN1: false, showBTN2: true, showBTN3: false}); -} - -function drawProgramCompleted() { +function drawProgDone() { const title1 = "You did"; const title2 = "GREAT!"; const msg = "That's the program\ncompleted. Now eat\nsome food and\nget plenty of rest."; clearWatch(); setWatch(Bangle.showLauncher, BTN2, {repeat: false}); - - g.setColor(WHITE); - g.setFont("Vector", 35); - g.drawString(title1, centerStringX(title1), 10); - g.setFont("Vector", 40); - g.drawString(title2, centerStringX(title2), 50); - g.setFont("Vector", 15); - g.drawString(msg, 30, 150); - drawMenu({showBTN1: false, showBTN2: true, showBTN3: false}); -} - -/* -function drawExerciseCompleted(program) { - const exercise = program.currentExercise(); - const title = exercise.canProgress? - "WELL DONE!" : - "NOT BAD!"; - const msg = exercise.canProgress? - `You weight is automatically increased\nfor ${exercise.title} to ${exercise.weight}${exercise.unit}` : - "It looks like you struggled\non a few sets, your weight will\nstay the same"; - const action = "Move straight on to the next exercise"; - - clearScreen(); - g.setColor(WHITE); - g.setFont("Vector", 20); - g.drawString(title, centerStringX(title), 10); - g.setFont("Vector", 10); - g.drawString(msg, centerStringX(msg), 180); - g.drawString(action, centerStringX(action), 210); drawMenu({showBTN2: true}); - clearWatch(); - setWatch(() => { - init(program); - }, BTN2, {repeat: false}); + g.setFontAlign(0, -1); + g.setColor(WHITE); + g.setFont("6x8", 2); + g.drawString(title1, W / 2, 10); + g.drawString(title2, W / 2, 30); + g.setFont("6x8", 1); + g.drawString(msg, (W / 2) + 3, 70); + g.flip(); +} + +function drawSetComp() { + const title = "Good work"; + const msg = "No need to rest\nmove straight on\nto the next\nexercise.Your\nweight has been\nincreased for\nnext time!"; + + g.clear(); + drawMenu({showBTN2: true}); + + g.setFontAlign(0, -1); + g.setColor(WHITE); + g.setFont("6x8", 2); + g.drawString(title, W / 2, 10); + g.setFont("6x8", 1); + g.drawString(msg, (W / 2) - 2, 45); + + g.flip(); } -*/ function drawRestTimer(program) { const exercise = program.currentExercise(); const motivation = "Take a breather.."; - clearScreen(); - drawMenu({showBTN2: true}); - - g.setColor(PINK); - g.fillCircle(W / 2, H / 2, 50); - g.setColor(WHITE); - g.setFont("Vector", 15); - g.drawString(motivation, centerStringX(motivation), 25); - g.setFont("Vector", 40); - g.drawString(exercise.restPeriod, centerStringX(exercise.restPeriod), (H - 45) / 2); - exercise.decRestPeriod(); if (exercise.restPeriod <= 0) { exercise.resetRestTimer(); - redraw(program); + program.next(); + + return; } + + g.clear(); + drawMenu({showBTN2: true}); + g.setFontAlign(0, -1); + g.setColor(PINK); + g.fillRect(15, 42, W - 15, 80); + g.setColor(WHITE); + g.setFont("6x8", 1); + g.drawString("Have a short\nrest period.", W / 2, 10); + g.setFont("6x8", 5); + g.drawString(exercise.restPeriod, (W / 2) + 2, (H / 2) - 19); + g.flip(); + + exercise.decRestPeriod(); } function redraw(program) { const exercise = program.currentExercise(); - - clearScreen(); + g.clear(); if (program.isCompleted()) { - drawProgramCompleted(program); + saveProg(program); + drawProgDone(program); return; } if (exercise.isRestTimerRunning()) { if (exercise.isLastSet()) { - drawStartNextExercise(program); + drawSetComp(program); } else { drawRestTimer(program); } @@ -179,48 +137,141 @@ function redraw(program) { return; } - drawSetProgress(exercise); + drawSet(exercise); } -function init(program) { - clearWatch(); - program.next(); -} +function drawProgMenu(programs, selProgIdx) { + g.clear(); + g.setFontAlign(0, -1); + g.setColor(WHITE); + g.setFont("6x8", 2); + g.drawString("BuffGym", W / 2, 10); -// Setup training program. This should come from file - -// Squats -function buildPrograms() { - const programsJSON = require("Storage").readJSON("buffgym-programs.json", 1); - - if (!programsJSON) throw "No programs JSON found"; - - const programs = []; - - programsJSON.forEach(programJSON => { - const program = new Program({ - title: programJSON.title, - }); - const exercises = programJSON.exercises.map(exerciseJSON => { - const exercise = new Exercise({ - title: exerciseJSON.title, - weight: exerciseJSON.weight, - unit: exerciseJSON.unit, - }); - exerciseJSON.sets.forEach(setJSON => { - exercise.addSet(new Set(setJSON)); - }); - - return exercise; - }); - program.addExercises(exercises); - programs.push(program); + g.setFont("6x8", 1); + g.setFontAlign(-1, -1); + let selectedProgram = programs[selProgIdx].title; + let yPos = 50; + programs.forEach(program => { + g.setColor("#f05a56"); + g.fillRect(0, yPos, W, yPos + 11); + g.setColor("#ffffff"); + if (selectedProgram === program.title) { + g.drawRect(0, yPos, W - 1, yPos + 11); + } + g.drawString(program.title, 10, yPos + 2); + yPos += 15; }); - - return programs; + g.flip(); } -// For this spike, just run the first program, what will -// really happen is the user picks a program to do from -// some menu on a start page. -init(buildPrograms()[0]); \ No newline at end of file +function setupMenu() { + clearWatch(); + const progs = getProgIndex(); + let selProgIdx = 0; + drawProgMenu(progs, selProgIdx); + + setWatch(()=>{ + selProgIdx--; + if (selProgIdx< 0) selProgIdx = 0; + drawProgMenu(progs, selProgIdx); + }, BTN1, {repeat: true}); + + setWatch(()=>{ + const prog = buildProg(progs[selProgIdx].file); + prog.next(); + }, BTN2, {repeat: false}); + + setWatch(()=>{ + selProgIdx++; + if (selProgIdx > progs.length - 1) selProgIdx = progs.length - 1; + drawProgMenu(progs, selProgIdx); + }, BTN3, {repeat: true}); +} + +function drawSplash() { + g.reset(); + g.setBgColor(RED); + g.clear(); + g.setColor(WHITE); + g.setFontAlign(0,-1); + g.setFont("6x8", 2); + g.drawString("BuffGym", W / 2, 10); + g.setFont("6x8", 1); + g.drawString("5x5", W / 2, 42); + g.drawString("training app", W / 2, 55); + g.drawRect(19, 38, 100, 99); + const img = require("heatshrink").decompress(atob("lkdxH+AB/I5ASQACwpB5vNFkwpBAIfNFdZZkFYwskFZAsiFZBZiVYawEFf6ETFUwsIFUYmB54ADAwIskFYoRKBoIroB4grV58kkgCDFRotWFZwqHFiwYMFZIsTC5wLDFjGlCoWlkgJDRQIABCRAsLCwodCFAIABCwIOCFQYABr4RCCQIrMC4gqEAAwpFFZosFC5ArHFQ4rFNYQrGEgosMBxIrFLQwrLAB4sFSw4rFFjYrQFi4rNbASeEFjIoJFQYsGMAgAPEQgAIGwosCRoorbA=")); + g.drawImage(img, 40, 70); + g.flip(); + + let flasher = false; + let bgCol, txtCol; + const i = setInterval(() => { + if (flasher) { + bgCol = WHITE; + txtCol = RED; + } else { + bgCol = RED; + txtCol = WHITE; + } + flasher = !flasher; + g.setColor(bgCol); + g.fillRect(0, 108, W, 120); + g.setColor(txtCol); + g.drawString("Press btn to begin", W / 2, 110); + g.flip(); + }, 250); + + setWatch(()=>{ + clearInterval(i); + setupMenu(); + }, BTN1, {repeat: false}); + + setWatch(()=>{ + clearInterval(i); + setupMenu(); + }, BTN2, {repeat: false}); + + setWatch(()=>{ + clearInterval(i); + setupMenu(); + }, BTN3, {repeat: false}); +} + +function getProgIndex() { + const progIdx = require("Storage").readJSON("buffgym-program-index.json"); + return progIdx; +} + +function buildProg(fName) { + const Set = require("buffgym-set.js"); + const Exercise = require("buffgym-exercise.js"); + const Program = require("buffgym-program.js"); + const progJSON = require("Storage").readJSON(fName); + const prog = new Program({ + title: progJSON.title, + }); + const exercises = progJSON.exercises.map(exerciseJSON => { + const exercise = new Exercise({ + title: exerciseJSON.title, + weight: exerciseJSON.weight, + unit: exerciseJSON.unit, + restPeriod: exerciseJSON.restPeriod, + }); + exerciseJSON.sets.forEach(setJSON => { + exercise.addSet(new Set(setJSON)); + }); + + return exercise; + }); + prog.addExercises(exercises); + + return prog; +} + +function saveProg(program) { + const fName = getProgIndex().find(prog => prog.title === program.title).file; + require("Storage").writeJSON(fName, program.toJSON()); +} + +drawSplash(); \ No newline at end of file diff --git a/apps/buffgym/buffgym.png b/apps/buffgym/buffgym.png old mode 100644 new mode 100755 index 93a29a4a686f172e5e6dbd2ecb2a1d3edf4751c0..9bde64cc4b4a6cbea919ae5d61fe2f01694da589 GIT binary patch literal 7576 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 Date: Tue, 21 Apr 2020 20:10:56 +0100 Subject: [PATCH 128/878] Add README --- apps/buffgym/README.md | 43 +++++++++++++++++++++++++++++++++ apps/buffgym/buffgym-scrn1.png | Bin 0 -> 4141 bytes apps/buffgym/buffgym-scrn2.png | Bin 0 -> 2801 bytes apps/buffgym/buffgym-scrn3.png | Bin 0 -> 3569 bytes apps/buffgym/buffgym-scrn4.png | Bin 0 -> 3299 bytes apps/buffgym/buffgym-scrn5.png | Bin 0 -> 4500 bytes apps/buffgym/buffgym-scrn6.png | Bin 0 -> 3912 bytes 7 files changed, 43 insertions(+) create mode 100644 apps/buffgym/README.md create mode 100755 apps/buffgym/buffgym-scrn1.png create mode 100755 apps/buffgym/buffgym-scrn2.png create mode 100755 apps/buffgym/buffgym-scrn3.png create mode 100755 apps/buffgym/buffgym-scrn4.png create mode 100755 apps/buffgym/buffgym-scrn5.png create mode 100755 apps/buffgym/buffgym-scrn6.png diff --git a/apps/buffgym/README.md b/apps/buffgym/README.md new file mode 100644 index 000000000..e9e217828 --- /dev/null +++ b/apps/buffgym/README.md @@ -0,0 +1,43 @@ +# BuffGym + +This gym training assistant trains you on the famous [Stronglifts 5x5 workout](https://stronglifts.com/5x5) program. + +## Usage + +When you start the app it will wait on a splash screen until you are ready to start the work out. Press any of the buttons to start + +![](buffgym-scrn1.png) + +You are then presented with the programs menu, use BTN1 to move up the list, and BTN3 to move down the list. Once you have made your selection, press BTN2 to select the program. + +![](buffgym-scrn2.png) + +You will now begin moving through the exercises in the program. You will see the exercise information on the display. +1. At the top is the exercise name, e.g 'Squats' +2. Next is the weight you must train +3. In the center is where you record the number of *reps* you completed (more on that shortly) +4. Below the *reps* value, is the target reps you must try to reach. +5. Below the target reps is the current set you are training, out of the total sets for the exercise. +6. The *reps* value is used to store what you achieved for the current set, you enter this after you have trained on your current set. To alter this value, use BTN1 to increase the value (it will stop at the maximum required reps) and BTN3 to decreas the value to a minimum of 0 (this is the default value). Pressing BTN2 will confirm your reps + +![](buffgym-scrn3.png) + +You will then be presented with a rest timer screen, it counts down and automatically moves to the next exercise when it reaches 0. You can cancel the timer early if you wish by pressing BTN2. If it is the last set of an exercise, you don't need to rest, so it lets you know you have completed all the sets in the exercise and can start the next exercise. + +![](buffgym-scrn4.png) +![](buffgym-scrn5.png) + +Once all exercises are done, you are presented with a pat-on-the-back screen to tell you how awesome you are. + +![](buffgym-scrn6.png) + +## Features + +* If you successfully complete all reps and sets for an exercise, it will automatically update your weights for next time +* Has a neat rest timer to make sure you are training optimally +* Doesn't require a mobile phone, most 'smart watches' are just a visual presentation of the mobile phone app, this runs purley on the watch. So why not leave your phone and its distractions out of the gym! +* Clear and simple user interface + +## Created by + +[Paul Cockrell](https://github.com/paulcockrell) April 2020. \ No newline at end of file diff --git a/apps/buffgym/buffgym-scrn1.png b/apps/buffgym/buffgym-scrn1.png new file mode 100755 index 0000000000000000000000000000000000000000..07b79386f1503317acee9ff894d8dcf4c0035bc4 GIT binary patch literal 4141 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 literal 0 HcmV?d00001 diff --git a/apps/buffgym/buffgym-scrn2.png b/apps/buffgym/buffgym-scrn2.png new file mode 100755 index 0000000000000000000000000000000000000000..ec70fb79110bb029f286b66194fea8be4fe50e28 GIT binary patch literal 2801 zcmeHJT~t%q6~6c81_G&qM!*3faZNQ;$Kps?APU64A}vE?AV8rImeMlH@MAS3CI33M zqYDUQDJ}(*ahQUVhJb>^0Lf)hfhARHF+@}#%M1uyNPv(Z5<+@yANtg{K6I_l!#U^S z?C(4KoW1wA&(%{YiJN?beE|U2lyvg=r`Wpmeh|E{Ii4|h9RPe)Nym?*bMh7^KED3l zz!vc;_?1rXtTOE$w@lwq zGKKDX&lXDA&&3fCZ7Sa+4ZI@|=0SMw5pGLAEXyFI`s&)}D#jzyc76FHFaLGp$ zBzp328kK@P1H>Uj!ctZA$O|7rTjYNM##{No;WRU|Lp>I|u*1ZR6BHdN$@?({8NTXy zlg~mjB*FtX%CCq38Si+8_vcmz^}<;yqL0PNaStoji_YG9IxR&ea1QmAiIGaV1VJmR zrBma^%)CUUa^Aj*LOl++A+)U#_kw>UPVITS_{hBk^>B!I&c{przYj7z_NIw~a0xue zu(!%p_h;W^R&T5ygKytgXpdYUH?rMn+78XiZ*%FLG99l;Ni1_j{4Cx3o9;eFehV(! zidHixm{xAD)T^mQ$!l@PR`lk|Om65SL>L>%psBr+MQQD1J+TcSE|KBG;{Kq9`F*FN zc%9%JsVQfwSDQWcoZg``hQAX-?i2RCZi*pKhx1gc!weZ$JVl1p*;Nj0(!%*%vz^%!Aa3~-}7^U>M(7v z(iM6lnx=DhTTq*F;9pcWxFk-DcPxDA96YJOWf#-!0cx&Lr*%~uXP05sUbRg?&!-#4 zhz)>pQvv%T7-+~4$#G-+!RP!VoJHYk;TzNXUWrbR&%%80gPiWMQKeHapJwH%+tB^KBMlz(>hx@?mh39_RmaohvYJt2rt7&? zIe@lyRe(uK_PcK9#<0-K1YPv20X$hMbku4#l?EdnnnP1MJF(0Xu`7M*Qn_sVoL8pz z%IvZnb9!s6O^v;@AH9}ZW@EBLL-g9}@<)I&uWebmtE@BV%c8j#54IRy4TTc%a7=%I z;jeU7I0gCOYoJijats8Y0r(h8+9&zxG*RMO6t%{OP&U(i3%M%-Br8QJ6p}v%h!UrQ zVA!<2fwr51+?1Vz8X@TL6Xij1GEEejpo4#khdH&(3(!r`ds3fDU&2zjb_PCxv9G6- zwg>ndQUy*xeL1)qxrr%N)5AP?b6{4W!Hg?S(HAaWX5Zg# zI+LK1p&E5PpbXRuIUwFwRWY34VO)>(ny2FHhZ~;33i?bA0_YI2j@`k($*))LDqj2>rsu%SaG+Tkeg$b4Fn) z^{(r0IvWf3A@aw&C>JgXG0g8nC#fDZhO6z=I13FX;uC5ATPf;8SgIFz1sc#R#g8lN z@SMj5lI^2i_Y=c|je8(yoljMlK2qKn&n$l~9>hDwUl&`=SRR`nHjY`s#ah^rD(}jI z%sUO4Kbks2R=m9f30}JIgp`h(cVbrUl8oh3ASjp}$gyz=geC4mBjYeuEM)a^ojVMp z4|9DM;1}RnS!8-v^*&_vS{+{qf*Ma)cHd<@?C7g6owEn|8(ii)0f)0NT+dpa;NJ$- zeoK=~A#cC)?|-r|pKv?-@Q!nbu0Kl@rS;|LFzvNwLL<&Ir^&C|?fIqd1#~b*r_Ss0 zEF_f7BrcW&AQ$gL>%qxj%1Et~gl{Do6x3f@kIgEx5+}6mc-^lVmV2$4#!`h){!HRv zorvIT0k%w~%XwkK!p)4OWXj&C0W%-^Ry^yqyH{A0J6E`{8gZ;gFs6)`bGI_%>bqyC zNMam_=jg>3M%y8*yVwH+R#J>RP`%PR!|bJ{>*X7|L)T2!k_5X1t9kB zL@e3M=Hv_#b0k literal 0 HcmV?d00001 diff --git a/apps/buffgym/buffgym-scrn3.png b/apps/buffgym/buffgym-scrn3.png new file mode 100755 index 0000000000000000000000000000000000000000..0888fc507c229f1eb1b757770531a56ffa63b63e GIT binary patch literal 3569 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 DipYXY literal 0 HcmV?d00001 diff --git a/apps/buffgym/buffgym-scrn4.png b/apps/buffgym/buffgym-scrn4.png new file mode 100755 index 0000000000000000000000000000000000000000..3078d25dce7b2b114c17804571e16c858aaf2d7f GIT binary patch literal 3299 zcmeH~X;4#H7RSTO6M|w4FcAR*aRC((5k#D@7(g}`pxJ^5Bx<)oY(bHL>^zsYU2#Ag zv;`S)5E3BTfRF@8zy)PT36Uibki||Q1n2+)N#@zse3+@44>M&=)lAKY_g=lKbN}bu zbL#)Qb+7n%xvyMqupEIvtn~EQ>kEHnpC6Pu{B{iZH3NarqI>Rj@;?_gk>ix1`$lK) zWkdP-W$r^BYp*O@5xMhNSKbbZ)m2$x%pI!Pz(6wNw)=3?IWw%z^T(4>Q7Ywg6&?YZ zXeK#}OxkV~tdn^mAbk*JegFaKIobzbMgZ1GOi(rg*q(H*9IXZ(SI0lGR0G52W#Kpg z)vQIN905?(vcV1lh{@JZ%1c9&p?l;a3sg)UKaX;pgH zx-?!h0$gpH##>=*RN{hw?yCKLLLI2mcwj)FSXy!oP8B>nw8%cGLM7?_`cl$t)>xb@ zr1dqSLU8^xg+(4Sm>O7HHcJz%#mhn;=`pPtn?L`Z;a2m~k&b|aV^hF|)3Ko~+=RTc z;Ro`m_k!-Sr#-4aO-|9MW3*SaXH+?3j9i0;Qgxk0>G?xC>d@9@4W-*RovsL#=gf`c zxa>^(QZlwyOs)yzGo#r|W*6sNuCRmQO%$_8A%UEmJT7;2{A?OqBVSxe7bGWF7(rWy z+E}&sd1Bl@0JKp(wx*ujwAaEPy8GZUitF>#zc5^Jv~*KN^fif_1%REr6qvgbO7?MeGbio^Q`lkR&Xm>MpOTA7Vg0 zFZ~4p&M{2#1oyBzHorGLv8LzoNfl$bx|m0L0JY_I(A5YWWihq0BmEGphC1L*xoanj84gDQ zx)`FU&ZW>X82!q7ahfxi99MIq&e*_3RF~O9dm`?kWj$F5;rY(Fe0{}> zGsBFO`ayJYZc-Euc(9aAfhT~c4Nx#un+n(qBglG>VV|b3QBTw z7)p3<>(h9b_gs>q(ST}wJN6fjvW}G?bU&xuikTwK0vCnQI7m zCs<}yT;gToP!q&F*e`bFK`Wp)D7@@j4QD&dM|dXaZC%b3D*$ER4Yi{|*o##z*D5gC z*AaksEWR8G!OoSoAKeC;Zh#g4_hc}-^Aj_@-);`q06u^z%K1MUz4ai9)Xjf#&V!qc zU03QtISMytYOvh^Gy_l}+Cv1;6y}evF}lR*pM>lSRn2bm`y>$@5DI5cKD^E|y)~OH zR8Oc>+*4PF4&odWn@>6Ghh}u{jc1)0=V-dEp-ujjW;h zP*twCd&m*oh)}txQ$dd}puy5x8VWDmF<29qDz(R!2a{U%=eTzm0}PFi!H>~_5tKd! zYo_z8kAxmyG(!}T!GcfeJw<<85U{(V^j;QW73fBxxeW-4E-=yMcHYA4u#DdvWAtv< zly(p3d-EHOtu~fYWna8m_?LJouMgtukD!zqAtxeJkxx&mf= z$Les|c25ZTeGm&tDyzo@)mT63pAy2w&@~f7NWYgOLO0`raym?;JbE_$w6uEl_|(g# zEx+x49#%h&{2-00tnS~b#dH%Lx!8i3Bic4)H3=0HKaqf03nFEE8==Lao%XVSd0Z-I zL>|8CKN7bFJ3rAdH}^wIigLZptL;zwklT(#nMco69u7lR9NPleZFbz?f?J|?23q-X zV|-bU7X04p3qr6}iDSv-@MazCX+C`WIreS5S(bllWUH$YFrXD;@fb~C8y=Revv(vz z+;*LH)kSpGN6aP^7Abwt7l!yMgh@uIBoNEZocHV$_ADj{q%B&}e4?Vp-6?I|A{4H;f1YvGMVi}Mg~3So(G&#HW_pibrn}>1h@G89CPi_>{uy7st0LT*=&_Ufis<^!u7w) zF1k{{$d;>#d3^f{&wp7?4;zFte}`W(&NS$R4Nb63d41$7nE2nJMaCM`Mil<^d4kP4 z3XCz+TQ7)sCj_M1S){3^s|JH+qdK4opzh~+9YkfLV4`f?f$@M31CSQs%-f5A8Fd9B zo<{(i3jK5eQ=k|1{gA5`_{?QdiF#eu|B09E2|~2v1k9 Ky`|2S^M3`WxUwt& literal 0 HcmV?d00001 diff --git a/apps/buffgym/buffgym-scrn5.png b/apps/buffgym/buffgym-scrn5.png new file mode 100755 index 0000000000000000000000000000000000000000..b34a5b124aba6acacdcd671c2401563958faa509 GIT binary patch literal 4500 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 HT+Y7%cOZEH literal 0 HcmV?d00001 From a49397ed3dac75b38e3fd3537fe080d2a661a5a4 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Tue, 21 Apr 2020 20:11:32 +0100 Subject: [PATCH 129/878] Disable emulator --- apps.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps.json b/apps.json index 4eeee4e32..139192339 100644 --- a/apps.json +++ b/apps.json @@ -1302,6 +1302,7 @@ "description": "BuffGym is the famous 5x5 workout program for the BangleJS", "tags": "tool,outdoors", "type": "app", + "allow_emulator": false, "storage": [ {"name":"buffgym"}, {"name":"buffgym.app.js", "url": "buffgym.app.js"}, From 5f19c8bd80688b8f78c139b7185b5e19b2812f5d Mon Sep 17 00:00:00 2001 From: jeffmer Date: Tue, 21 Apr 2020 20:22:26 +0100 Subject: [PATCH 130/878] Update apps.json --- apps.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps.json b/apps.json index 0b7001a5e..8df240cf6 100644 --- a/apps.json +++ b/apps.json @@ -297,6 +297,7 @@ "version":"0.01", "description": "Displays GPS Course and Speed, + Directions to waypoint and waypoint recording", "tags": "tool,outdoors,gps", + "readme": "README.md", "storage": [ {"name":"gpsnav.app.js","url":"app.js"}, {"name":"waypoints.json","url":"waypoints.json","evaluate":false}, From b5fd14b4fb39e313544758f35950d9068f738fe0 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Tue, 21 Apr 2020 20:45:02 +0100 Subject: [PATCH 131/878] Add training programs to apps file --- apps.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 139192339..4b51a4689 100644 --- a/apps.json +++ b/apps.json @@ -1309,7 +1309,9 @@ {"name":"buffgym-set.js","url":"buffgym-set.js"}, {"name":"buffgym-exercise.js","url":"buffgym-exercise.js"}, {"name":"buffgym-program.js","url":"buffgym-program.js"}, - {"name":"buffgym-programs.json","url":"buffgym-programs.json"}, + {"name":"buffgym-program-a.json","url":"buffgym-program-a.json"}, + {"name":"buffgym-program-b.json","url":"buffgym-program-b.json"}, + {"name":"buffgym-program-index.json","url":"buffgym-program-index.json"}, {"name":"buffgym.img","url":"buffgym-icon.js","evaluate":true} ] } From 7e305033814aa2946c68686d82e94f85e70cbf6f Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Tue, 21 Apr 2020 20:46:30 +0100 Subject: [PATCH 132/878] Add readme to apps.json --- apps.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps.json b/apps.json index 4b51a4689..d800050ee 100644 --- a/apps.json +++ b/apps.json @@ -1303,6 +1303,7 @@ "tags": "tool,outdoors", "type": "app", "allow_emulator": false, + "readme": "README.md", "storage": [ {"name":"buffgym"}, {"name":"buffgym.app.js", "url": "buffgym.app.js"}, From 14e209b020c0eca0e54fc591c378c8a52f1fab4b Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Tue, 21 Apr 2020 20:47:45 +0100 Subject: [PATCH 133/878] Add tags to buffgym app in apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index d800050ee..96f758c07 100644 --- a/apps.json +++ b/apps.json @@ -1300,7 +1300,7 @@ "icon": "buffgym.png", "version":"0.01", "description": "BuffGym is the famous 5x5 workout program for the BangleJS", - "tags": "tool,outdoors", + "tags": "tools,outdoors,gym,exercise", "type": "app", "allow_emulator": false, "readme": "README.md", From bb9747da0924adbef19929b29c833bdc707fd70d Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Tue, 21 Apr 2020 20:51:15 +0100 Subject: [PATCH 134/878] Add app comments --- apps/buffgym/buffgym.app.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/buffgym/buffgym.app.js b/apps/buffgym/buffgym.app.js index eeabd5c29..4dc6ffd5a 100755 --- a/apps/buffgym/buffgym.app.js +++ b/apps/buffgym/buffgym.app.js @@ -1,3 +1,14 @@ +/** + * BangleJS Stronglifts 5x5 training aid + * + * Original Author: Paul Cockrell https://github.com/paulcockrell + * Created: April 2020 + * + * Inspired by: + * - Stronglifts 5x5 training program https://stronglifts.com/5x5/ + * - Stronglifts smart watch app + */ + Bangle.setLCDMode("120x120"); const W = g.getWidth(); From 94bb31889cba0b31be983a6dcfda7d506c367fa0 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Tue, 21 Apr 2020 21:14:18 +0100 Subject: [PATCH 135/878] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 96f758c07..65f0090b3 100644 --- a/apps.json +++ b/apps.json @@ -1300,7 +1300,7 @@ "icon": "buffgym.png", "version":"0.01", "description": "BuffGym is the famous 5x5 workout program for the BangleJS", - "tags": "tools,outdoors,gym,exercise", + "tags": "tool,outdoors,gym,exercise", "type": "app", "allow_emulator": false, "readme": "README.md", From 26d8855ea20bba5d7833fe331d4696f15d602e98 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 21 Apr 2020 23:13:04 +0200 Subject: [PATCH 136/878] locale: Measure temperature in Kelvin Because that is what Gadgetbridge sends for the weather --- apps.json | 2 +- apps/locale/ChangeLog | 1 + apps/locale/locale.html | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 1cacc920e..95a845f54 100644 --- a/apps.json +++ b/apps.json @@ -65,7 +65,7 @@ { "id": "locale", "name": "Languages", "icon": "locale.png", - "version":"0.06", + "version":"0.07", "description": "Translations for different countries", "tags": "tool,system,locale,translate", "type": "locale", diff --git a/apps/locale/ChangeLog b/apps/locale/ChangeLog index 3d983150d..a3cc0c9a3 100644 --- a/apps/locale/ChangeLog +++ b/apps/locale/ChangeLog @@ -6,3 +6,4 @@ Add correct scaling for speed/distance/temperature 0.06: Remove translations if not required Ensure 'on' is always supplied for translations +0.07: Measure temperature in Kelvin diff --git a/apps/locale/locale.html b/apps/locale/locale.html index 21bf37f29..936d2e9f0 100644 --- a/apps/locale/locale.html +++ b/apps/locale/locale.html @@ -112,8 +112,8 @@ exports = { name : "en_GB", currencySym:"£", `${js(locale.currency_symbol)} + n.toFixed(2)`: `n.toFixed(2) + ${js(locale.currency_symbol)}`; var temperature; - if (locale.temperature=='°C') temperature="t"; - else if (locale.temperature=='°F') temperature="(t*9/5)+32"; + if (locale.temperature=='°C') temperature="(t-273.15)"; + else if (locale.temperature=='°F') temperature="((t-273.15)*9/5)+32"; else throw new Error("Unknown temperature unit "+locale.temperature); var localeModule = `var l = ${JSON.stringify({ From 319307cdd1831b27a94b6a9150cf24e24379ae22 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 21 Apr 2020 23:18:21 +0200 Subject: [PATCH 137/878] weather: Show Gadgetbridge weather reports Based on http://forum.espruino.com/comments/15194626/, where NebbishHacker did most of the actual work :-) --- apps.json | 17 ++++ apps/weather/app.js | 54 +++++++++++ apps/weather/icon.js | 1 + apps/weather/icon.png | Bin 0 -> 1173 bytes apps/weather/lib.js | 176 ++++++++++++++++++++++++++++++++++++ apps/weather/readme.md | 16 ++++ apps/weather/screenshot.png | Bin 0 -> 4039 bytes apps/weather/widget.js | 40 ++++++++ 8 files changed, 304 insertions(+) create mode 100644 apps/weather/app.js create mode 100644 apps/weather/icon.js create mode 100644 apps/weather/icon.png create mode 100644 apps/weather/lib.js create mode 100644 apps/weather/readme.md create mode 100644 apps/weather/screenshot.png create mode 100644 apps/weather/widget.js diff --git a/apps.json b/apps.json index 95a845f54..3921e8ae1 100644 --- a/apps.json +++ b/apps.json @@ -348,6 +348,23 @@ {"name":"files.img","url":"files-icon.js","evaluate":true} ] }, + { "id": "weather", + "name": "Weather", + "icon": "icon.png", + "version":"0.01", + "description": "Show Gadgetbridge weather report", + "readme": "readme.md", + "tags": "widget,outdoors", + "storage": [ + {"name":"weather.app.js","url":"app.js"}, + {"name":"weather.wid.js","url":"widget.js"}, + {"name":"weather","url":"lib.js"}, + {"name":"weather.img","url":"icon.js","evaluate":true} + ], + "data": [ + {"name": "weather.json"} + ] + }, { "id": "widbat", "name": "Battery Level Widget", "icon": "widget.png", diff --git a/apps/weather/app.js b/apps/weather/app.js new file mode 100644 index 000000000..fdf28f0e0 --- /dev/null +++ b/apps/weather/app.js @@ -0,0 +1,54 @@ +(() => { + function draw(w) { + g.reset(); + g.setColor(0).fillRect(0, 24, 239, 239); + + require('weather').drawIcon(w.txt, 65, 90, 55); + const locale = require("locale"); + + g.setColor(-1); + + const temp = locale.temp(w.temp).match(/^(\D*\d*)(.*)$/); + let width = g.setFont("Vector", 40).stringWidth(temp[1]); + width += g.setFont("Vector", 20).stringWidth(temp[2]); + g.setFont("Vector", 40).setFontAlign(-1, -1, 0); + g.drawString(temp[1], 180-width/2, 70); + g.setFont("Vector", 20).setFontAlign(1, -1, 0); + g.drawString(temp[2], 180+width/2, 70); + + g.setFont("6x8", 1); + g.setFontAlign(-1, 0, 0); + g.drawString("Humidity", 135, 130); + g.drawString("Wind", 135, 142); + g.setFontAlign(1, 0, 0); + g.drawString(w.hum+"%", 225, 130); + g.drawString(locale.speed(w.wind), 225, 142); + + g.setFont("6x8", 2).setFontAlign(0, 0, 0); + g.drawString(w.loc, 120, 170); + + g.setFont("6x8", 1).setFontAlign(0, 0, 0); + g.drawString(w.txt.charAt(0).toUpperCase()+w.txt.slice(1), 120, 190); + + g.flip(); + } + + const _GB = global.GB; + global.GB = (event) => { + if (event.t==="weather") draw(event); + if (_GB) setTimeout(_GB, 0, event); + }; + + Bangle.loadWidgets(); + Bangle.drawWidgets(); + + const weather = require('weather').load(); + if (weather) { + draw(weather); + } else { + E.showMessage('Weather unknown\n\nIs Gadgetbridge\nconnected?'); + } + + // Show launcher when middle button pressed + setWatch(Bangle.showLauncher, BTN2, {repeat: false, edge: 'falling'}) +})() diff --git a/apps/weather/icon.js b/apps/weather/icon.js new file mode 100644 index 000000000..18ca2b0c9 --- /dev/null +++ b/apps/weather/icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwhC/AE8N6AXV7vdFyoXBGCQUBAAoXp73u93tC6YWBAAIXSFwQwDRiAWDGASSBmYABIx5IDgYXCmC7KCoYRBnvUCwQwKC4gSEAAgwKC5gwKCwPjC6inBC6owBC6wVKPBXd6YXMDBAuNJJQXWfwZITC/6QIBw073ezR6m73anOJAwuHeBAYFIw4WJAAsL3YQOAAxeBCiWIC4e72AJChGACpMIxAXBIwIwEBIIXKBgouDEIYuLC4ghEC6ELLoYXPU4YXFLxQNBBgcLEQqqQFwYA/AH4AYA==")) diff --git a/apps/weather/icon.png b/apps/weather/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bbfc0ace0b8d25c4afefcb336ea04df799a70f22 GIT binary patch literal 1173 zcmV;G1Zw+fgKelF z+6!B~5F)8y)e1%MqEWnPiWg$RgkaGND+=ED(@M!jy(#RCC2ci@HZ&m;H8wSEeq1-3 zna_*eO*h%I$(hL}OJN@v*!|9#@4WBKnQzV+C{Un)Z={DV>E%eib@(DFUXn-NOejAm zNe^8p4lfCJt4`j{fhJF^Xh3?ARSnST?;@FEt!47{!1jEGWkFpPY~BdvcO+sr|AoPp7;j(Z^c9nYrv8 zkRG}g{?t`1FFr+i3Dj4?(4UDMy&OqZr_)1HX<73JfL%aC@{G&CN!PWHJ+npq?bSfm z3XxGNw?6LPs7g_(j(pdPtX6NkmEpEmb0c6>eVOf?QhKnNuV{Lt@F=40(L-~ zBr4U6#P%`av@$0Zg!qTMN57+X49^FVjkbLQP)KEm&RPQbv6&-%R5y%N$)W|^G z3HAX4eumxfNt%QZOugspBgMdEG}xzWFfy>SLB*_~-Ht~Sp@@Yn(5USLDV>K=tk6T&Gr@s zpI_!oxJY!Hg>_~@60*CA@DI5jXU)oJfI#||^z>SYhgIBx&7a<=4-nV|vaT9J`>ZY?00000NkvXXu0mjfi9tF% literal 0 HcmV?d00001 diff --git a/apps/weather/lib.js b/apps/weather/lib.js new file mode 100644 index 000000000..f87984fe5 --- /dev/null +++ b/apps/weather/lib.js @@ -0,0 +1,176 @@ +exports = { + save: weather => { + let json = require('Storage').readJSON('weather.json')||{} + json.weather = Object.assign({}, weather) // don't mutate GB events + delete json.weather.t // don't save the event type (if present) + require('Storage').write('weather.json', json) + }, + load: () => { + let json = require('Storage').readJSON('weather.json')||{} + return json.weather + }, + drawIcon: (cond, x, y, r) => { + function drawSun(x, y, r) { + g.setColor("#FF7700"); + g.fillCircle(x, y, r); + } + + function drawCloud(x, y, r, c) { + const u = r/12; + if (c==null) c = "#EEEEEE"; + g.setColor(c); + g.fillCircle(x-8*u, y+3*u, 4*u); + g.fillCircle(x-4*u, y-2*u, 5*u); + g.fillCircle(x+4*u, y+0*u, 4*u); + g.fillCircle(x+9*u, y+4*u, 3*u); + g.fillPoly([ + x-8*u, y+7*u, + x-8*u, y+3*u, + x-4*u, y-2*u, + x+4*u, y+0*u, + x+9*u, y+4*u, + x+9*u, y+7*u, + ]); + } + + function drawBrokenClouds(x, y, r) { + drawCloud(x+1/8*r, y-1/8*r, 7/8*r, "#777777"); + drawCloud(x-1/8*r, y+1/8*r, 7/8*r); + } + + function drawFewClouds(x, y, r) { + drawSun(x+3/8*r, y-1/8*r, 5/8*r); + drawCloud(x-1/8*r, y+1/8*r, 7/8*r); + } + + function drawRainLines(x, y, r) { + g.setColor("#FFFFFF"); + const y1 = y+1/2*r; + const y2 = y+1*r; + g.fillPoly([ + x-6/12*r+1, y1, + x-8/12*r+1, y2, + x-7/12*r, y2, + x-5/12*r, y1, + ]); + g.fillPoly([ + x-2/12*r+1, y1, + x-4/12*r+1, y2, + x-3/12*r, y2, + x-1/12*r, y1, + ]); + g.fillPoly([ + x+2/12*r+1, y1, + x+0/12*r+1, y2, + x+1/12*r, y2, + x+3/12*r, y1, + ]); + } + + function drawShowerRain(x, y, r) { + drawFewClouds(x, y-1/3*r, r); + drawRainLines(x, y, r); + } + + function drawRain(x, y, r) { + drawBrokenClouds(x, y-1/3*r, r); + drawRainLines(x, y, r); + } + + function drawThunderstorm(x, y, r) { + function drawLightning(x, y, r) { + g.setColor("#FF7700"); + g.fillPoly([ + x-2/6*r, y-r, + x-4/6*r, y+1/6*r, + x-1/6*r, y+1/6*r, + x-3/6*r, y+1*r, + x+3/6*r, y-1/6*r, + x+0/6*r, y-1/6*r, + x+3/6*r, y-r, + ]); + } + + drawBrokenClouds(x, y-1/3*r, r); + drawLightning(x-1/12*r, y+1/2*r, 1/2*r); + } + + function drawSnow(x, y, r) { + function rotatePoints(points, pivotX, pivotY, angle) { + for(let i = 0; i {}; + condition = condition.toLowerCase(); + if (condition.includes("thunderstorm")) return drawThunderstorm; + if (condition.includes("freezing")||condition.includes("snow")|| + condition.includes("sleet")) { + return drawSnow; + } + if (condition.includes("drizzle")|| + condition.includes("shower")) { + return drawRain; + } + if (condition.includes("rain")) return drawShowerRain; + if (condition.includes("clear")) return drawSun; + if (condition.includes("few clouds")) return drawFewClouds; + if (condition.includes("scattered clouds")) return drawCloud; + if (condition.includes("clouds")) return drawBrokenClouds; + return drawMist; + } + + chooseIcon(cond)(x, y, r) + }, +} diff --git a/apps/weather/readme.md b/apps/weather/readme.md new file mode 100644 index 000000000..a326b67dd --- /dev/null +++ b/apps/weather/readme.md @@ -0,0 +1,16 @@ +# Weather + +Shows Gadgetbridge weather reports. + +This adds a widget with a weather pictogram and the temperature. +You can view the full report through the app: +![Screenshot](screenshot.png) + +## Setup + +See [this guide](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Weather) +to setup Gadgetbridge weather reporting. + +## Controls + +BTN2: opens the launcher diff --git a/apps/weather/screenshot.png b/apps/weather/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..ce79b3b646bfebdad6c29f57779c018ce0ce457e GIT binary patch literal 4039 zcmeH~`#03v-@x~0#*hh>gNlYDI&Mcul3`HEZ5+4C-OyDUF>W=C_)JB*xF%F*8l7B@ zJGsUTpX4M`N{ma)OcA+_$^90Ov)1zmJik2a`^$H)wfB4NAKrVfz1Lo^{eIncw6~JP z%3}clk~Y>B&YMyAZ{H%iIhvjtOWh12p+{{_ZrN;6Th7G;ur1og;>bxVX^O#qk292t z!~GijR=fJm`CRKSL`urujE86LrfJCazUx(Vb5c#|;>EvefuU7}+k1Uxb{LGd8}YU& znMN(~d}5Ywpw#(}bS2PxnnT%*Y0v;j8VY;Z1;9A9Z9Pr^&WB_uMF1GvE0#P1-~?Ko z?*@S@f0}q%K_FMu5h+K3$-@z~i6~$vnFXK4fZpI43JwD@<;|fMEGQcq{({E>T>}`E zC<}aBT3?0B0N+ahvquXciT7_!r~{-6{0BGWp8^|eZ#&Ld#;nd821}qFk-I1X#4-0I zit5rdPOKGa@a6bBD4}{_w>e9bFU5bzM?LR({?D{0lljb>U=F`89$(U+oL#Yp*Z$_PQJF0Pl=vrv-bNL2fBD z(nFW{=430G!_xfwbvoWlDRt+Za!{a1#`bfp=i?+!T<5;Hr$|JQ3ZwU0&i;WRecfX` z2~6SyVkp5hy(T@hy0%<#_`(Rhr%sU)8UrFO#C`3%z2arGr+`6LEp3x#-u$rs}=VTL4LXT05;JPy*3vTVo$m zf~aCF^EK{Y`<_o@1H`CmEOWd3MsIpCFoQ~6m(fc$R65nZ-1nOarW!<{ zSc=NITbW|*{)&*$f49vV#J_PrG@kqxGRB z%>m4Rk65(4{WwWn>$E7}HN;R`9jyO$ep{`vxhUViYTfo2SabF8L$tydxZ@C?^zBT$ zr>L;CWfYgs2rm-lUjz9yGn^w=?>zn&MczMwStxO(nn*$WTDR@1V>!SLen- zNB6`U1K40Xnwi+-C!6P4)_!o0f@!yV4(Z`?nqY6bR{)|TnE@Bxf9>!r90}Og)kix)U-PC=SGoY2=|<)}>k)W59u2m3>NxnCqt0&w#TtiIb# zkf>I_a#%X7a@Dwuaa5+@bDlA7X}azm6>h?2he!G3F1|Z}mSA0LeZjx>)wtR|TC;Gp zo1ePkqJE5rMpKlKe)o#{Fd0~T@%d>;l%yRuG;{%;lq8K!Wd)yV^eDSB$u+82yWFRT zdkRslY#U1TuzDb4_B@8laf&%U4}{oLYWT)NAFBNPWV{0*v>SZ7 zMjK}6=ZSr-0baD6NYU@|x(vcIw^j?4M6ELtm8Boj@RKRCe<72t*n!Ftaqv*?9>!p6|2>D(XsVq~xYN=1b6 z7oH_EqP_O}&&tEDuV}XyRgs<*gLpPf+nJR+G!L6#DIJd-Iw0TkqEF&#M9K^)u4t2x zdoJlOgI@u+hpE4S^)VhfXh)i}-R|76CTFX8>M&z3>5PS>&|tKyCe=lW=>RWwnn@$l ztm42DhOt7f+9Xt#wW1-kMD?P4=k`k=V9jFa@95cV45_Z{%aKISqF<6e7AAgB3+Jih zcEOid^YhV6s*(h&`X=*0@b1e(@4d1TG;7SNRje|&LY=&E;%%?~hUVZpG&&#%A_Je(x z8P6{XD8ZXxd1_;!A&&2@+aa=a^I50`g{D06oh8nX5Q~lRSeea;;FzuBJLJ+=WRvlQ z=ZxCQjk-_!i=~T9v!z(!yy(ebu>iZoZqo~TunE$Wa?}S$^#Te} zCE!VLl)z~xm3H#%dnpWXbKFh6nx;&i(*%g*H@K#zD6@tLff98|R=sUQLz_+-}A9Rl_GB^eq0?!*&Tzz!usnf5S zSpaN2!0-uAWqv%hqPwC3#u|{%Cl0k69f!b({>#sooK~!TquB>Z&&#zl6JrG(hj>bN z|J*^m2#+;PX?B5brml?oJgbu+_Yq}Cb(KC%5j<`f)r{EboTUFgS?&` zsX%sgM6r=e$Ms{*HmIeB{r_kbf2vzAkdk1j1o%W2UC*2jTLZ+=hk{UqmqVhZ%n&+`FJ>zI% z0a6I%&RS|u91d=j^W`U;XiiZH-$of*l3>wn>lO*`xDm9!JZjqR)IwD6h5^rX#meuJ zl;g^aE6$Hy@30rD)2~d)2G@&b3JSFu4Z)8V>Evy~yy-F0#(s9tz-af1`!cPvSjX8F<7$!Ki++_W zJ}Xne|1xLI9aqX(pCX%*I)l5`*@C}KNed8IPuBqJwAS}10QUr90zt{t_s&Gm`=y*O z*-a1d@s&>&p15jmrg|%shO1z! zyl1BKCjvn=SH)(?YFfNlyh1KMe655^wi@tqXk~JHG$Vs{7p=R^u69vDw2fFgHjER8 zK^&fXka}>4U+XPHbzu<-tQD;nC8CaDfiOAB&XVr82_nCFzi^pdo1nTieD(m=q!0kJ zLbJkWNHPkTs4Cre;=5zOlKW40941Z%@RgS{@1Z(2(bqBFF|MwgjqCtENuxGO`V+T9 zVh3dp(asP@)1o@p?L6w|?W$ewat;?Kq%!+o^apEeM>7A&n8UFfWci(;l{;(oMHFqy zjyIob@QC_wkAV?ZaW1wypo=~d^)H+hdneD)^Mo20Z)4xQv~S#}GS$Aw>R+nwb>1-( zG*DaeZGl)%uCr{lyrkyi`kYykr*S8hR2(GjKjz+Psrjh?LNeL$Q%tVeKFkw_*`3z>XvqEZmMX3^+BH7h#RtgQSTw-)ueeqEEL;U;Pu=0@sR4qr@0O#gW zQ~jm-&>3Pw(I7kbSOY|i{07oP2A?rqIv#Gn1=Uto*jm+hzQ1G>@GiPv?_kaLPHKX~ zKDSDY+CR#WHsjaI(wIsR*!N+DS8=)uzhLJ`u5JQFgXf7yb1+%-ePa7-G$4Om=?{M~ zq*x_vO1)sv!egCysB*Tejrrl{rf#i=T8q#( z9|_W`7PhgeW*d8?kN9qWWRw~4!NyIE`)~UH@#@x;Hc|>Q0>`zpH_aT_9JjY9IqG}; Fe*nCRR)+up literal 0 HcmV?d00001 diff --git a/apps/weather/widget.js b/apps/weather/widget.js new file mode 100644 index 000000000..7488b7657 --- /dev/null +++ b/apps/weather/widget.js @@ -0,0 +1,40 @@ +(() => { + function draw() { + const w = require('weather').load() + if (!w) return; + g.reset(); + g.setColor(0).fillRect(this.x, this.y, this.x+this.width, this.y+24) + if (w.txt) { + require('weather').drawIcon(w.txt, this.x+10, this.y+8, 8); + } + if (w.temp) { + let t = require('locale').temp(w.temp); // applies conversion + t = t.substr(0, t.length-2); // but we have no room for units + g.setFontAlign(0, 1); // center horizontally at bottom of widget + g.setFont('6x8', 1); + g.setColor(-1) + g.drawString(t, this.x+10, this.y+24) + } + } + + function update(weather) { + require('weather').save(weather); + if (!WIDGETS["weather"].width) { + WIDGETS["weather"].width = 20 + Bangle.drawWidgets() + } else if (Bangle.isLCDOn()) { + WIDGETS["weather"].draw() + } + } + + const _GB = global.GB; + global.GB = (event) => { + if (event.t==="weather") update(event); + if (_GB) setTimeout(_GB, 0, event); + }; + + WIDGETS["weather"] = {area: "tl", width: 20, draw: draw}; + if (!require('weather').load()) { + WIDGETS["weather"].width = 0 + } +})(); From 06fc54f83171cf175af359e2113cc239e24cad4c Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 22 Apr 2020 08:56:50 +0100 Subject: [PATCH 138/878] oops - fix sanity check errors --- apps.json | 3 +-- apps/buffgym/buffgym-icon.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 70fb6cac7..84b8fb643 100644 --- a/apps.json +++ b/apps.json @@ -1332,7 +1332,6 @@ "allow_emulator": false, "readme": "README.md", "storage": [ - {"name":"buffgym"}, {"name":"buffgym.app.js", "url": "buffgym.app.js"}, {"name":"buffgym-set.js","url":"buffgym-set.js"}, {"name":"buffgym-exercise.js","url":"buffgym-exercise.js"}, @@ -1438,7 +1437,7 @@ { "id": "osmpoi", "name": "POI Compass", "icon": "app.png", - "version":"0.01", + "version":"0.02", "description": "Uploads all the points of interest in an area onto your watch, same as Beer Compass with more p.o.i.", "tags": "tool,outdoors,gps", "custom": "osmpoi.html", diff --git a/apps/buffgym/buffgym-icon.js b/apps/buffgym/buffgym-icon.js index 31764acbb..523ed35b6 100644 --- a/apps/buffgym/buffgym-icon.js +++ b/apps/buffgym/buffgym-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwxH+ACPI5AUSADAtB5vNGFQtBAIfNF95hoF4wwoF5AwmF5BhmXYbAEF/6QbF1QwIF04qB54ADAwIwoF4oRKBoIvsB4gvZ58kkgCDFxoxaF5wuHGDQcMF5IwXDZwLDGDmlDIWlkgJDSwIABCRAwPDQohCFgIABDQIOCFwYABr4RCCQIvQDYguEAAwtFF5owJDZAvHFw4vFOYQvKFAowMBxIvFMQwvPAB4wFUQ4vJGDYvUGC4vNdgyuEGDIsNFwYwGNAgAPExAvMGIdfTIovfTpYvrfRCOkZ44ugF44NGF05gUFyQvKGIoueGKIufGJ4uhG5oupGItfr4vvAAgvlGAQvt/wrEF9oEGF841IF9QGHX0oGIAD8kAAYJOFzwEBBQoMFACA=")); \ No newline at end of file +require("heatshrink").decompress(atob("mEwxH+ACPI5AUSADAtB5vNGFQtBAIfNF95hoF4wwoF5AwmF5BhmXYbAEF/6QbF1QwIF04qB54ADAwIwoF4oRKBoIvsB4gvZ58kkgCDFxoxaF5wuHGDQcMF5IwXDZwLDGDmlDIWlkgJDSwIABCRAwPDQohCFgIABDQIOCFwYABr4RCCQIvQDYguEAAwtFF5owJDZAvHFw4vFOYQvKFAowMBxIvFMQwvPAB4wFUQ4vJGDYvUGC4vNdgyuEGDIsNFwYwGNAgAPExAvMGIdfTIovfTpYvrfRCOkZ44ugF44NGF05gUFyQvKGIoueGKIufGJ4uhG5oupGItfr4vvAAgvlGAQvt/wrEF9oEGF841IF9QGHX0oGIAD8kAAYJOFzwEBBQoMFACA=")) From 6d07882eae4bb6a8b4d17c7bdac38c9ec6cbe0af Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Wed, 22 Apr 2020 10:59:00 +0200 Subject: [PATCH 139/878] Revert "locale: Measure temperature in Kelvin" This reverts commit 26d8855e --- apps.json | 2 +- apps/locale/ChangeLog | 1 - apps/locale/locale.html | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps.json b/apps.json index 3921e8ae1..3a76c645b 100644 --- a/apps.json +++ b/apps.json @@ -65,7 +65,7 @@ { "id": "locale", "name": "Languages", "icon": "locale.png", - "version":"0.07", + "version":"0.06", "description": "Translations for different countries", "tags": "tool,system,locale,translate", "type": "locale", diff --git a/apps/locale/ChangeLog b/apps/locale/ChangeLog index a3cc0c9a3..3d983150d 100644 --- a/apps/locale/ChangeLog +++ b/apps/locale/ChangeLog @@ -6,4 +6,3 @@ Add correct scaling for speed/distance/temperature 0.06: Remove translations if not required Ensure 'on' is always supplied for translations -0.07: Measure temperature in Kelvin diff --git a/apps/locale/locale.html b/apps/locale/locale.html index 936d2e9f0..21bf37f29 100644 --- a/apps/locale/locale.html +++ b/apps/locale/locale.html @@ -112,8 +112,8 @@ exports = { name : "en_GB", currencySym:"£", `${js(locale.currency_symbol)} + n.toFixed(2)`: `n.toFixed(2) + ${js(locale.currency_symbol)}`; var temperature; - if (locale.temperature=='°C') temperature="(t-273.15)"; - else if (locale.temperature=='°F') temperature="((t-273.15)*9/5)+32"; + if (locale.temperature=='°C') temperature="t"; + else if (locale.temperature=='°F') temperature="(t*9/5)+32"; else throw new Error("Unknown temperature unit "+locale.temperature); var localeModule = `var l = ${JSON.stringify({ From c3940972b58039afc7a60df46a49b512f3ab3b54 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Wed, 22 Apr 2020 11:00:16 +0200 Subject: [PATCH 140/878] weather: Convert Gadgetbridge temperature from Kelvin to Celsius --- apps/weather/app.js | 2 +- apps/weather/widget.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/weather/app.js b/apps/weather/app.js index fdf28f0e0..8493144f7 100644 --- a/apps/weather/app.js +++ b/apps/weather/app.js @@ -8,7 +8,7 @@ g.setColor(-1); - const temp = locale.temp(w.temp).match(/^(\D*\d*)(.*)$/); + const temp = locale.temp(w.temp-273.15).match(/^(\D*\d*)(.*)$/); let width = g.setFont("Vector", 40).stringWidth(temp[1]); width += g.setFont("Vector", 20).stringWidth(temp[2]); g.setFont("Vector", 40).setFontAlign(-1, -1, 0); diff --git a/apps/weather/widget.js b/apps/weather/widget.js index 7488b7657..e02591543 100644 --- a/apps/weather/widget.js +++ b/apps/weather/widget.js @@ -8,7 +8,7 @@ require('weather').drawIcon(w.txt, this.x+10, this.y+8, 8); } if (w.temp) { - let t = require('locale').temp(w.temp); // applies conversion + let t = require('locale').temp(w.temp-273.15); // applies conversion t = t.substr(0, t.length-2); // but we have no room for units g.setFontAlign(0, 1); // center horizontally at bottom of widget g.setFont('6x8', 1); From bf5bf91967eb37d703533ce775f57aa8b31696f8 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 22 Apr 2020 13:17:31 +0100 Subject: [PATCH 141/878] mclock: Improve performance, attempt to remove occasional glitch when LCD on (fix #279) --- apps.json | 2 +- apps/mclock/ChangeLog | 1 + apps/mclock/clock-morphing.js | 107 ++++++++++++++++++++-------------- 3 files changed, 66 insertions(+), 44 deletions(-) diff --git a/apps.json b/apps.json index 837b94669..65b681390 100644 --- a/apps.json +++ b/apps.json @@ -108,7 +108,7 @@ { "id": "mclock", "name": "Morphing Clock", "icon": "clock-morphing.png", - "version":"0.03", + "version":"0.04", "description": "7 segment clock that morphs between minutes and hours", "tags": "clock", "type":"clock", diff --git a/apps/mclock/ChangeLog b/apps/mclock/ChangeLog index e6a689e9e..4bc1ea352 100644 --- a/apps/mclock/ChangeLog +++ b/apps/mclock/ChangeLog @@ -1,2 +1,3 @@ 0.02: Modified for use with new bootloader and firmware 0.03: Added Locale based date +0.04: Improve performance, attempt to remove occasional glitch when LCD on (fix #279) diff --git a/apps/mclock/clock-morphing.js b/apps/mclock/clock-morphing.js index ce30ad033..e9365db52 100644 --- a/apps/mclock/clock-morphing.js +++ b/apps/mclock/clock-morphing.js @@ -1,14 +1,15 @@ var locale = require("locale"); +var CHARW = 34; // how tall are digits? +var CHARP = 2; // how chunky are digits? +var Y = 50; // start height // Offscreen buffer -var buf = Graphics.createArrayBuffer(240,86,1,{msb:true}); -function flip() { - g.setColor(1,1,1); - g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},0,50); -} +var buf = Graphics.createArrayBuffer(CHARW+CHARP*2,CHARW*2 + CHARP*2,1,{msb:true}); +var bufimg = {width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer}; // The last time that we displayed var lastTime = " "; // If animating, this is the interval's id var animInterval; +var timeInterval; /* Get array of lines from digit d to d+1. n is the amount (0..1) @@ -49,7 +50,7 @@ const DIGITS = { [0,1,1,1], [1,1,1,2], [1-n,2,1,2]], -"5": (n,maxFive)=>maxFive ? [ // 5 -> 0 +"5to0": n=>[ // 5 -> 0 [0,0,0,1], [0,0,1,0], [n,1,1,1], @@ -57,7 +58,8 @@ const DIGITS = { [0,2,1,2], [0,2,0,2], [1,1-n,1,1], -[0,1,0,1+n]] : [ // 5 -> 6 +[0,1,0,1+n]], +"5to6": n=>[ // 5 -> 6 [0,0,0,1], [0,0,1,0], [0,1,1,1], @@ -109,59 +111,66 @@ const DIGITS = { /* Draw a transition between lastText and thisText. 'n' is the amount - 0..1 */ -function draw(lastText,thisText,n) { - buf.clear(); - var x = 1; // x offset - const p = 2; // padding around digits - var y = p; // y offset - const s = 34; // character size +function drawDigits(lastText,thisText,n) { + const p = CHARP; // padding around digits + const s = CHARW; // character size + var x = 0; // x offset + g.reset(); for (var i=0;i{ + if (c[0]!=c[2]) // horiz + buf.fillRect(p+c[0]*s,c[1]*s,p+c[2]*s,2*p+c[3]*s); + else if (c[1]!=c[3]) // vert + buf.fillRect(c[0]*s,p+c[1]*s,2*p+c[2]*s,p+c[3]*s); + }); + g.drawImage(bufimg,x,Y); } - var l = DIGITS[ch](chn,lastCh==5 && thisCh==0); - l.forEach(c=>{ - if (c[0]!=c[2]) // horiz - buf.fillRect(x+c[0]*s,y+c[1]*s-p,x+c[2]*s,y+c[3]*s+p); - else if (c[1]!=c[3]) // vert - buf.fillRect(x+c[0]*s-p,y+c[1]*s,x+c[2]*s+p,y+c[3]*s); - }); if (thisCh==":") x-=4; x+=s+p+7; } - y += 2*s; +} +function drawSeconds() { + var x = (CHARW + CHARP + 6)*5; + var y = Y + 2*CHARW + CHARP; var d = new Date(); - buf.setFont("6x8"); - buf.setFontAlign(-1,-1); - buf.drawString(("0"+d.getSeconds()).substr(-2), x, y-8); + g.reset(); + g.setFont("6x8"); + g.setFontAlign(-1,-1); + g.drawString(("0"+d.getSeconds()).substr(-2), x, y-8, true); // date - buf.setFontAlign(0,-1); + g.setFontAlign(0,-1); var date = locale.date(d,false); - buf.drawString(date, buf.getWidth()/2, y+8); - flip(); + g.drawString(date, g.getWidth()/2, y+8, true); } /* Show the current time, and animate if needed */ function showTime() { - if (!Bangle.isLCDOn()) return; if (animInterval) return; // in animation - quit var d = new Date(); var t = (" "+d.getHours()).substr(-2)+":"+ ("0"+d.getMinutes()).substr(-2); var l = lastTime; // same - don't animate - if (t==l) { - draw(t,l,0); + if (t==l || l==" ") { + drawDigits(l,t,0); + drawSeconds(); + lastTime = t; return; } var n = 0; @@ -170,23 +179,35 @@ function showTime() { if (n>=1) { n=1; clearInterval(animInterval); - animInterval=0; + animInterval = undefined; } - draw(l,t,n); + drawDigits(l,t,n); }, 20); lastTime = t; } Bangle.on('lcdPower',function(on) { - if (on) + if (animInterval) { + clearInterval(animInterval); + animInterval = undefined; + } + if (timeInterval) { + clearInterval(timeInterval); + timeInterval = undefined; + } + if (on) { showTime(); + timeInterval = setInterval(showTime, 1000); + } else { + lastTime = " "; + } }); g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); // Update time once a second -setInterval(showTime, 1000); +timeInterval = setInterval(showTime, 1000); showTime(); // Show launcher when middle button pressed From 9e8dea08e4888ea602e6440402a3a3d5d9a873cb Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Thu, 23 Apr 2020 06:54:08 +0100 Subject: [PATCH 142/878] Rename program to workout --- apps/buffgym/buffgym-exercise.js | 40 ++++----- apps/buffgym/buffgym-program-index.json | 10 --- apps/buffgym/buffgym-set.js | 6 +- ...-program-a.json => buffgym-workout-a.json} | 2 +- ...-program-b.json => buffgym-workout-b.json} | 2 +- apps/buffgym/buffgym-workout-index.json | 10 +++ ...{buffgym-program.js => buffgym-workout.js} | 6 +- apps/buffgym/buffgym.app.js | 87 ++++++++++--------- 8 files changed, 84 insertions(+), 79 deletions(-) delete mode 100644 apps/buffgym/buffgym-program-index.json rename apps/buffgym/{buffgym-program-a.json => buffgym-workout-a.json} (96%) rename apps/buffgym/{buffgym-program-b.json => buffgym-workout-b.json} (96%) create mode 100644 apps/buffgym/buffgym-workout-index.json rename apps/buffgym/{buffgym-program.js => buffgym-workout.js} (95%) diff --git a/apps/buffgym/buffgym-exercise.js b/apps/buffgym/buffgym-exercise.js index 68e49be84..078e206de 100644 --- a/apps/buffgym/buffgym-exercise.js +++ b/apps/buffgym/buffgym-exercise.js @@ -1,16 +1,16 @@ exports = class Exercise { constructor(params) { + this.completed = false; + this.sets = []; this.title = params.title; this.weight = params.weight; this.unit = params.unit; this.restPeriod = params.restPeriod; - this.completed = false; - this.sets = []; + this._originalRestPeriod = params.restPeriod; + this._weightIncrement = params.weightIncrement; this._restTimeout = null; this._restInterval = null; this._state = null; - this._originalRestPeriod = params.restPeriod; - this._weightIncrement = params.weightIncrement || 2.5; } get humanTitle() { @@ -63,13 +63,13 @@ exports = class Exercise { return (targetRepsTotalSum - completedRepsTotalSum) === 0; } - startRestTimer(program) { + startRestTimer(workout) { this._restTimeout = setTimeout(() => { - this.next(program); + this.next(workout); }, 1000 * this.restPeriod); this._restInterval = setInterval(() => { - program.emit("redraw"); + workout.emit("redraw"); }, 1000 ); } @@ -85,28 +85,28 @@ exports = class Exercise { return this._restTimeout != null; } - setupStartedButtons(program) { + setupStartedButtons(workout) { clearWatch(); setWatch(() => { this.currentSet().incReps(); - program.emit("redraw"); + workout.emit("redraw"); }, BTN1, {repeat: true}); - setWatch(program.next.bind(program), BTN2, {repeat: false}); + setWatch(workout.next.bind(workout), BTN2, {repeat: false}); setWatch(() => { this.currentSet().decReps(); - program.emit("redraw"); + workout.emit("redraw"); }, BTN3, {repeat: true}); } - setupRestingButtons(program) { + setupRestingButtons(workout) { clearWatch(); - setWatch(program.next.bind(program), BTN2, {repeat: false}); + setWatch(workout.next.bind(workout), BTN2, {repeat: false}); } - next(program) { + next(workout) { const STARTED = 1; const RESTING = 2; const COMPLETED = 3; @@ -114,12 +114,12 @@ exports = class Exercise { switch(this._state) { case null: this._state = STARTED; - this.setupStartedButtons(program); + this.setupStartedButtons(workout); break; case STARTED: this._state = RESTING; - this.startRestTimer(program); - this.setupRestingButtons(program); + this.startRestTimer(workout); + this.setupRestingButtons(workout); break; case RESTING: this.resetRestTimer(); @@ -132,13 +132,13 @@ exports = class Exercise { this._state = null; } // As we are changing state and require it to be reprocessed - // invoke the next step of program - program.next(); + // invoke the next step of workout + workout.next(); break; default: throw "Exercise: Attempting to move to an unknown state"; } - program.emit("redraw"); + workout.emit("redraw"); } } \ No newline at end of file diff --git a/apps/buffgym/buffgym-program-index.json b/apps/buffgym/buffgym-program-index.json deleted file mode 100644 index 3bb51f1b5..000000000 --- a/apps/buffgym/buffgym-program-index.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "title": "Program A", - "file": "buffgym-program-a.json" - }, - { - "title": "Program B", - "file": "buffgym-program-b.json" - } -] \ No newline at end of file diff --git a/apps/buffgym/buffgym-set.js b/apps/buffgym/buffgym-set.js index 4bd12d7ec..dc0c05671 100644 --- a/apps/buffgym/buffgym-set.js +++ b/apps/buffgym/buffgym-set.js @@ -1,9 +1,9 @@ exports = class Set { constructor(maxReps) { - this.minReps = 0; - this.maxReps = maxReps; - this.reps = 0; this.completed = false; + this.minReps = 0; + this.reps = 0; + this.maxReps = maxReps; } isCompleted() { diff --git a/apps/buffgym/buffgym-program-a.json b/apps/buffgym/buffgym-workout-a.json similarity index 96% rename from apps/buffgym/buffgym-program-a.json rename to apps/buffgym/buffgym-workout-a.json index 7ebaf3741..8eb8611d6 100644 --- a/apps/buffgym/buffgym-program-a.json +++ b/apps/buffgym/buffgym-workout-a.json @@ -1,5 +1,5 @@ { - "title": "Program A", + "title": "Workout A", "exercises": [ { "title": "Squats", diff --git a/apps/buffgym/buffgym-program-b.json b/apps/buffgym/buffgym-workout-b.json similarity index 96% rename from apps/buffgym/buffgym-program-b.json rename to apps/buffgym/buffgym-workout-b.json index b93348621..43845a98b 100644 --- a/apps/buffgym/buffgym-program-b.json +++ b/apps/buffgym/buffgym-workout-b.json @@ -1,5 +1,5 @@ { - "title": "Program B", + "title": "Workout B", "exercises": [ { "title": "Squats", diff --git a/apps/buffgym/buffgym-workout-index.json b/apps/buffgym/buffgym-workout-index.json new file mode 100644 index 000000000..af74d5e3b --- /dev/null +++ b/apps/buffgym/buffgym-workout-index.json @@ -0,0 +1,10 @@ +[ + { + "title": "Workout A", + "file": "buffgym-workout-a.json" + }, + { + "title": "Workout B", + "file": "buffgym-workout-b.json" + } +] \ No newline at end of file diff --git a/apps/buffgym/buffgym-program.js b/apps/buffgym/buffgym-workout.js similarity index 95% rename from apps/buffgym/buffgym-program.js rename to apps/buffgym/buffgym-workout.js index 68a069da5..811125293 100644 --- a/apps/buffgym/buffgym-program.js +++ b/apps/buffgym/buffgym-workout.js @@ -1,4 +1,4 @@ -exports = class Program { +exports = class Workout { constructor(params) { this.title = params.title; this.exercises = []; @@ -27,6 +27,10 @@ exports = class Program { return !!this.completed; } + static fromJSON(workout) { + + } + toJSON() { return { title: this.title, diff --git a/apps/buffgym/buffgym.app.js b/apps/buffgym/buffgym.app.js index 4dc6ffd5a..b92b2bb98 100755 --- a/apps/buffgym/buffgym.app.js +++ b/apps/buffgym/buffgym.app.js @@ -5,7 +5,7 @@ * Created: April 2020 * * Inspired by: - * - Stronglifts 5x5 training program https://stronglifts.com/5x5/ + * - Stronglifts 5x5 training workout https://stronglifts.com/5x5/ * - Stronglifts smart watch app */ @@ -66,10 +66,10 @@ function drawSet(exercise) { g.flip(); } -function drawProgDone() { +function drawWorkoutDone() { const title1 = "You did"; const title2 = "GREAT!"; - const msg = "That's the program\ncompleted. Now eat\nsome food and\nget plenty of rest."; + const msg = "That's the workout\ncompleted. Now eat\nsome food and\nget plenty of rest."; clearWatch(); setWatch(Bangle.showLauncher, BTN2, {repeat: false}); @@ -102,13 +102,13 @@ function drawSetComp() { g.flip(); } -function drawRestTimer(program) { - const exercise = program.currentExercise(); +function drawRestTimer(workout) { + const exercise = workout.currentExercise(); const motivation = "Take a breather.."; if (exercise.restPeriod <= 0) { exercise.resetRestTimer(); - program.next(); + workout.next(); return; } @@ -128,21 +128,21 @@ function drawRestTimer(program) { exercise.decRestPeriod(); } -function redraw(program) { - const exercise = program.currentExercise(); +function redraw(workout) { + const exercise = workout.currentExercise(); g.clear(); - if (program.isCompleted()) { - saveProg(program); - drawProgDone(program); + if (workout.isCompleted()) { + saveWorkout(workout); + drawWorkoutDone(workout); return; } if (exercise.isRestTimerRunning()) { if (exercise.isLastSet()) { - drawSetComp(program); + drawSetComp(workout); } else { - drawRestTimer(program); + drawRestTimer(workout); } return; @@ -151,7 +151,7 @@ function redraw(program) { drawSet(exercise); } -function drawProgMenu(programs, selProgIdx) { +function drawWorkoutMenu(workouts, selWorkoutIdx) { g.clear(); g.setFontAlign(0, -1); g.setColor(WHITE); @@ -160,16 +160,16 @@ function drawProgMenu(programs, selProgIdx) { g.setFont("6x8", 1); g.setFontAlign(-1, -1); - let selectedProgram = programs[selProgIdx].title; + let selectedWorkout = workouts[selWorkoutIdx].title; let yPos = 50; - programs.forEach(program => { + workouts.forEach(workout => { g.setColor("#f05a56"); g.fillRect(0, yPos, W, yPos + 11); g.setColor("#ffffff"); - if (selectedProgram === program.title) { + if (selectedWorkout === workout.title) { g.drawRect(0, yPos, W - 1, yPos + 11); } - g.drawString(program.title, 10, yPos + 2); + g.drawString(workout.title, 10, yPos + 2); yPos += 15; }); g.flip(); @@ -177,25 +177,25 @@ function drawProgMenu(programs, selProgIdx) { function setupMenu() { clearWatch(); - const progs = getProgIndex(); - let selProgIdx = 0; - drawProgMenu(progs, selProgIdx); + const workouts = getWorkoutIndex(); + let selWorkoutIdx = 0; + drawWorkoutMenu(workouts, selWorkoutIdx); setWatch(()=>{ - selProgIdx--; - if (selProgIdx< 0) selProgIdx = 0; - drawProgMenu(progs, selProgIdx); + selWorkoutIdx--; + if (selWorkoutIdx< 0) selWorkoutIdx = 0; + drawWorkoutMenu(workouts, selWorkoutIdx); }, BTN1, {repeat: true}); setWatch(()=>{ - const prog = buildProg(progs[selProgIdx].file); - prog.next(); + const workout = buildWorkout(workouts[selWorkoutIdx].file); + workout.next(); }, BTN2, {repeat: false}); setWatch(()=>{ - selProgIdx++; - if (selProgIdx > progs.length - 1) selProgIdx = progs.length - 1; - drawProgMenu(progs, selProgIdx); + selWorkoutIdx++; + if (selWorkoutIdx > workouts.length - 1) selWorkoutIdx = workouts.length - 1; + drawWorkoutMenu(workouts, selWorkoutIdx); }, BTN3, {repeat: true}); } @@ -249,23 +249,24 @@ function drawSplash() { }, BTN3, {repeat: false}); } -function getProgIndex() { - const progIdx = require("Storage").readJSON("buffgym-program-index.json"); - return progIdx; +function getWorkoutIndex() { + const workoutIdx = require("Storage").readJSON("buffgym-workout-index.json"); + return workoutIdx; } -function buildProg(fName) { +function buildWorkout(fName) { const Set = require("buffgym-set.js"); const Exercise = require("buffgym-exercise.js"); - const Program = require("buffgym-program.js"); - const progJSON = require("Storage").readJSON(fName); - const prog = new Program({ - title: progJSON.title, + const Workout = require("buffgym-workout.js"); + const workoutJSON = require("Storage").readJSON(fName); + const workout = new Workout({ + title: workoutJSON.title, }); - const exercises = progJSON.exercises.map(exerciseJSON => { + const exercises = workoutJSON.exercises.map(exerciseJSON => { const exercise = new Exercise({ title: exerciseJSON.title, weight: exerciseJSON.weight, + weightIncrement: exerciseJSON.weightIncrement, unit: exerciseJSON.unit, restPeriod: exerciseJSON.restPeriod, }); @@ -275,14 +276,14 @@ function buildProg(fName) { return exercise; }); - prog.addExercises(exercises); + workout.addExercises(exercises); - return prog; + return workout; } -function saveProg(program) { - const fName = getProgIndex().find(prog => prog.title === program.title).file; - require("Storage").writeJSON(fName, program.toJSON()); +function saveWorkout(workout) { + const fName = getWorkoutIndex().find(workout => workout.title === workout.title).file; + require("Storage").writeJSON(fName, workout.toJSON()); } drawSplash(); \ No newline at end of file From bf1fe5de4e7d383fd2be7184ca4012e696c6d61a Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Thu, 23 Apr 2020 06:58:14 +0100 Subject: [PATCH 143/878] Fix logic leak, make sure draw functions only deal with drawing UI --- apps/buffgym/buffgym-exercise.js | 9 +++++++++ apps/buffgym/buffgym.app.js | 10 ---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/apps/buffgym/buffgym-exercise.js b/apps/buffgym/buffgym-exercise.js index 078e206de..7d631182e 100644 --- a/apps/buffgym/buffgym-exercise.js +++ b/apps/buffgym/buffgym-exercise.js @@ -69,6 +69,15 @@ exports = class Exercise { }, 1000 * this.restPeriod); this._restInterval = setInterval(() => { + this.decRestPeriod(); + + if (this.restPeriod < 0) { + this.resetRestTimer(); + this.next(); + + return; + } + workout.emit("redraw"); }, 1000 ); } diff --git a/apps/buffgym/buffgym.app.js b/apps/buffgym/buffgym.app.js index b92b2bb98..d1c0386ff 100755 --- a/apps/buffgym/buffgym.app.js +++ b/apps/buffgym/buffgym.app.js @@ -104,14 +104,6 @@ function drawSetComp() { function drawRestTimer(workout) { const exercise = workout.currentExercise(); - const motivation = "Take a breather.."; - - if (exercise.restPeriod <= 0) { - exercise.resetRestTimer(); - workout.next(); - - return; - } g.clear(); drawMenu({showBTN2: true}); @@ -124,8 +116,6 @@ function drawRestTimer(workout) { g.setFont("6x8", 5); g.drawString(exercise.restPeriod, (W / 2) + 2, (H / 2) - 19); g.flip(); - - exercise.decRestPeriod(); } function redraw(workout) { From 3384f493e250fff949d032e57a4fed6b609e427b Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Thu, 23 Apr 2020 07:06:25 +0100 Subject: [PATCH 144/878] Fix set complete UI message --- apps/buffgym/buffgym.app.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/buffgym/buffgym.app.js b/apps/buffgym/buffgym.app.js index d1c0386ff..2c7416dba 100755 --- a/apps/buffgym/buffgym.app.js +++ b/apps/buffgym/buffgym.app.js @@ -85,9 +85,12 @@ function drawWorkoutDone() { g.flip(); } -function drawSetComp() { +function drawSetComp(exercise) { const title = "Good work"; - const msg = "No need to rest\nmove straight on\nto the next\nexercise.Your\nweight has been\nincreased for\nnext time!"; + const msg1= "No need to rest\nmove straight on\nto the next\nexercise."; + const msg2 = exercise.canProgress()? + "Your\nweight has been\nincreased for\nnext time!": + "You'll\nsmash it next\ntime!"; g.clear(); drawMenu({showBTN2: true}); @@ -97,14 +100,12 @@ function drawSetComp() { g.setFont("6x8", 2); g.drawString(title, W / 2, 10); g.setFont("6x8", 1); - g.drawString(msg, (W / 2) - 2, 45); + g.drawString(msg1 + msg2, (W / 2) - 2, 45); g.flip(); } -function drawRestTimer(workout) { - const exercise = workout.currentExercise(); - +function drawRestTimer(exercise) { g.clear(); drawMenu({showBTN2: true}); g.setFontAlign(0, -1); @@ -124,15 +125,15 @@ function redraw(workout) { if (workout.isCompleted()) { saveWorkout(workout); - drawWorkoutDone(workout); + drawWorkoutDone(); return; } if (exercise.isRestTimerRunning()) { if (exercise.isLastSet()) { - drawSetComp(workout); + drawSetComp(exercise); } else { - drawRestTimer(workout); + drawRestTimer(exercise); } return; From d3c58fb323cf50439a831b50930fed678e834380 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Thu, 23 Apr 2020 09:41:57 +0100 Subject: [PATCH 145/878] Add interface to set weight values, update README --- apps/buffgym/README.md | 25 +++- apps/buffgym/buffgym.html | 245 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+), 4 deletions(-) create mode 100644 apps/buffgym/buffgym.html diff --git a/apps/buffgym/README.md b/apps/buffgym/README.md index e9e217828..bcadf22c4 100644 --- a/apps/buffgym/README.md +++ b/apps/buffgym/README.md @@ -2,17 +2,32 @@ This gym training assistant trains you on the famous [Stronglifts 5x5 workout](https://stronglifts.com/5x5) program. +## Configuration + +### Setting your start weight values + +You will want to set your own starting weight values for your 5x5 training program. To do this is easy! After installing this app, go to the BangleJS app store, connect to your watch, and navigate to the `My Apps` tab. In there you will find this app in the list, and an icon (a down arrow) to the right of the app title. Click that icon to reveal a configuration page. Enter your weights and other details, and click upload. That is it, you are now ready to train! + ## Usage +### Start screen + When you start the app it will wait on a splash screen until you are ready to start the work out. Press any of the buttons to start ![](buffgym-scrn1.png) -You are then presented with the programs menu, use BTN1 to move up the list, and BTN3 to move down the list. Once you have made your selection, press BTN2 to select the program. +### Workouts menu + +You are then presented with the workouts menu, use BTN1 to move up the list, and BTN3 to move down the list. Once you have made your selection, press BTN2 to select the workout. ![](buffgym-scrn2.png) -You will now begin moving through the exercises in the program. You will see the exercise information on the display. +### Recording your training + +You will now begin moving through the exercises in the workout. You will see the exercise information on the display. + +![](buffgym-scrn3.png) + 1. At the top is the exercise name, e.g 'Squats' 2. Next is the weight you must train 3. In the center is where you record the number of *reps* you completed (more on that shortly) @@ -20,13 +35,15 @@ You will now begin moving through the exercises in the program. You will see the 5. Below the target reps is the current set you are training, out of the total sets for the exercise. 6. The *reps* value is used to store what you achieved for the current set, you enter this after you have trained on your current set. To alter this value, use BTN1 to increase the value (it will stop at the maximum required reps) and BTN3 to decreas the value to a minimum of 0 (this is the default value). Pressing BTN2 will confirm your reps -![](buffgym-scrn3.png) +### Rest timers You will then be presented with a rest timer screen, it counts down and automatically moves to the next exercise when it reaches 0. You can cancel the timer early if you wish by pressing BTN2. If it is the last set of an exercise, you don't need to rest, so it lets you know you have completed all the sets in the exercise and can start the next exercise. ![](buffgym-scrn4.png) ![](buffgym-scrn5.png) +### Workout completed + Once all exercises are done, you are presented with a pat-on-the-back screen to tell you how awesome you are. ![](buffgym-scrn6.png) @@ -40,4 +57,4 @@ Once all exercises are done, you are presented with a pat-on-the-back screen to ## Created by -[Paul Cockrell](https://github.com/paulcockrell) April 2020. \ No newline at end of file +[Paul Cockrell](https://github.com/paulcockrell) April 2020. diff --git a/apps/buffgym/buffgym.html b/apps/buffgym/buffgym.html new file mode 100644 index 000000000..c5766bcfa --- /dev/null +++ b/apps/buffgym/buffgym.html @@ -0,0 +1,245 @@ + + + + + +

BuffGym

+

+ Enter in your weights for each exercise, start light and keep consistent with your training. The weight increment field is how much the app will increase your weights for an exercise if you successfully complete all the reps and sets for an exercise. Make sure its a value that matches the weights in your gym. +

+

+ For more information on how to train this program refer the Stronglifts website +

+
+

Workout A

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExerciseSets / RepsWeightWeight increment
+ Squats + + 5x5 + + + + +
+ Overhead press + + 5x5 + + + + +
+ Deadlift + + 1x5 + + + + +
+ Pullups + + 3x10 + + + + +
+

Workout B

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExerciseSets / RepsWeightWeight increment
+ Squats + + 5x5 + + + + +
+ Bench press + + 5x5 + + + + +
+ Row + + 5x5 + + + + +
+ Tricep extension + + 3x10 + + + + +
+
+

+ + + + + + + From 04f1e523e85676a16b3058ba6718cf9519efccd4 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Thu, 23 Apr 2020 09:48:31 +0100 Subject: [PATCH 146/878] Serialise uploading. Add buzz on watch to indicate completed --- apps/buffgym/buffgym.html | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/buffgym/buffgym.html b/apps/buffgym/buffgym.html index c5766bcfa..4025ee19d 100644 --- a/apps/buffgym/buffgym.html +++ b/apps/buffgym/buffgym.html @@ -237,8 +237,13 @@ } document.getElementById("upload").addEventListener("click", function() { - Puck.eval(`require("Storage").writeJSON("buffgym-workout-a.json",${JSON.stringify(workoutA())})`, ()=>{console.log("Done uploading workout A")}); - Puck.eval(`require("Storage").writeJSON("buffgym-workout-b.json",${JSON.stringify(workoutB())})`, ()=>{console.log("Done uploading workout B")}); + Puck.eval(`require("Storage").writeJSON("buffgym-workout-a.json",${JSON.stringify(workoutA())})`, ()=>{ + Puck.eval(`require("Storage").writeJSON("buffgym-workout-b.json",${JSON.stringify(workoutB())})`, ()=>{ + Puck.eval(`Bangle.buzz();`, () => { + console.log("all done"); + }) + }) + }); }); From a0d6f8741e81f2861f491a857594fb844b8537ef Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Thu, 23 Apr 2020 09:51:15 +0100 Subject: [PATCH 147/878] Add interface to apps.json for BuffGym app --- apps.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps.json b/apps.json index 65b681390..4f0346bd8 100644 --- a/apps.json +++ b/apps.json @@ -1347,6 +1347,7 @@ "description": "BuffGym is the famous 5x5 workout program for the BangleJS", "tags": "tool,outdoors,gym,exercise", "type": "app", + "interface": "buffgym.html", "allow_emulator": false, "readme": "README.md", "storage": [ From edd1b73bc00dcb2a2e9c43d5d5aa9d7da4224b25 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Thu, 23 Apr 2020 10:11:28 +0100 Subject: [PATCH 148/878] Update apps.json to use new buffgym file names. Fix buzz command --- apps.json | 8 ++++---- apps/buffgym/buffgym.html | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps.json b/apps.json index 4f0346bd8..60d973e23 100644 --- a/apps.json +++ b/apps.json @@ -1354,10 +1354,10 @@ {"name":"buffgym.app.js", "url": "buffgym.app.js"}, {"name":"buffgym-set.js","url":"buffgym-set.js"}, {"name":"buffgym-exercise.js","url":"buffgym-exercise.js"}, - {"name":"buffgym-program.js","url":"buffgym-program.js"}, - {"name":"buffgym-program-a.json","url":"buffgym-program-a.json"}, - {"name":"buffgym-program-b.json","url":"buffgym-program-b.json"}, - {"name":"buffgym-program-index.json","url":"buffgym-program-index.json"}, + {"name":"buffgym-workout.js","url":"buffgym-workout.js"}, + {"name":"buffgym-workout-a.json","url":"buffgym-workout-a.json"}, + {"name":"buffgym-workout-b.json","url":"buffgym-workout-b.json"}, + {"name":"buffgym-workout-index.json","url":"buffgym-workout-index.json"}, {"name":"buffgym.img","url":"buffgym-icon.js","evaluate":true} ] }, diff --git a/apps/buffgym/buffgym.html b/apps/buffgym/buffgym.html index 4025ee19d..3c18932e9 100644 --- a/apps/buffgym/buffgym.html +++ b/apps/buffgym/buffgym.html @@ -239,7 +239,7 @@ document.getElementById("upload").addEventListener("click", function() { Puck.eval(`require("Storage").writeJSON("buffgym-workout-a.json",${JSON.stringify(workoutA())})`, ()=>{ Puck.eval(`require("Storage").writeJSON("buffgym-workout-b.json",${JSON.stringify(workoutB())})`, ()=>{ - Puck.eval(`Bangle.buzz();`, () => { + Puck.eval(`Bangle.buzz()`, () => { console.log("all done"); }) }) From a389ed5dbee7108ca55eb7853da3f307d962ec87 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 23 Apr 2020 10:28:42 +0100 Subject: [PATCH 149/878] Torch: Change start sequence to BTN1/3/1/3 to avoid accidental turning on (fix #342) --- apps.json | 4 ++-- apps/torch/ChangeLog | 1 + apps/torch/widget.js | 24 ++++++++++++++++-------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/apps.json b/apps.json index 65b681390..4c5910a6f 100644 --- a/apps.json +++ b/apps.json @@ -921,8 +921,8 @@ "name": "Torch", "shortName":"Torch", "icon": "app.png", - "version":"0.01", - "description": "Turns screen white to help you see in the dark. Select from the launcher or press BTN3 four times in quick succession to start when in normal clock mode", + "version":"0.02", + "description": "Turns screen white to help you see in the dark. Select from the launcher or press BTN1,BTN3,BTN1,BTN3 quickly to start when in any app that shows widgets", "tags": "tool,torch", "storage": [ {"name":"torch.app.js","url":"app.js"}, diff --git a/apps/torch/ChangeLog b/apps/torch/ChangeLog index 5560f00bc..8e76b717a 100644 --- a/apps/torch/ChangeLog +++ b/apps/torch/ChangeLog @@ -1 +1,2 @@ 0.01: New App! +0.02: Change start sequence to BTN1/3/1/3 to avoid accidental turning on (fix #342) diff --git a/apps/torch/widget.js b/apps/torch/widget.js index e3d1ea22f..a5002ea71 100644 --- a/apps/torch/widget.js +++ b/apps/torch/widget.js @@ -1,18 +1,26 @@ +(function() { var clickTimes = []; -var CLICK_COUNT = 4; // number of taps -var CLICK_PERIOD = 1; // second +var clickPattern = ""; +var TAPS = 4; // number of taps +var PERIOD = 1; // seconds // we don't actually create/draw a widget here at all... - Bangle.on("lcdPower",function(on) { // First click (that turns LCD on) isn't given to // setWatch, so handle it here - if (on) clickTimes=[getTime()]; + if (!on) return; + clickTimes=[getTime()]; + clickPattern="x"; }); -setWatch(function(e) { - while (clickTimes.length>=CLICK_COUNT) clickTimes.shift(); +function tap(e,c) { + clickPattern = clickPattern.substr(-3)+c; + while (clickTimes.length>=TAPS) clickTimes.shift(); clickTimes.push(e.time); var clickPeriod = e.time-clickTimes[0]; - if (clickTimes.length==CLICK_COUNT && clickPeriod Date: Thu, 23 Apr 2020 10:53:09 +0100 Subject: [PATCH 150/878] stopwatch: Ensure seconds counter is in sync with subseconds (fix #341) --- apps.json | 2 +- apps/swatch/ChangeLog | 1 + apps/swatch/stopwatch.js | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 4c5910a6f..127d87d89 100644 --- a/apps.json +++ b/apps.json @@ -452,7 +452,7 @@ { "id": "swatch", "name": "Stopwatch", "icon": "stopwatch.png", - "version":"0.06", + "version":"0.07", "interface": "interface.html", "description": "Simple stopwatch with Lap Time logging to a JSON file", "tags": "health", diff --git a/apps/swatch/ChangeLog b/apps/swatch/ChangeLog index 9a037fa41..caa74a1ba 100644 --- a/apps/swatch/ChangeLog +++ b/apps/swatch/ChangeLog @@ -6,3 +6,4 @@ 0.04: Changed save file filename, add interface.html to allow laps to be loaded 0.05: Added widgets 0.06: Added total running time, moved lap time to smaller display, total run time now appends as first entry in array, saving now saves last lap as well +0.07: Ensure seconds counter is in sync with subseconds (fix #341) diff --git a/apps/swatch/stopwatch.js b/apps/swatch/stopwatch.js index 659f0606d..478de2712 100644 --- a/apps/swatch/stopwatch.js +++ b/apps/swatch/stopwatch.js @@ -94,7 +94,8 @@ setWatch(function() { // Start/stop displayInterval = setInterval(function() { var last = tCurrent; if (started) tCurrent = Date.now(); - if (Math.floor(last/1000)!=Math.floor(tCurrent/1000)) + if (Math.floor((last-tStart)/1000)!=Math.floor((tCurrent-tStart)/1000) || + Math.floor((last-tTotal)/1000)!=Math.floor((tCurrent-tTotal)/1000)) drawsecs(); else drawms(); From c36bd7f97f7b89c2d7445a62255686f399333ed7 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 23 Apr 2020 10:57:59 +0100 Subject: [PATCH 151/878] Add readme to example apps (fix #300) --- apps/_example_app/README.md | 25 +++++++++++++++++++++++++ apps/_example_app/add_to_apps.json | 1 + apps/_example_widget/README.md | 25 +++++++++++++++++++++++++ apps/_example_widget/add_to_apps.json | 1 + 4 files changed, 52 insertions(+) create mode 100644 apps/_example_app/README.md create mode 100644 apps/_example_widget/README.md diff --git a/apps/_example_app/README.md b/apps/_example_app/README.md new file mode 100644 index 000000000..dc139bc9a --- /dev/null +++ b/apps/_example_app/README.md @@ -0,0 +1,25 @@ +# App Name + +Describe the app... + +Add screen shots (if possible) to the app folder and link then into this file with ![](.png) + +## Usage + +Describe how to use it + +## Features + +Name the function + +## Controls + +Name the buttons and what they are used for + +## Requests + +Name who should be contacted for support/update requests + +## Creator + +Your name diff --git a/apps/_example_app/add_to_apps.json b/apps/_example_app/add_to_apps.json index ca75a7bd8..bb0377b66 100644 --- a/apps/_example_app/add_to_apps.json +++ b/apps/_example_app/add_to_apps.json @@ -6,6 +6,7 @@ "version":"0.01", "description": "A detailed description of my great app", "tags": "", + "readme": "README.md", "storage": [ {"name":"7chname.app.js","url":"app.js"}, {"name":"7chname.img","url":"app-icon.js","evaluate":true} diff --git a/apps/_example_widget/README.md b/apps/_example_widget/README.md new file mode 100644 index 000000000..a909e9e7e --- /dev/null +++ b/apps/_example_widget/README.md @@ -0,0 +1,25 @@ +# Widget Name + +Describe the app... + +Add screen shots (if possible) to the app folder and link then into this file with ![](.png) + +## Usage + +Describe how to use it + +## Features + +Name the function + +## Controls + +Name the buttons and what they are used for + +## Requests + +Name who should be contacted for support/update requests + +## Creator + +Your name diff --git a/apps/_example_widget/add_to_apps.json b/apps/_example_widget/add_to_apps.json index 5d0057960..527c698a0 100644 --- a/apps/_example_widget/add_to_apps.json +++ b/apps/_example_widget/add_to_apps.json @@ -7,6 +7,7 @@ "description": "A detailed description of my great widget", "tags": "widget", "type": "widget", + "readme": "README.md", "storage": [ {"name":"7chname.wid.js","url":"widget.js"} ] From f8590bdcf58df24f66f88f694c24c51159354f02 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Thu, 23 Apr 2020 11:18:10 +0100 Subject: [PATCH 152/878] Refactor workout json loading. Fix file name matching bug --- apps/buffgym/buffgym-exercise.js | 4 ++-- apps/buffgym/buffgym-workout.js | 25 ++++++++++++++++++++++++- apps/buffgym/buffgym.app.js | 23 ++--------------------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/apps/buffgym/buffgym-exercise.js b/apps/buffgym/buffgym-exercise.js index 7d631182e..ea20aa132 100644 --- a/apps/buffgym/buffgym-exercise.js +++ b/apps/buffgym/buffgym-exercise.js @@ -4,10 +4,10 @@ exports = class Exercise { this.sets = []; this.title = params.title; this.weight = params.weight; + this.weightIncrement = params.weightIncrement; this.unit = params.unit; this.restPeriod = params.restPeriod; this._originalRestPeriod = params.restPeriod; - this._weightIncrement = params.weightIncrement; this._restTimeout = null; this._restInterval = null; this._state = null; @@ -50,7 +50,7 @@ exports = class Exercise { setCompleted() { if (!this.canSetCompleted()) throw "All sets must be completed"; - if (this.canProgress()) this.weight += this._weightIncrement; + if (this.canProgress()) this.weight += this.weightIncrement; this.completed = true; } diff --git a/apps/buffgym/buffgym-workout.js b/apps/buffgym/buffgym-workout.js index 811125293..124c27f4b 100644 --- a/apps/buffgym/buffgym-workout.js +++ b/apps/buffgym/buffgym-workout.js @@ -27,8 +27,30 @@ exports = class Workout { return !!this.completed; } - static fromJSON(workout) { + static fromJSON(workoutJSON) { + const Set = require("buffgym-set.js"); + const Exercise = require("buffgym-exercise.js"); + const workout = new this({ + title: workoutJSON.title, + }); + const exercises = workoutJSON.exercises.map(exerciseJSON => { + const exercise = new Exercise({ + title: exerciseJSON.title, + weight: exerciseJSON.weight, + weightIncrement: exerciseJSON.weightIncrement, + unit: exerciseJSON.unit, + restPeriod: exerciseJSON.restPeriod, + }); + exerciseJSON.sets.forEach(setJSON => { + exercise.addSet(new Set(setJSON)); + }); + return exercise; + }); + + workout.addExercises(exercises); + + return workout; } toJSON() { @@ -38,6 +60,7 @@ exports = class Workout { return { title: exercise.title, weight: exercise.weight, + weightIncrement: exercise.weightIncrement, unit: exercise.unit, sets: exercise.sets.map(set => set.maxReps), restPeriod: exercise.restPeriod, diff --git a/apps/buffgym/buffgym.app.js b/apps/buffgym/buffgym.app.js index 2c7416dba..fc2be83f9 100755 --- a/apps/buffgym/buffgym.app.js +++ b/apps/buffgym/buffgym.app.js @@ -246,34 +246,15 @@ function getWorkoutIndex() { } function buildWorkout(fName) { - const Set = require("buffgym-set.js"); - const Exercise = require("buffgym-exercise.js"); const Workout = require("buffgym-workout.js"); const workoutJSON = require("Storage").readJSON(fName); - const workout = new Workout({ - title: workoutJSON.title, - }); - const exercises = workoutJSON.exercises.map(exerciseJSON => { - const exercise = new Exercise({ - title: exerciseJSON.title, - weight: exerciseJSON.weight, - weightIncrement: exerciseJSON.weightIncrement, - unit: exerciseJSON.unit, - restPeriod: exerciseJSON.restPeriod, - }); - exerciseJSON.sets.forEach(setJSON => { - exercise.addSet(new Set(setJSON)); - }); - - return exercise; - }); - workout.addExercises(exercises); + const workout = Workout.fromJSON(workoutJSON); return workout; } function saveWorkout(workout) { - const fName = getWorkoutIndex().find(workout => workout.title === workout.title).file; + const fName = getWorkoutIndex().find(w => w.title === workout.title).file; require("Storage").writeJSON(fName, workout.toJSON()); } From 2ebdf0c6c309e8983b08b8906cd1bc5cb96fb6e1 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Thu, 23 Apr 2020 11:45:45 +0100 Subject: [PATCH 153/878] Add Changelog and bump version in apps.json --- apps.json | 2 +- apps/buffgym/ChangeLog | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 apps/buffgym/ChangeLog diff --git a/apps.json b/apps.json index 60d973e23..009f510b9 100644 --- a/apps.json +++ b/apps.json @@ -1343,7 +1343,7 @@ "id": "buffgym", "name": "BuffGym", "icon": "buffgym.png", - "version":"0.01", + "version":"0.02", "description": "BuffGym is the famous 5x5 workout program for the BangleJS", "tags": "tool,outdoors,gym,exercise", "type": "app", diff --git a/apps/buffgym/ChangeLog b/apps/buffgym/ChangeLog new file mode 100644 index 000000000..6efdd865a --- /dev/null +++ b/apps/buffgym/ChangeLog @@ -0,0 +1,2 @@ +0.01: Create BuffGym app +0.02: Add web interface for personalising workout From e40829ea73f2402dc1abf0e0edad7d6fd23f1205 Mon Sep 17 00:00:00 2001 From: Dimitri Gigot Date: Thu, 23 Apr 2020 13:46:06 +0000 Subject: [PATCH 154/878] 0.06: Complete rewrite in 80x80, better perf, add settings --- apps.json | 6 +- apps/toucher/ChangeLog | 2 +- apps/toucher/app.js | 299 +++++++++++++++++++++++---------------- apps/toucher/settings.js | 59 ++++++++ 4 files changed, 239 insertions(+), 127 deletions(-) create mode 100644 apps/toucher/settings.js diff --git a/apps.json b/apps.json index 43e7e4b9d..ad5b20820 100644 --- a/apps.json +++ b/apps.json @@ -1092,14 +1092,16 @@ }, { "id": "toucher", "name": "Touch Launcher", - "shortName":"Menu", + "shortName":"Toucher", "icon": "app.png", "version":"0.06", "description": "Touch enable left to right launcher.", "tags": "tool,system,launcher", "type":"launch", "storage": [ - {"name":"toucher.app.js","url":"app.js"} + {"name":"toucher.app.js","url":"app.js"}, + {"name":"toucher.settings.js","url":"settings.js"}, + {"name":"toucher.json"} ], "sortorder" : -10 }, diff --git a/apps/toucher/ChangeLog b/apps/toucher/ChangeLog index 0c97d9e13..494110d55 100644 --- a/apps/toucher/ChangeLog +++ b/apps/toucher/ChangeLog @@ -3,4 +3,4 @@ 0.03: Close launcher when lcd turn off 0.04: Complete rewrite to add animation and loop ( issue #210 ) 0.05: Improve perf -0.06: Only store relevant app data (saves RAM when many apps) +0.06: Complete rewrite in 80x80, better perf, add settings \ No newline at end of file diff --git a/apps/toucher/app.js b/apps/toucher/app.js index cf7d5333b..5aac55134 100644 --- a/apps/toucher/app.js +++ b/apps/toucher/app.js @@ -1,160 +1,206 @@ -Bangle.setLCDMode("120x120"); +const Storage = require("Storage"); +const filename = 'toucher.json'; +let settings = Storage.readJSON(filename,1) || { + hightres: true, + animation : true, + frame : 3, + debug: false +}; + +if(!settings.highres) Bangle.setLCDMode("80x80"); +else Bangle.setLCDMode(); + g.clear(); g.flip(); -const Storage = require("Storage"); - -function getApps(){ - return Storage.list(/\.info$/).map(app=>{var a=Storage.readJSON(app,1);return a&&{name:a.name,type:a.type,icon:a.icon,sortorder:a.sortorder,src:a.src,version:a.version}}) - .filter(app=>app && (app.type=="app" || app.type=="clock" || !app.type)) - .sort((a,b)=>{ - var n=(0|a.sortorder)-(0|b.sortorder); - if (n) return n; // do sortorder first - if (a.nameb.name) return 1; - return 0; - }); -} +let icons = {}; const HEIGHT = g.getHeight(); const WIDTH = g.getWidth(); const HALF = WIDTH/2; -const ANIMATION_FRAME = 4; -const ANIMATION_STEP = HALF / ANIMATION_FRAME; +const ORIGINAL_ICON_SIZE = 48; + +const STATE = { + settings_open: false, + index: 0, + target: 240, + offset: 0 +}; function getPosition(index){ return (index*HALF); } -let current_app = 0; -let target = 0; -let slideOffset = 0; +function getApps(){ + const exit_app = { + name: 'Exit', + special: true + }; + const raw_apps = Storage.list(/\.info$/).filter(app => app.endsWith('.info')).map(app => Storage.readJSON(app,1) || { name: "DEAD: "+app.substr(1) }) + .filter(app=>app.type=="app" || app.type=="clock" || !app.type) + .sort((a,b)=>{ + var n=(0|a.sortorder)-(0|b.sortorder); + if (n) return n; // do sortorder first + if (a.nameb.name) return 1; + return 0; + }).map(raw => ({ + name: raw.name, + src: raw.src, + icon: raw.icon, + version: raw.version + })); -const back = { - name: 'BACK', - back: true -}; - -let icons = {}; - -const apps = [back].concat(getApps()); -apps.push(back); - -function noIcon(x, y, size){ - const half = size/2; - g.setColor(1,1,1); - g.setFontAlign(-0,0); - const fontSize = Math.floor(size / 30 * 2); - g.setFont('6x8', fontSize); - if(fontSize) g.drawString('-?-', x+1.5, y); - g.drawRect(x-half, y-half, x+half, y+half); + const apps = [Object.assign({}, exit_app)].concat(raw_apps); + apps.push(exit_app); + return apps.map((app, i) => { + app.x = getPosition(i); + return app; + }); } -function drawIcons(offset){ - apps.forEach((app, i) => { - const x = getPosition(i) + HALF - offset; - const y = HALF - (HALF*0.3);//-(HALF*0.7); - let diff = (x - HALF); - if(diff < 0) diff *=-1; +const APPS = getApps(); - const dontRender = x+(HALF/2)<0 || x-(HALF/2)>120; - if(dontRender) { - delete icons[app.name]; +function noIcon(x, y, scale){ + if(scale < 0.2) return; + g.setColor(scale, scale, scale); + g.setFontAlign(0,0); + g.setFont('6x8',settings.highres ? 6:3); + g.drawString('x_x', x+1.5, y); + const h = (ORIGINAL_ICON_SIZE/3); + g.drawRect(x-h, y-h, x+h, y+h); +} + +function render(){ + const start = Date.now(); + + const ANIMATION_FRAME = settings.frame; + const ANIMATION_STEP = Math.floor(HALF / ANIMATION_FRAME); + const THRESHOLD = ANIMATION_STEP - 1; + + g.clear(); + const visibleApps = APPS.filter(app => app.x >= STATE.offset-HALF && app.x <= STATE.offset+WIDTH-HALF ); + + visibleApps.forEach(app => { + + const x = app.x+HALF-STATE.offset; + const y = HALF - (HALF*0.3); + + let dist = HALF - x; + if(dist < 0) dist *= -1; + + const scale = 1 - (dist / HALF); + + if(!scale) return; + + if(app.special){ + const font = settings.highres ? '6x8' : '4x6'; + const fontSize = settings.highres ? 2 : 1; + g.setFont(font, fontSize); + g.setColor(scale,scale,scale); + g.setFontAlign(0,0); + g.drawString(app.name, HALF, HALF); return; } - let size = 30; - if((diff*0.5) < size) size -= (diff*0.5); - else size = 0; - const scale = size / 30; - if(size){ - let c = size / 30 * 2; - c = c -1; - if(c < 0) c = 0; + //draw icon + const icon = app.icon ? + icons[app.name] ? icons[app.name] : Storage.read(app.icon) + : null; - if(app.back){ - g.setFont('6x8', 1); - g.setFontAlign(0, -1); - g.setColor(c,c,c); - g.drawString('Back', HALF, HALF); - return; + if(icon){ + icons[app.name] = icon; + try { + const rescale = settings.highres ? scale*ORIGINAL_ICON_SIZE : (scale*(ORIGINAL_ICON_SIZE/2)); + const imageScale = settings.highres ? scale*2 : scale; + g.drawImage(icon, x-rescale, y-rescale, { scale: imageScale }); + } catch(e){ + noIcon(x, y, scale); } - // icon - - const icon = app.icon ? - icons[app.name] ? icons[app.name] : Storage.read(app.icon) - : null; - if(icon){ - icons[app.name] = icon; - try { - g.drawImage(icon, x-(scale*24), y-(scale*24), { scale: scale }); - } catch(e){ - noIcon(x, y, size); - } - }else{ - noIcon(x, y, size); - } - //text - g.setFont('6x8', 1); - g.setFontAlign(0, -1); - g.setColor(c,c,c); - g.drawString(app.name, HALF, HEIGHT - (HALF*0.7)); - - const type = app.type ? app.type : 'App'; - const version = app.version ? app.version : '0.00'; - const info = type+' v'+version; - g.setFontAlign(0,1); - g.setFont('4x6', 0.25); - g.setColor(c,c,c); - g.drawString(info, HALF, 110, { scale: scale }); + }else{ + noIcon(x, y, scale); } - }); -} -function draw(ignoreLoop){ - g.setColor(0,0,0); - g.fillRect(0,0,WIDTH,HEIGHT); - drawIcons(slideOffset); + //draw text + g.setColor(scale,scale,scale); + if(scale > 0.1){ + const font = settings.highres ? '6x8': '4x6'; + const fontSize = settings.highres ? 2 : 1; + g.setFont(font, fontSize); + g.setFontAlign(0,0); + g.drawString(app.name, HALF, HEIGHT/4*3); + } + + if(settings.highres){ + const type = app.type ? app.type : 'App'; + const version = app.version ? app.version : '0.00'; + const info = type+' v'+version; + g.setFontAlign(0,1); + g.setFont('6x8', 1.5); + g.setColor(scale,scale,scale); + g.drawString(info, HALF, 215, { scale: scale }); + } + + }); + + const duration = Math.floor(Date.now()-start); + if(settings.debug){ + g.setFontAlign(0,1); + g.setColor(0, 1, 0); + const fontSize = settings.highres ? 2 : 1; + g.setFont('4x6',fontSize); + g.drawString('Render: '+duration+'ms', HALF, HEIGHT); + } g.flip(); - if(slideOffset == target) return; - if(slideOffset < target) slideOffset+= ANIMATION_STEP; - else if(slideOffset > target) slideOffset -= ANIMATION_STEP; - if(!ignoreLoop) draw(); + if(STATE.offset == STATE.target) return; + + if(STATE.offset < STATE.target) STATE.offset += ANIMATION_STEP; + else if(STATE.offset > STATE.target) STATE.offset -= ANIMATION_STEP; + + if(STATE.offset >= STATE.target-THRESHOLD && STATE.offset < STATE.target) STATE.offset = STATE.target; + if(STATE.offset <= STATE.target+THRESHOLD && STATE.offset > STATE.target) STATE.offset = STATE.target; + setTimeout(render, 0); } function animateTo(index){ - target = getPosition(index); - draw(); -} -function goTo(index){ - current_app = index; - target = getPosition(index); - slideOffset = target; - draw(true); + STATE.index = index; + STATE.target = getPosition(index); + render(); } -goTo(1); +function jumpTo(index){ + STATE.index = index; + STATE.target = getPosition(index); + STATE.offset = STATE.target; + render(); +} function prev(){ - if(current_app == 0) goTo(apps.length-1); - current_app -= 1; - if(current_app < 0) current_app = 0; - animateTo(current_app); + if(STATE.settings_open) return; + if(STATE.index == 0) jumpTo(APPS.length-1); + setTimeout(() => { + if(!settings.animation) jumpTo(STATE.index-1); + else animateTo(STATE.index-1); + },1); } function next(){ - if(current_app == apps.length-1) goTo(0); - current_app += 1; - if(current_app > apps.length-1) current_app = apps.length-1; - animateTo(current_app); + if(STATE.settings_open) return; + if(STATE.index == APPS.length-1) jumpTo(0); + setTimeout(() => { + if(!settings.animation) jumpTo(STATE.index+1); + else animateTo(STATE.index+1); + },1); } -function run() { - const app = apps[current_app]; - if(app.back) return load(); +function run(){ + + const app = APPS[STATE.index]; + if(app.name == 'Exit') return load(); + if (Storage.read(app.src)===undefined) { E.showMessage("App Source\nNot found"); - setTimeout(draw, 2000); + setTimeout(render, 2000); } else { Bangle.setLCDMode(); g.clear(); @@ -162,15 +208,12 @@ function run() { E.showMessage("Loading..."); load(app.src); } + } - -setWatch(prev, BTN1, { repeat: true }); -setWatch(next, BTN3, { repeat: true }); -setWatch(run, BTN2, {repeat:true,edge:"falling"}); - // Screen event Bangle.on('touch', function(button){ + if(STATE.settings_open) return; switch(button){ case 1: prev(); @@ -185,6 +228,7 @@ Bangle.on('touch', function(button){ }); Bangle.on('swipe', dir => { + if(STATE.settings_open) return; if(dir == 1) prev(); else next(); }); @@ -193,3 +237,10 @@ Bangle.on('swipe', dir => { Bangle.on('lcdPower', on => { if(!on) return load(); }); + + +setWatch(prev, BTN1, { repeat: true }); +setWatch(next, BTN3, { repeat: true }); +setWatch(run, BTN2, { repeat:true }); + +jumpTo(1); \ No newline at end of file diff --git a/apps/toucher/settings.js b/apps/toucher/settings.js new file mode 100644 index 000000000..6f7320513 --- /dev/null +++ b/apps/toucher/settings.js @@ -0,0 +1,59 @@ +(function(back) { + + const Storage = require("Storage"); + const filename = 'toucher.json'; + let settings = Storage.readJSON(filename,1)|| null; + + function getSettings(){ + return { + highres: true, + animation : true, + frame : 3, + debug: true + }; + } + + function updateSettings() { + require("Storage").writeJSON(filename, settings); + Bangle.buzz(); + } + + if(!settings){ + settings = getSettings(); + updateSettings(); + } + + function saveChange(name){ + return function(v){ + settings[name] = v; + updateSettings(); + } + } + + E.showMenu({ + '': { 'title': 'Toucher settings' }, + "Resolution" : { + value : settings.highres, + format : v => v?"High":"Low", + onchange: v => { + saveChange('highres')(!settings.highres); + } + }, + "Animation" : { + value : settings.animation, + format : v => v?"On":"Off", + onchange : saveChange('animation') + }, + "Frame rate" : { + value : settings.frame, + min: 1, max: 10, step: 1, + onchange : saveChange('frame') + }, + "Debug" : { + value : settings.debug, + format : v => v?"On":"Off", + onchange : saveChange('debug') + }, + '< Back': back + }); +}); \ No newline at end of file From 1cdbe79bac650fa639cf57ea4378c5148711ac10 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 23 Apr 2020 15:47:57 +0100 Subject: [PATCH 155/878] Tweak favourite apps code to remove the duplicated app uploader --- js/index.js | 130 +++++++++++++++++++++------------------------------- js/utils.js | 13 ------ 2 files changed, 51 insertions(+), 92 deletions(-) diff --git a/js/index.js b/js/index.js index 51b1d71c3..665b5b62b 100644 --- a/js/index.js +++ b/js/index.js @@ -1,7 +1,6 @@ var appJSON = []; // List of apps and info from apps.json var appsInstalled = []; // list of app JSON var files = []; // list of files on Bangle -var favourites = []; // list of user favourite app const FAVOURITE = "favouriteapps.json"; httpGet("apps.json").then(apps=>{ @@ -144,7 +143,13 @@ function handleAppInterface(app) { }); } -function handleAppFavourite(favourite, app){ +function getAppFavourites() { + var f = localStorage.getItem(FAVOURITE); + return (f === null) ? ["boot","launch","setting"] : JSON.parse(f); +} + +function changeAppFavourite(favourite, app) { + var favourites = getAppFavourites(); if (favourite) { favourites = favourites.concat([app.id]); } else { @@ -154,7 +159,7 @@ function handleAppFavourite(favourite, app){ favourites = favourites.filter(e => e != app.id); } } - localStorage.setItem("favouriteapps.json", JSON.stringify(favourites)); + localStorage.setItem(FAVOURITE, JSON.stringify(favourites)); refreshLibrary(); } @@ -187,6 +192,7 @@ function refreshFilter(){ function refreshLibrary() { var panelbody = document.querySelector("#librarycontainer .panel-body"); var visibleApps = appJSON; + var favourites = getAppFavourites(); if (activeFilter) { if ( activeFilter == "favourites" ) { @@ -200,8 +206,6 @@ function refreshLibrary() { visibleApps = visibleApps.filter(app => app.name.toLowerCase().includes(currentSearch) || app.tags.includes(currentSearch)); } - favourites = (localStorage.getItem(FAVOURITE)) === null ? JSON.parse('["boot","launch","setting"]') : JSON.parse(localStorage.getItem("favouriteapps.json")); - panelbody.innerHTML = visibleApps.map((app,idx) => { var appInstalled = appsInstalled.find(a=>a.id==app.id); var version = getVersionInfo(app, appInstalled); @@ -275,9 +279,9 @@ function refreshLibrary() { } else if (icon.classList.contains("icon-download")) { handleAppInterface(app); } else if ( button.innerText == String.fromCharCode(0x2661)) { - handleAppFavourite(true, app); + changeAppFavourite(true, app); } else if ( button.innerText == String.fromCharCode(0x2665) ) { - handleAppFavourite(false, app); + changeAppFavourite(false, app); } }); }); @@ -478,6 +482,43 @@ function getInstalledApps(refresh) { }); } +/// Removes everything and install the given apps, eg: installMultipleApps(["boot","mclock"], "minimal") +function installMultipleApps(appIds, promptName) { + var apps = appIds.map( appid => appJSON.find(app=>app.id==appid) ); + if (apps.some(x=>x===undefined)) + return Promise.reject("Not all apps found"); + var appCount = apps.length; + return showPrompt("Install Defaults",`Remove everything and install ${promptName} apps?`).then(() => { + return Comms.removeAllApps(); + }).then(()=>{ + Progress.hide({sticky:true}); + appsInstalled = []; + showToast(`Existing apps removed. Installing ${appCount} apps...`); + return new Promise((resolve,reject) => { + function upload() { + var app = apps.shift(); + if (app===undefined) return resolve(); + Progress.show({title:`${app.name} (${appCount-apps.length}/${appCount})`,sticky:true}); + Comms.uploadApp(app,"skip_reset").then((appJSON) => { + Progress.hide({sticky:true}); + if (appJSON) appsInstalled.push(appJSON); + showToast(`(${appCount-apps.length}/${appCount}) ${app.name} Uploaded`); + upload(); + }).catch(function() { + Progress.hide({sticky:true}); + reject(); + }); + } + upload(); + }); + }).then(()=>{ + return Comms.setTime(); + }).then(()=>{ + showToast("Apps successfully installed!","success"); + return getInstalledApps(true); + }); +} + var connectMyDeviceBtn = document.getElementById("connectmydevice"); function handleConnectionChange(connected) { @@ -571,42 +612,8 @@ document.getElementById("removeall").addEventListener("click",event=>{ }); // Install all default apps in one go document.getElementById("installdefault").addEventListener("click",event=>{ - var defaultApps, appCount; httpGet("defaultapps.json").then(json=>{ - defaultApps = JSON.parse(json); - defaultApps = defaultApps.map( appid => appJSON.find(app=>app.id==appid) ); - if (defaultApps.some(x=>x===undefined)) - throw "Not all apps found"; - appCount = defaultApps.length; - return showPrompt("Install Defaults","Remove everything and install default apps?"); - }).then(() => { - return Comms.removeAllApps(); - }).then(()=>{ - Progress.hide({sticky:true}); - appsInstalled = []; - showToast(`Existing apps removed. Installing ${appCount} apps...`); - return new Promise((resolve,reject) => { - function upload() { - var app = defaultApps.shift(); - if (app===undefined) return resolve(); - Progress.show({title:`${app.name} (${appCount-defaultApps.length}/${appCount})`,sticky:true}); - Comms.uploadApp(app,"skip_reset").then((appJSON) => { - Progress.hide({sticky:true}); - if (appJSON) appsInstalled.push(appJSON); - showToast(`(${appCount-defaultApps.length}/${appCount}) ${app.name} Uploaded`); - upload(); - }).catch(function() { - Progress.hide({sticky:true}); - reject(); - }); - } - upload(); - }); - }).then(()=>{ - return Comms.setTime(); - }).then(()=>{ - showToast("Default apps successfully installed!","success"); - return getInstalledApps(true); + return installMultipleApps(JSON.parse(json), "default"); }).catch(err=>{ Progress.hide({sticky:true}); showToast("App Install failed, "+err,"error"); @@ -615,43 +622,8 @@ document.getElementById("installdefault").addEventListener("click",event=>{ // Install all favoutrie apps in one go document.getElementById("installfavourite").addEventListener("click",event=>{ - var defaultApps, appCount; - asyncLocalStorage.getItem(FAVOURITE).then(json=>{ - defaultApps = JSON.parse(json); - defaultApps = defaultApps.map( appid => appJSON.find(app=>app.id==appid) ); - if (defaultApps.some(x=>x===undefined)) - throw "Not all apps found"; - appCount = defaultApps.length; - return showPrompt("Install Defaults","Remove everything and install favourite apps?"); - }).then(() => { - return Comms.removeAllApps(); - }).then(()=>{ - Progress.hide({sticky:true}); - appsInstalled = []; - showToast(`Existing apps removed. Installing ${appCount} apps...`); - return new Promise((resolve,reject) => { - function upload() { - var app = defaultApps.shift(); - if (app===undefined) return resolve(); - Progress.show({title:`${app.name} (${appCount-defaultApps.length}/${appCount})`,sticky:true}); - Comms.uploadApp(app,"skip_reset").then((appJSON) => { - Progress.hide({sticky:true}); - if (appJSON) appsInstalled.push(appJSON); - showToast(`(${appCount-defaultApps.length}/${appCount}) ${app.name} Uploaded`); - upload(); - }).catch(function() { - Progress.hide({sticky:true}); - reject(); - }); - } - upload(); - }); - }).then(()=>{ - return Comms.setTime(); - }).then(()=>{ - showToast("Favourites apps successfully installed!","success"); - return getInstalledApps(true); - }).catch(err=>{ + var favApps = getAppFavourites(); + installMultipleApps(favApps, "favourite").catch(err=>{ Progress.hide({sticky:true}); showToast("App Install failed, "+err,"error"); }); diff --git a/js/utils.js b/js/utils.js index f4670da3c..53eeb1868 100644 --- a/js/utils.js +++ b/js/utils.js @@ -79,16 +79,3 @@ function getVersionInfo(appListing, appInstalled) { canUpdate : canUpdate } } - -const asyncLocalStorage = { - setItem: function (key, value) { - return Promise.resolve().then(function () { - localStorage.setItem(key, value); - }); - }, - getItem: function (key) { - return Promise.resolve().then(function () { - return localStorage.getItem(key); - }); - } -}; From e93a9125e4a5999f189364d5860e6ce0546802e3 Mon Sep 17 00:00:00 2001 From: Dimitri Gigot Date: Thu, 23 Apr 2020 15:53:51 +0000 Subject: [PATCH 156/878] put toucher.json correctly in the apps.json --- apps.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index ad5b20820..6d67d8b40 100644 --- a/apps.json +++ b/apps.json @@ -1098,10 +1098,12 @@ "description": "Touch enable left to right launcher.", "tags": "tool,system,launcher", "type":"launch", + "data": [ + {"name":"toucher.json"} + ], "storage": [ {"name":"toucher.app.js","url":"app.js"}, - {"name":"toucher.settings.js","url":"settings.js"}, - {"name":"toucher.json"} + {"name":"toucher.settings.js","url":"settings.js"} ], "sortorder" : -10 }, From 4441f3055cf5db49660e2b5ec07e78b1ba0ca161 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Thu, 23 Apr 2020 19:05:22 +0200 Subject: [PATCH 157/878] Added local and support for 12h clock --- apps/rclock/rclock.app.js | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/apps/rclock/rclock.app.js b/apps/rclock/rclock.app.js index bd8395116..a8debe282 100644 --- a/apps/rclock/rclock.app.js +++ b/apps/rclock/rclock.app.js @@ -4,6 +4,8 @@ var hours; var date; var first = true; + var locale = require('locale'); + var _12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||false; const screen = { width: g.getWidth(), @@ -41,17 +43,7 @@ }; const dateStr = function (date) { - day = date.getDate(); - month = date.getMonth(); - year = date.getFullYear(); - if (day < 10) { - day = "0" + day; - } - if (month < 10) { - month = "0" + month; - } - - return year + "-" + month + "-" + day; + return locale.date(new Date(),1); }; const getArcXY = function (centerX, centerY, radius, angle) { @@ -133,9 +125,22 @@ //Write the time as configured in the settings hours = currentTime.getHours(); + if(_12hour && hours>13) { + hours=hours-12; + } + + var medidian=locale.medidian(new Date()); + var timestr; + + if(medidian.length>0) { + timestr=hour+" "+medidian; + } else { + timestr=hour; + } + g.setColor(settings.time.color); g.setFont(settings.time.font, settings.time.size); - g.drawString(hours, settings.time.center, settings.time.middle); + g.drawString(timestr, settings.time.center, settings.time.middle); //Write the date as configured in the settings g.setColor(settings.date.color); From 9ce908761a2d826f801e8289123ad195bfce8d3f Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Thu, 23 Apr 2020 19:09:31 +0200 Subject: [PATCH 158/878] Updated changelog --- apps/rclock/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/rclock/ChangeLog b/apps/rclock/ChangeLog index a8f708a0a..23b1a6e87 100644 --- a/apps/rclock/ChangeLog +++ b/apps/rclock/ChangeLog @@ -1 +1,2 @@ 0.01: First published version of app +0.02: Added support for locale and 12H clock \ No newline at end of file From 0874fb698a882b22fa473a4b59d7fa7acf36555b Mon Sep 17 00:00:00 2001 From: bengwalker <63957296+bengwalker@users.noreply.github.com> Date: Thu, 23 Apr 2020 19:14:18 +0200 Subject: [PATCH 159/878] Update README.md --- apps/metronome/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/metronome/README.md b/apps/metronome/README.md index aab2d5a3f..1bb9a893c 100644 --- a/apps/metronome/README.md +++ b/apps/metronome/README.md @@ -11,4 +11,4 @@ This metronome makes your watch blink and vibrate with a given rate. ## Attributions -"Icon made by Roundicons from www.flaticon.com" \ No newline at end of file +Icon made by Roundicons from www.flaticon.com From 5c3e5ff2eeb7b7e396ef5193f9a911c24329bce0 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Thu, 23 Apr 2020 19:35:18 +0200 Subject: [PATCH 160/878] Fixing so that hour is shown right --- apps/rclock/rclock.app.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/rclock/rclock.app.js b/apps/rclock/rclock.app.js index a8debe282..15bc3caf0 100644 --- a/apps/rclock/rclock.app.js +++ b/apps/rclock/rclock.app.js @@ -129,13 +129,20 @@ hours=hours-12; } - var medidian=locale.medidian(new Date()); + var meridian; + + if (typeof locale.meridian === "function") { + meridian=locale.meridian(new Date()); + } else { + meridian=""; + } + var timestr; - if(medidian.length>0) { - timestr=hour+" "+medidian; + if(meridian.length>0 && _12hour) { + timestr=hours+" "+meridian; } else { - timestr=hour; + timestr=hours; } g.setColor(settings.time.color); From 43ae16f1c0154024ececda3c1786483a911b4bdb Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Thu, 23 Apr 2020 19:43:48 +0200 Subject: [PATCH 161/878] Clean up code format --- apps/rclock/rclock.app.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/apps/rclock/rclock.app.js b/apps/rclock/rclock.app.js index 15bc3caf0..4e63fe36a 100644 --- a/apps/rclock/rclock.app.js +++ b/apps/rclock/rclock.app.js @@ -5,7 +5,7 @@ var date; var first = true; var locale = require('locale'); - var _12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||false; + var _12hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"] || false; const screen = { width: g.getWidth(), @@ -43,7 +43,7 @@ }; const dateStr = function (date) { - return locale.date(new Date(),1); + return locale.date(new Date(), 1); }; const getArcXY = function (centerX, centerY, radius, angle) { @@ -64,7 +64,7 @@ //g.setPixel(r[0],r[1]); g.drawLine(r1[0], r1[1], r2[0], r2[1]); g.setColor('#333333'); - g.drawCircle(settings.circle.middle, settings.circle.center, rad - settings.circle.width-4) + g.drawCircle(settings.circle.middle, settings.circle.center, rad - settings.circle.width - 4) }; const drawSecArc = function (sections, color) { @@ -76,7 +76,7 @@ //g.setPixel(r[0],r[1]); g.drawLine(r1[0], r1[1], r2[0], r2[1]); g.setColor('#333333'); - g.drawCircle(settings.circle.middle, settings.circle.center, rad - settings.circle.width-4) + g.drawCircle(settings.circle.middle, settings.circle.center, rad - settings.circle.width - 4) }; const drawClock = function () { @@ -96,7 +96,7 @@ } first = false; } - + // Reset seconds if (seconds == 59) { g.setColor('#000000'); @@ -120,29 +120,29 @@ //Update seconds when needed if (seconds != currentTime.getSeconds()) { seconds = currentTime.getSeconds(); - drawSecArc(seconds, settings.circle.colorsec); + drawSecArc(seconds, settings.circle.colorsec); } //Write the time as configured in the settings hours = currentTime.getHours(); - if(_12hour && hours>13) { - hours=hours-12; + if (_12hour && hours > 13) { + hours = hours - 12; } var meridian; - if (typeof locale.meridian === "function") { - meridian=locale.meridian(new Date()); + if (typeof locale.meridian === "function") { + meridian = locale.meridian(new Date()); } else { - meridian=""; + meridian = ""; } var timestr; - if(meridian.length>0 && _12hour) { - timestr=hours+" "+meridian; + if (meridian.length > 0 && _12hour) { + timestr = hours + " " + meridian; } else { - timestr=hours; + timestr = hours; } g.setColor(settings.time.color); @@ -161,7 +161,7 @@ // clean app screen g.clear(); - g.setFontAlign( 0, 0, 0); + g.setFontAlign(0, 0, 0); Bangle.loadWidgets(); Bangle.drawWidgets(); From a7305dc947ecebd275874941c35d3510667290c8 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Thu, 23 Apr 2020 21:31:12 +0200 Subject: [PATCH 162/878] First atempt to HR indication --- apps/rclock/rclock.app.js | 96 +++++++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 18 deletions(-) diff --git a/apps/rclock/rclock.app.js b/apps/rclock/rclock.app.js index bd8395116..bbb74205d 100644 --- a/apps/rclock/rclock.app.js +++ b/apps/rclock/rclock.app.js @@ -4,6 +4,14 @@ var hours; var date; var first = true; + var locale = require('locale'); + var _12hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"] || false; + + //HR variables + var color="#FF0000"; + var id=0; + var size=10; + var grow=true; const screen = { width: g.getWidth(), @@ -41,17 +49,7 @@ }; const dateStr = function (date) { - day = date.getDate(); - month = date.getMonth(); - year = date.getFullYear(); - if (day < 10) { - day = "0" + day; - } - if (month < 10) { - month = "0" + month; - } - - return year + "-" + month + "-" + day; + return locale.date(new Date(), 1); }; const getArcXY = function (centerX, centerY, radius, angle) { @@ -72,7 +70,7 @@ //g.setPixel(r[0],r[1]); g.drawLine(r1[0], r1[1], r2[0], r2[1]); g.setColor('#333333'); - g.drawCircle(settings.circle.middle, settings.circle.center, rad - settings.circle.width-4) + g.drawCircle(settings.circle.middle, settings.circle.center, rad - settings.circle.width - 4) }; const drawSecArc = function (sections, color) { @@ -84,7 +82,7 @@ //g.setPixel(r[0],r[1]); g.drawLine(r1[0], r1[1], r2[0], r2[1]); g.setColor('#333333'); - g.drawCircle(settings.circle.middle, settings.circle.center, rad - settings.circle.width-4) + g.drawCircle(settings.circle.middle, settings.circle.center, rad - settings.circle.width - 4) }; const drawClock = function () { @@ -104,7 +102,7 @@ } first = false; } - + // Reset seconds if (seconds == 59) { g.setColor('#000000'); @@ -128,14 +126,34 @@ //Update seconds when needed if (seconds != currentTime.getSeconds()) { seconds = currentTime.getSeconds(); - drawSecArc(seconds, settings.circle.colorsec); + drawSecArc(seconds, settings.circle.colorsec); } //Write the time as configured in the settings hours = currentTime.getHours(); + if (_12hour && hours > 13) { + hours = hours - 12; + } + + var meridian; + + if (typeof locale.meridian === "function") { + meridian = locale.meridian(new Date()); + } else { + meridian = ""; + } + + var timestr; + + if (meridian.length > 0 && _12hour) { + timestr = hours + " " + meridian; + } else { + timestr = hours; + } + g.setColor(settings.time.color); g.setFont(settings.time.font, settings.time.size); - g.drawString(hours, settings.time.center, settings.time.middle); + g.drawString(timestr, settings.time.center, settings.time.middle); //Write the date as configured in the settings g.setColor(settings.date.color); @@ -147,19 +165,61 @@ if (on) drawClock(); }); + +//setInterval for HR visualisation + const newBeats = function (hr) { + if (id != 0) { + changeInterval(id, 6e3 / hr.bpm); + } else { + id = setInterval(drawHR, 6e3 / hr.bpm); + } + }; + +//visualize HR with circles pulsating + const drawHR = function (hr) { + if (grow && size < 12) { + size++; + } + + if (!grow && size > 3) { + size--; + } + + if (size == 12 || size == 3) { + grow = !grow; + } + + if (grow) { + color = "#f0af00"; + g.setColor(color); + g.fillCircle(settings.circle.center, settings.circle.middle, size); + } else { + color = "#000000"; + g.setColor(color); + g.drawCircle(settings.circle.center, settings.circle.middle, size); + } + print(size); + }; + // clean app screen g.clear(); - g.setFontAlign( 0, 0, 0); + g.setFontAlign(0, 0, 0); Bangle.loadWidgets(); Bangle.drawWidgets(); // refesh every 30 sec setInterval(drawClock, 1E3); + //start HR monitor and draw heart rate + Bangle.setHRMPower(1); + Bangle.on('HRM', function (d) { + newBeats(d); + }); + // draw now drawClock(); // Show launcher when middle button pressed setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); -} \ No newline at end of file +} \ No newline at end of file From e9509ca74fbda81e9df819fe2a2b4e417f81ca92 Mon Sep 17 00:00:00 2001 From: Fredrik Lautrup Date: Fri, 24 Apr 2020 07:33:16 +0200 Subject: [PATCH 163/878] Updated change log --- apps/rclock/ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/rclock/ChangeLog b/apps/rclock/ChangeLog index a8f708a0a..d3c24cd8e 100644 --- a/apps/rclock/ChangeLog +++ b/apps/rclock/ChangeLog @@ -1 +1,3 @@ 0.01: First published version of app +0.02: Added support for locale and 12H clock +0.03: Added HR indication to clock \ No newline at end of file From 1223184ee027e66aad9be82976d89e6eb1f3658c Mon Sep 17 00:00:00 2001 From: Amos Blanton Date: Sat, 25 Apr 2020 12:11:07 +0200 Subject: [PATCH 164/878] Add imprecise word clock. --- apps.json | 13 +++ apps/impwclock/clock-impword-icon.js | 1 + apps/impwclock/clock-impword.js | 160 +++++++++++++++++++++++++++ apps/impwclock/clock-impword.png | Bin 0 -> 10763 bytes 4 files changed, 174 insertions(+) create mode 100644 apps/impwclock/clock-impword-icon.js create mode 100644 apps/impwclock/clock-impword.js create mode 100644 apps/impwclock/clock-impword.png diff --git a/apps.json b/apps.json index 6d67d8b40..65f321a91 100644 --- a/apps.json +++ b/apps.json @@ -163,6 +163,19 @@ {"name":"wclock.img","url":"clock-word-icon.js","evaluate":true} ] }, + { "id": "impwclock", + "name": "Imprecise Word Clock", + "icon": "clock-impword.png", + "version":"0.01", + "description": "Imprecise word clock for vacations, weekends, and those who never need accurate time.", + "tags": "clock", + "type":"clock", + "allow_emulator":true, + "storage": [ + {"name":"impwclock.app.js","url":"clock-impword.js"}, + {"name":"impwclock.img","url":"clock-impword-icon.js","evaluate":true} + ] + }, { "id": "aclock", "name": "Analog Clock", "icon": "clock-analog.png", diff --git a/apps/impwclock/clock-impword-icon.js b/apps/impwclock/clock-impword-icon.js new file mode 100644 index 000000000..f5ed47f1f --- /dev/null +++ b/apps/impwclock/clock-impword-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkEIf4A3iIBEn8ggP//8wgX/+cQl8Agc/BQPyCokQgHzmEB+ET+EfmMj+AXCmABBF4MBiIABiEC+PxC4Uwn4NB+QXMBAMzI4UxmYOBC5sfCgIvBgPzF4cfC5BgCFAMPkPwiXzL4cPmMvkAXDPAnzEgMxR4wDCGITl/AH4ApgUQbIICBAgXwBYMD+UAYoP/l4CBiUhd4QXFgIXCh73BfQUfAgIPBC4cQiIACC4cvj4PBC5AuCC48zgcwC4ZHBC5sBCAIEBF5EAC4RgDCQItCPAIXLCoQBBFgM/IoZHER4QA/AH4Anj8wgXzgX/+cQWoPyYQK9Bn/zj/wb4MTCAMf+MDAYMxkfwj8BmYXBmEzCYMf+cDmPzkMvj8zAIM/eoPyC4fy+IXDl8TmfwI4UvmYABAwIXB//xgPwBIIXCgYFBmEP/8fh/yF4sDC4QjBC4RvBF4UPB4JUBL4kAn8ROIJbBC4IIBL4hDBmaPEgBuB+EB+aPCUQUjCALn/AH4A/A")) \ No newline at end of file diff --git a/apps/impwclock/clock-impword.js b/apps/impwclock/clock-impword.js new file mode 100644 index 000000000..dafbbfcf5 --- /dev/null +++ b/apps/impwclock/clock-impword.js @@ -0,0 +1,160 @@ +/* Imprecise Word Clock - A. Blanton +A remix of word clock +by Gordon Williams https://github.com/gfwilliams +- Changes the representation of time to be more general +- Shows accurate digital time when button 1 is pressed +*/ +/* jshint esversion: 6 */ + +const allWords = [ + "AEARLYDN", + "LATEYRZO", + "MORNINGO", + "KMIDDLEN", + "AFTERDAY", + "OFDZTHEC", + "EVENINGR", + "ORMNIGHT" +]; + + +const timeOfDay = { + 0: ["", 0, 0], + 1: ["EARLYMORNING", 10, 11, 12, 13, 14, 02, 12, 22, 32, 42, 52, 62], + 2: ["MORNING", 02, 12, 22, 32, 42, 52, 62], + 3: ["LATEMORNING", 01, 11, 21, 31, 02, 12, 22, 32, 42, 52, 62], + 4: ["MIDDAY", 13, 23, 33, 54, 64, 74], + 5: ["EARLYAFTERNOON", 10, 20, 30, 40, 50, 04, 14, 24, 34, 44, 70, 71, 72, 73], + 6: ["AFTERNOON", 04, 14, 24, 34, 44, 70, 71, 72, 73], + 7: ["LATEAFTERNOON", 01, 11, 21, 31, 04, 14, 24, 34, 44, 70, 71, 72, 73], + 8: ["EARLYEVENING", 10, 20, 30, 40, 50, 06, 16, 26, 36, 46, 56, 66], + 9: ["EVENING", 06, 16, 26, 36, 46, 56, 66], + 10: ["NIGHT", 37, 47, 57, 67, 77], + 11: ["MIDDLEOFTHENIGHT", 32, 33, 34, 35, 36, 37, 50, 51, 54, 55, 56, 73,74,75,76,77 ], +}; + + +// offsets and increments +const xs = 35; +const ys = 31; +const dy = 22; +const dx = 25; + +// font size and color +const fontSize = 3; // "6x8" +const passivColor = 0x3186 /*grey*/ ; +const activeColorNight = 0xF800 /*red*/ ; +const activeColorDay = 0xFFFF /* white */; + +function drawWordClock() { + + + // get time + var t = new Date(); + var h = t.getHours(); + var m = t.getMinutes(); + var time = ("0" + h).substr(-2) + ":" + ("0" + m).substr(-2); + var day = t.getDay(); + + var hidx; + + var activeColor = activeColorDay; + if(h < 7 || h > 19) {activeColor = activeColorNight;} + + g.setFont("6x8",fontSize); + g.setColor(passivColor); + g.setFontAlign(0, -1, 0); + + // draw allWords + var c; + var y = ys; + var x = xs; + allWords.forEach((line) => { + x = xs; + for (c in line) { + g.drawString(line[c], x, y); + x += dx; + } + y += dy; + }); + + + // Switch case isn't good for this in Js apparently so... + if(h < 3){ + // Middle of the Night + hidx = 11; + } + else if (h < 7){ + // Early Morning + hidx = 1; + } + else if (h < 10){ + // Morning + hidx = 2; + } + else if (h < 12){ + // Late Morning + hidx = 3; + } + else if (h < 13){ + // Midday + hidx = 4; + } + else if (h < 14){ + // Early afternoon + hidx = 5; + } + else if (h < 16){ + // Afternoon + hidx = 6; + } + else if (h < 17){ + // Late Afternoon + hidx = 7; + } + else if (h < 19){ + // Early evening + hidx = 8; + } + else if (h < 21){ + // evening + hidx = 9; + } + else if (h < 24){ + // Night + hidx = 10; + } + + // write hour in active color + g.setColor(activeColor); + timeOfDay[hidx][0].split('').forEach((c, pos) => { + x = xs + (timeOfDay[hidx][pos + 1] / 10 | 0) * dx; + y = ys + (timeOfDay[hidx][pos + 1] % 10) * dy; + g.drawString(c, x, y); + }); + + + // Display digital time while button 1 is pressed + if (BTN1.read()){ + g.setColor(activeColor); + g.clearRect(0, 215, 240, 240); + g.drawString(time, 120, 215); + } else { g.clearRect(0, 215, 240, 240); } + +} + +Bangle.on('lcdPower', function(on) { + if (on) drawWordClock(); +}); + +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +setInterval(drawWordClock, 1E4); +drawWordClock(); + +// Show digital time while top button is pressed +setWatch(drawWordClock, BTN1, {repeat:true,edge:"both"}); + +// Show launcher when middle button pressed +setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); diff --git a/apps/impwclock/clock-impword.png b/apps/impwclock/clock-impword.png new file mode 100644 index 0000000000000000000000000000000000000000..e7ed0e8282583a96e7bbd8bc444813af273260f7 GIT binary patch literal 10763 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 JPDHLkV1n2bV Date: Sat, 25 Apr 2020 18:25:13 +0200 Subject: [PATCH 165/878] Add readme. --- apps/impwclock/README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 apps/impwclock/README.md diff --git a/apps/impwclock/README.md b/apps/impwclock/README.md new file mode 100644 index 000000000..30e42c95e --- /dev/null +++ b/apps/impwclock/README.md @@ -0,0 +1,4 @@ +# Imprecise Word Clock + +This clock tells time in very rough approximation, as in "Late morning" or "Early afternoon." Good for vacations and weekends. Press button 1 to see the time in accurate, digital form. But do you really need to know the exact time? + From 152b0e617b9b852058aee788726da41fb7a0abe3 Mon Sep 17 00:00:00 2001 From: Ignas Bukys Date: Sat, 25 Apr 2020 23:02:10 +0300 Subject: [PATCH 166/878] locale.meridian function does not exists if languages app is not installed --- apps/barclock/clock-bar.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/barclock/clock-bar.js b/apps/barclock/clock-bar.js index da436daee..0f2609298 100644 --- a/apps/barclock/clock-bar.js +++ b/apps/barclock/clock-bar.js @@ -12,7 +12,12 @@ date.setMonth(1, 3) // februari: months are zero-indexed const localized = locale.date(date, true) locale.dayFirst = /3.*2/.test(localized) - locale.hasMeridian = (locale.meridian(date) !== '') + + locale.hasMeridian = false + if(typeof locale.meridian === 'function') { // function does not exists if languages app is not installed + locale.hasMeridian = (locale.meridian(date) !== '') + } + } const screen = { width: g.getWidth(), From cff313e89db2141d060d484cc73d1eba3b125e4b Mon Sep 17 00:00:00 2001 From: Ignas Bukys Date: Sat, 25 Apr 2020 23:05:36 +0300 Subject: [PATCH 167/878] version update --- apps.json | 2 +- apps/barclock/ChangeLog | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 6d67d8b40..e39756b84 100644 --- a/apps.json +++ b/apps.json @@ -1012,7 +1012,7 @@ { "id": "barclock", "name": "Bar Clock", "icon": "clock-bar.png", - "version":"0.04", + "version":"0.05", "description": "A simple digital clock showing seconds as a bar", "tags": "clock", "type":"clock", diff --git a/apps/barclock/ChangeLog b/apps/barclock/ChangeLog index 2e0fd088c..616ee66e9 100644 --- a/apps/barclock/ChangeLog +++ b/apps/barclock/ChangeLog @@ -2,3 +2,4 @@ 0.02: Apply locale, 12-hour setting 0.03: Fix dates drawing over each other at midnight 0.04: Small bugfix +0.05: Clock does not start if app Languages is not installed \ No newline at end of file From 66264ea61c300564f433a87515b6d982e2b9f79c Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Sun, 26 Apr 2020 03:29:45 +0200 Subject: [PATCH 168/878] ballmaze game: Navigate a ball through a maze using the accelerometer --- apps.json | 16 ++ apps/ballmaze/README.md | 15 + apps/ballmaze/app.js | 514 ++++++++++++++++++++++++++++++++++ apps/ballmaze/icon.js | 1 + apps/ballmaze/icon.png | Bin 0 -> 444 bytes apps/ballmaze/maze.png | Bin 0 -> 2850 bytes apps/ballmaze/size_select.png | Bin 0 -> 4409 bytes 7 files changed, 546 insertions(+) create mode 100644 apps/ballmaze/README.md create mode 100644 apps/ballmaze/app.js create mode 100644 apps/ballmaze/icon.js create mode 100644 apps/ballmaze/icon.png create mode 100644 apps/ballmaze/maze.png create mode 100644 apps/ballmaze/size_select.png diff --git a/apps.json b/apps.json index 6d67d8b40..9652b3e19 100644 --- a/apps.json +++ b/apps.json @@ -1482,5 +1482,21 @@ {"name":"pong.app.js","url":"app.js"}, {"name":"pong.img","url":"app-icon.js","evaluate":true} ] + }, + { "id": "ballmaze", + "name": "Ball Maze", + "icon": "icon.png", + "version": "0.01", + "description": "Navigate a ball through a maze by tilting your watch.", + "readme": "README.md", + "tags": "game", + "type": "app", + "storage": [ + {"name": "ballmaze.app.js","url":"app.js"}, + {"name": "ballmaze.img","url":"icon.js","evaluate": true} + ], + "data": [ + {"name": "ballmaze.json"} + ] } ] diff --git a/apps/ballmaze/README.md b/apps/ballmaze/README.md new file mode 100644 index 000000000..22a295686 --- /dev/null +++ b/apps/ballmaze/README.md @@ -0,0 +1,15 @@ +# Ball Maze + +Navigate a ball through a maze by tilting your watch. + +![Screenshot](size_select.png) +![Screenshot](maze.png) + +## Usage + +Select a maze size to begin the game. +Tilt your watch to steer the ball towards the target and advance to the next level. + +## Creator + +Richard de Boer diff --git a/apps/ballmaze/app.js b/apps/ballmaze/app.js new file mode 100644 index 000000000..b249d6494 --- /dev/null +++ b/apps/ballmaze/app.js @@ -0,0 +1,514 @@ +(() => { + let intervalID; + let settings = require("Storage").readJSON("ballmaze.json") || {}; + + // density, elasticity of bounces, "drag coefficient" + const rho = 100, e = 0.3, C = 0.01; + // screen width & height in pixels + const sW = 240, sH = 160; + // gravity constant (lowercase was already taken) + const G = 9.80665; + + // wall bit flags + const TOP = 1<<0, LEFT = 1<<1, BOTTOM = 1<<2, RIGHT = 1<<3, + LINKED = 1<<4; // used in maze generation + + // The play area is 240x160, sizes are the ball radius, so we can use common + // denominators of 120x80 to get square rooms + // Reverse the order to show the easiest on top of the menu + const sizes = [1, 2, 4, 5, 8, 10, 16, 20, 40].reverse(), + // even size 1 actually works, but larger mazes take forever to generate + minSize = 4, defaultSize = 10; + const sizeNames = { + 1: "Insane", 2: "Gigantic", 4: "Enormous", 5: "Huge", 8: "Large", + 10: "Medium", 16: "Small", 20: "Tiny", 40: "Trivial", + }; + + /** + * Draw something to all screen buffers + * @param draw {function} Callback which performs the drawing + */ + function drawAll(draw) { + draw(); + g.flip(); + draw(); + g.flip(); + } + + /** + * Clear all buffers + */ + function clearAll() { + drawAll(() => g.clear()); + } + + // use unbuffered graphics for UI stuff + function showMessage(message, title) { + Bangle.setLCDMode(); + return E.showMessage(message, title); + } + + function showPrompt(prompt, options) { + Bangle.setLCDMode(); + return E.showPrompt(prompt, options); + } + + function showMenu(menu) { + Bangle.setLCDMode(); + return E.showMenu(menu); + } + + const sign = (n) => n<0?-1:1; // we don't really care about zero + + /** + * Play the game, using a ball with radius size + * @param size {number} + */ + function playMaze(size) { + const r = size; + // ball mass, weight, "drag" + // Yes, larger maze = larger ball = heavier ball + // (atm our physics is so oversimplified that mass cancels out though) + const m = rho*(r*r*r), w = G*m, d = C*w; + + // number of columns/rows + const cols = Math.round(sW/(r*2.5)), + rows = Math.round(sH/(r*2.5)); + // width & height of one column/row in pixels + const cW = sW/cols, rH = sH/rows; + + // list of rooms, every room can have one or more wall bits set + // actual layout: 0 1 2 + // 3 4 5 + // this means that for room with index "i": (except edge cases!) + // i-1 = room to the left + // i+1 = room to the right + // i-cols = room above + // i+cols = room below + let rooms = new Uint8Array(rows*cols); + // shortest route from start to finish + let route; + + let x, y, // current position + px, py, ppx, ppy, // previous positions (for erasing old image) + vx, vy; // velocity + + function start() { + // start in top left corner + x = cW/2; + y = rH/2; + vx = vy = 0; + ppx = px = x; + ppy = py = y + + clearWatch(); + generateMaze(); // this shows unbuffered progress messages + if (settings.cheat && r>1) findRoute(); // not enough memory for r==1 :-( + + Bangle.setLCDMode("doublebuffered"); + clearAll(); + drawAll(drawMaze); + intervalID = setInterval(tick, 100); + } + + // Position conversions + // index: index of room in rooms[] + // rowcol: position measured in roomsizes + // xy: position measured in pixels + /** + * Index from RowCol + * @param row {number} + * @param col {number} + * @returns {number} rooms[] index + */ + function iFromRC(row, col) { + return row*cols+col; + } + + /** + * RowCol from index + * @param index {number} + * @returns {(number)[]} [row,column] + */ + function rcFromI(index) { + return [ + Math.floor(index/cols), + index%cols, + ]; + } + + /** + * RowCol from Xy + * @param x {number} + * @param y {number} + * @returns {(number)[]} [row,column] + */ + function rcFromXy(x, y) { + return [ + Math.floor(y/sH*rows), + Math.floor(x/sW*cols), + ]; + } + + /** + * Link another room up + * @param index {number} Dig from already linked room with this index + * @param dir {number} in this direction + * @return {number} index of room we just linked up + */ + function dig(index, dir) { + rooms[index] &= ~dir; + let neighbour; + switch(dir) { + case LEFT: + neighbour = index-1; + rooms[neighbour] &= ~RIGHT; + break; + case RIGHT: + neighbour = index+1; + rooms[neighbour] &= ~LEFT; + break; + case TOP: + neighbour = index-cols; + rooms[neighbour] &= ~BOTTOM; + break; + case BOTTOM: + neighbour = index+cols; + rooms[neighbour] &= ~TOP; + break; + } + rooms[neighbour] |= LINKED; + return neighbour; + } + + /** + * Generate the maze + */ + function generateMaze() { + // Maze generation basically works like this: + // 1. Start with all rooms set to completely walled off and "unlinked" + // 2. Then mark a room as "linked", and add it to the "to do" list + // 3. When the "to do" list is empty, we're done + // 4. pick a random room from the list + // 5. if all adjacent rooms are linked -> remove room from list, goto 3 + // 6. pick a random unlinked adjacent room + // 7. remove the walls between the rooms + // 8. mark the adjacent room as linked and add it to the "to do" list + // 9. go to 4 + let pdotnum = 0; + const title = "Please wait", + message = "Generating maze\n", + showProgress = (done, total) => { + const dotnum = Math.floor(done/total*10); + if (dotnum>pdotnum) { + const dots = ".".repeat(dotnum)+" ".repeat(10-dotnum); + showMessage(message+dots, title); + pdotnum = dotnum; + } + }; + showProgress(0, 100); + // start with all rooms completely walled off + rooms.fill(TOP|LEFT|BOTTOM|RIGHT); + const + // is room at row,col already linked? + linked = (row, col) => !!(rooms[iFromRC(row, col)]&LINKED), + // pick random array element + pickRandom = (arr) => arr[Math.floor(Math.random()*arr.length)]; + // starting with top-right room seems to generate more interesting mazes + rooms[cols] |= LINKED; + let todo = [cols], done = 1; + while(todo.length) { + const index = pickRandom(todo); + const rc = rcFromI(index), + row = rc[0], col = rc[1]; + let sides = []; + if ((col>0) && !linked(row, col-1)) sides.push(LEFT); + if ((col0) && !linked(row-1, col)) sides.push(TOP); + if ((row0 && !(walls&LEFT) && dist[i-1]>d+1) { + dist[i-1] = d+1; + todo.push(i-1); + } + if (row>0 && !(walls&TOP) && dist[i-cols]>d+1) { + dist[i-cols] = d+1; + todo.push(i-cols); + } + if (cold+1) { + dist[i+1] = d+1; + todo.push(i+1); + } + if (rowd+1) { + dist[i+cols] = d+1; + todo.push(i+cols); + } + } + + route = [rooms.length-1]; + while(true) { + const i = route[0], d = dist[i], walls = rooms[i], + rc = rcFromI(i), + row = rc[0], col = rc[1]; + if (i===0) { break; } + if (col0 && !(walls&TOP) && dist[i-cols]0 && !(walls&LEFT) && dist[i-1] { + const rc = rcFromI(i), + row = rc[0], col = rc[1], + x = (col+0.5)*cW, y = (row+0.5)*rH; + g.lineTo(x, y); + }); + } + + /** + * Move the ball + */ + function move() { + const a = Bangle.getAccel(); + const fx = (-a.x*w)-(sign(vx)*d*a.z), fy = (-a.y*w)-(sign(vy)*d*a.z); + vx += fx/m; + vy += fy/m; + const s = Math.ceil(Math.max(Math.abs(vx), Math.abs(vy))); + for(let n = s; n>0; n--) { + x += vx/s; + y += vy/s; + bounce(); + } + if (x>sW-cW+r && y>sH-rH+r) win(); + } + + /** + * Check whether we hit any walls, and if so: Bounce. + * + * Bounce = reverse velocity in bounce direction, multiply with elasticity + * Also apply drag in perpendicular direction ("friction with the wall") + */ + function bounce() { + const row = Math.floor(y/sH*rows), col = Math.floor(x/sW*cols), + i = row*cols+col, walls = rooms[i]; + if (vx<0) { + const left = col*cW+r; + if ((walls&LEFT) && x<=left) { + x += (1+e)*(left-x); + const fy = sign(vy)*d*Math.abs(vx); + vy -= fy/m; + vx = -vx*e; + } + } else { + const right = (col+1)*cW-r; + if ((walls&RIGHT) && x>=right) { + x -= (1+e)*(x-right); + const fy = sign(vy)*d*Math.abs(vx); + vy -= fy/m; + vx = -vx*e; + } + } + if (vy<0) { + const top = row*rH+r; + if ((walls&TOP) && y<=top) { + y += (1+e)*(top-y); + const fx = sign(vx)*d*Math.abs(vy); + vx -= fx/m; + vy = -vy*e; + } + } else { + const bottom = (row+1)*rH-r; + if ((walls&BOTTOM) && y>=bottom) { + y -= (1+e)*(y-bottom); + const fx = sign(vx)*d*Math.abs(vy); + vx -= fx/m; + vy = -vy*e; + } + } + } + + /** + * You reached the bottom-right corner, you win! + */ + function win() { + clearInterval(intervalID); + Bangle.buzz().then(askAgain); + } + + /** + * You solved the maze, try the next one? + */ + function askAgain() { + const nextLevel = (size>minSize)?"next level":"again"; + const nextSize = (size>minSize)?sizes[sizes.indexOf(size)+1]:size; + showPrompt(`Well done!\n\nPlay ${nextLevel}?`, + {"title": "Congratulations!"}) + .then(function(again) { + if (again) { + playMaze(nextSize); + } else { + startGame(); + } + }); + } + + function tick() { + ppx = px; + ppy = py; + px = x; + py = y; + move(); + drawUpdate(); + } + + start(); + } + + /** + * Ask player what size maze they would like to play + */ + function startGame() { + let menu = { + "": { + title: "Select Maze Size", + selected: sizes.indexOf(settings.size || defaultSize), + }, + }; + sizes.filter(s => s>=minSize).forEach(size => { + let name = sizeNames[size]; + if (size { + // remember chosen size + settings.size = size; + require("Storage").write("ballmaze.json", settings); + playMaze(size); + }; + }); + menu["< Exit"] = () => load(); + showMenu(menu); + } + + startGame(); +})(); diff --git a/apps/ballmaze/icon.js b/apps/ballmaze/icon.js new file mode 100644 index 000000000..10b5a502e --- /dev/null +++ b/apps/ballmaze/icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwhC/AH4AU9wAOCw0OC5/gFyowHC+Hs5gACC7HhiMRjwXSCoIADC5wCB4MSkIXDGIoXKiUikQwJC5PhCwIXFGAgXJFwRHEGAnOC5HhC5IwC5gXJIw4XF4AXKFwwXEGAoXCiKlFMAzNCgDpDC4QAKcgZJBC6wADF6kAhgXP5xfEC58SC4iNCC4nhC5McC4S/DC6a9DC4IACC5MhC4XOC5HuLxPMC4PuC5IwHkUeC44ABA4IACFw5cBC5owEkUhjwXPGAyMCC5wxDLgIACC54ADC94AGC7sOCx/gC4owQCwwA/AH4AMA")) diff --git a/apps/ballmaze/icon.png b/apps/ballmaze/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..44697db4b75e49c76f668a4da1275b040f1d6fd7 GIT binary patch literal 444 zcmV;t0Ym4UUAPlroCJC$1Svpf^DXX-r@I8EuYDFP7;1rO2 zQeP^R-1+hGBB5-u_oCr624NNa!kt}*6zh+GX3n<0y z77qV^KI8A&C@o@%1NRV$UR)|ht%%q3{q4zz5FiMJ=Xyj_;3`>vEr zAOGRLg@Rs%ygP%_Ou0Mekl)-Ium z2h$Y%LDzIM<$KYAM%vCa(uZruYsycoDhIUEh?38x4|i0pPN7y2v~XLV)qF2hvoocU z-^k|L2s$mUcVn(3EKzbwYXoEN$y)sby6#WCcip|#ep&mo_x?Wn z`@`PPrvZF#UF}`k6beO`=i_;l?1^_3)+AfbvAGhmgHk+rfiPJ_aLfe?MSGOz=^iKy zUzl`DKJm}(e?Mn!j-shJMNWs2lh5ezPSDi!5E=uY-?}>sHpX>~^yrt7=I2YywPEGT zT$(Iwq57*6uac`C$U3INs|7vx2Zw`#f}C19MW}>piY0&seE%L;WX6s7h+9)m!3qoN z(ja)B2E2`lCjCM*U7}#8C|DE-y=Q!Vh=De4K?D3Gc-P~BgCKMTfG#5RM?ztUw*+^P zaQ6eC0ZlLu(}OkXR+e1F^uOYF17HsY?1JDEZ1&gY+=!ij7LiArZ!*;1VgLXgL?)1p z6;;6xi;2=)<+vbdO8sl--_*Oj6@g&OVmM5Gm7~+@T6H<|F&e5RMKOL=87vH1@P4j^D5GF~tn1oWt_< z*{QVymPwIIO``2!AvJe-p^~MQyD{}Nt`a4V$KHZLZ-l*FJ;b_+ClnPasWy;bY8>QZ4(XgO~11;04$bDW8p$UBM?J#`9L#G4kAY zwX+YoT4c*bk3^K=1^fy8r%bC$xDDt{4-MtB)Ii$FQ zXV_J`saRW2YRO}*`0f$bfSQ?LZ9PvPF~z#ThPj-(4QjdaWsgt7m(dFr3}Vvfs-wSb zsf$6V@RJkITnP&X>7Pnt{Zpf>j#;u~1o{ioHmtScLWHw!H8=ub9dfsrdzpgeCzW}j z{t--!W_NDDq}$}@TtwBf%$sF}xpj$|*g(?Qe4Sf?U|6s`tnN9FT;osWt<6ckoVOD` zxnZ%!A_64+l>>nPaN_L1M5m#%YdiI~fxO$l;|vWN)vDcP_m8QnbWWd2iVX~e2DsS< zw{GTn8-?5yJNLLIuP0cte4U?>FmhMNBN*4KlZPEErE_Tp_`2CZ-g>+zSUGNVH&TIX!e)2tTwz_)< z-IdMQ8>VSc%b*`9!}*z#%$f<+!?un2SvH6w>+Lm%(SZF;IJGRq#{6iD#=_+YaoodlTuOrAbP6FuC* zX3a6aMMMYIPM$S&BHBioznin{#ZzSdY&R1F$_!t{VYAJO7>Inel5(VPV{0YtFlt{+ z!Dhe7Z~z}eFuN!KfMysd!Cv8eMUd%J0mDXuvq92xc{jX;i4yi6RC+m?9xac2xD$&6 zA!DyQ6mXfmmvJ`B+@4IO9>e|Dl2ZB&jK*Tw7Baet8lU@q%FyHf@M?~Jg0gi3qu>b%7 literal 0 HcmV?d00001 diff --git a/apps/ballmaze/size_select.png b/apps/ballmaze/size_select.png new file mode 100644 index 0000000000000000000000000000000000000000..cac278820c92c15dce2a7897279c0299fe50b84a GIT binary patch literal 4409 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 Pg+ToG1^HHalhXbJ%Igu= literal 0 HcmV?d00001 From 615aeef4cdd0b226a432c4b50b1c9f0f916d74b5 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Sun, 26 Apr 2020 05:35:50 +0200 Subject: [PATCH 169/878] ballmaze: also bounce off corners --- apps/ballmaze/app.js | 68 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/apps/ballmaze/app.js b/apps/ballmaze/app.js index b249d6494..cce296f2c 100644 --- a/apps/ballmaze/app.js +++ b/apps/ballmaze/app.js @@ -99,9 +99,8 @@ y = rH/2; vx = vy = 0; ppx = px = x; - ppy = py = y + ppy = py = y; - clearWatch(); generateMaze(); // this shows unbuffered progress messages if (settings.cheat && r>1) findRoute(); // not enough memory for r==1 :-( @@ -395,7 +394,7 @@ y += vy/s; bounce(); } - if (x>sW-cW+r && y>sH-rH+r) win(); + if (x>sW-cW && y>sH-rH) win(); } /** @@ -407,40 +406,79 @@ function bounce() { const row = Math.floor(y/sH*rows), col = Math.floor(x/sW*cols), i = row*cols+col, walls = rooms[i]; + const left = col*cW, + right = (col+1)*cW, + top = row*rH, + bottom = (row+1)*rH; + let bounced = false; if (vx<0) { - const left = col*cW+r; - if ((walls&LEFT) && x<=left) { - x += (1+e)*(left-x); + if ((walls&LEFT) && x<=left+r) { + x += (1+e)*(left+r-x); const fy = sign(vy)*d*Math.abs(vx); vy -= fy/m; vx = -vx*e; + bounced = true; } } else { - const right = (col+1)*cW-r; - if ((walls&RIGHT) && x>=right) { - x -= (1+e)*(x-right); + if ((walls&RIGHT) && x>=right-r) { + x -= (1+e)*(x+r-right); const fy = sign(vy)*d*Math.abs(vx); vy -= fy/m; vx = -vx*e; + bounced = true; } } if (vy<0) { - const top = row*rH+r; - if ((walls&TOP) && y<=top) { - y += (1+e)*(top-y); + if ((walls&TOP) && y<=top+r) { + y += (1+e)*(top+r-y); const fx = sign(vx)*d*Math.abs(vy); vx -= fx/m; vy = -vy*e; + bounced = true; } } else { - const bottom = (row+1)*rH-r; - if ((walls&BOTTOM) && y>=bottom) { - y -= (1+e)*(y-bottom); + if ((walls&BOTTOM) && y>=bottom-r) { + y -= (1+e)*(y+r-bottom); const fx = sign(vx)*d*Math.abs(vy); vx -= fx/m; vy = -vy*e; + bounced = true; } } + if (bounced) return; + let cx, cy; + if ((rooms[i-1]&TOP) || rooms[i-cols]&LEFT) { + if ((x-left)*(x-left)+(y-top)*(y-top)<=r*r) { + cx = left; + cy = top; + } + } + else if ((rooms[i-1]&BOTTOM) || rooms[i+cols]&LEFT) { + if ((x-left)*(x-left)+(bottom-y)*(bottom-y)<=r*r) { + cx = left; + cy = bottom; + } + } + else if ((rooms[i+1]&TOP) || rooms[i-cols]&RIGHT) { + if ((right-x)*(right-x)+(y-top)*(y-top)<=r*r) { + cx = right; + cy = top; + } + } + else if ((rooms[i+1]&BOTTOM) || rooms[i+cols]&RIGHT) { + if ((right-x)*(right-x)+(bottom-y)*(bottom-y)<=r*r) { + cx = right; + cy = bottom; + } + } + if (!cx) return; + let nx = x-cx, ny = y-cy; + const l = Math.sqrt(nx*nx+ny*ny); + nx /= l; + ny /= l; + const p = vx*nx+vy*ny; + vx -= 2*p*nx*e; + vy -= 2*p*ny*e; } /** From a08c0383b4d7dcd2ea61c608385527d03a19268f Mon Sep 17 00:00:00 2001 From: Amos Blanton Date: Sun, 26 Apr 2020 08:45:35 +0200 Subject: [PATCH 170/878] Bug fix for hours in early morning. --- apps/impwclock/clock-impword.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/impwclock/clock-impword.js b/apps/impwclock/clock-impword.js index dafbbfcf5..c54fa7976 100644 --- a/apps/impwclock/clock-impword.js +++ b/apps/impwclock/clock-impword.js @@ -20,7 +20,7 @@ const allWords = [ const timeOfDay = { 0: ["", 0, 0], - 1: ["EARLYMORNING", 10, 11, 12, 13, 14, 02, 12, 22, 32, 42, 52, 62], + 1: ["EARLYMORNING", 10, 20, 30, 40, 50, 02, 12, 22, 32, 42, 52, 62], 2: ["MORNING", 02, 12, 22, 32, 42, 52, 62], 3: ["LATEMORNING", 01, 11, 21, 31, 02, 12, 22, 32, 42, 52, 62], 4: ["MIDDAY", 13, 23, 33, 54, 64, 74], @@ -30,7 +30,7 @@ const timeOfDay = { 8: ["EARLYEVENING", 10, 20, 30, 40, 50, 06, 16, 26, 36, 46, 56, 66], 9: ["EVENING", 06, 16, 26, 36, 46, 56, 66], 10: ["NIGHT", 37, 47, 57, 67, 77], - 11: ["MIDDLEOFTHENIGHT", 32, 33, 34, 35, 36, 37, 50, 51, 54, 55, 56, 73,74,75,76,77 ], + 11: ["MIDDLEOFTHENIGHT", 13, 23, 33, 43, 53, 63, 05, 15, 45, 55, 65, 37,47,57,67,77 ], }; From 02eb4d5c407cdce9a9519b8823499f749e62aa5f Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Sun, 26 Apr 2020 14:59:41 +0200 Subject: [PATCH 171/878] ballmaze: handle broken settings JSON --- apps/ballmaze/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ballmaze/app.js b/apps/ballmaze/app.js index cce296f2c..3e26277b7 100644 --- a/apps/ballmaze/app.js +++ b/apps/ballmaze/app.js @@ -1,6 +1,6 @@ (() => { let intervalID; - let settings = require("Storage").readJSON("ballmaze.json") || {}; + let settings = require("Storage").readJSON("ballmaze.json",true) || {}; // density, elasticity of bounces, "drag coefficient" const rho = 100, e = 0.3, C = 0.01; From dd014d5a268ef3fcbce70e1e51ffd618058ba35c Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 27 Apr 2020 10:35:11 +0200 Subject: [PATCH 172/878] Active Pedometer 0.04 --- apps/activepedom/ChangeLog | 3 ++- apps/activepedom/README.md | 19 ++++++++++--------- apps/activepedom/app.js | 2 +- apps/activepedom/widget.js | 21 +++++++++++---------- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/apps/activepedom/ChangeLog b/apps/activepedom/ChangeLog index c1b9ec011..ca26a648a 100644 --- a/apps/activepedom/ChangeLog +++ b/apps/activepedom/ChangeLog @@ -1,3 +1,4 @@ 0.01: New Widget! 0.02: Distance calculation and display -0.03: Data logging and display \ No newline at end of file +0.03: Data logging and display +0.04: Steps are set to 0 in log on new day \ No newline at end of file diff --git a/apps/activepedom/README.md b/apps/activepedom/README.md index f45297e57..a2a351a12 100644 --- a/apps/activepedom/README.md +++ b/apps/activepedom/README.md @@ -18,7 +18,7 @@ Steps are saved to a datafile every 5 minutes. You can watch a graph using the a * 10600 steps ![](10600.png) -## Features +## Features Widget * Two line display * Can display distance (in km) or steps in each line @@ -32,22 +32,23 @@ Steps are saved to a datafile every 5 minutes. You can watch a graph using the a * Steps are saved to a file and read-in at start (to not lose step progress) * Settings can be changed in Settings - App/widget settings - Active Pedometer +## Features App + +* The app accesses the data stored for the current day +* Timespan is choseable (1h, 4h, 8h, 12h, 16h, 20, 24h), standard is 24h, the whole current day + ## Data storage -* Data is stored to a file +* Data is stored to a file named activepedomYYYYMMDD.data (activepedom20200427.data) +* One file is created for each day * Format: now,stepsCounted,active,stepsTooShort,stepsTooLong,stepsOutsideTime -* now is UNIX timestamp in ms -* You can chose the app to watch a steps graph +* 'now' is UNIX timestamp in ms +* You can use the app to watch a steps graph * You can import the file into Excel * The file does not include a header * You can convert UNIX timestamp to a date in Excel using this formula: =DATUM(1970;1;1)+(LINKS(A2;10)/86400) * You have to format the cell with the formula to a date cell. Example: JJJJ-MM-TT-hh-mm-ss -## App - -* The app accesses the data stored for the current day -* Timespan is choseable (1h, 4h, 8h, 12h, 16h, 20, 24h), standard is 24h, the whole current day - ## Settings * Max time (ms): Maximum time between two steps in milliseconds, steps will not be counted if exceeded. Standard: 1100 diff --git a/apps/activepedom/app.js b/apps/activepedom/app.js index 0a9b3b93f..cc875f371 100644 --- a/apps/activepedom/app.js +++ b/apps/activepedom/app.js @@ -162,4 +162,4 @@ settings = storage.readJSON(SETTINGS_FILE, 1) || {}; drawMenu(); -})(); +})(); \ No newline at end of file diff --git a/apps/activepedom/widget.js b/apps/activepedom/widget.js index c6bd410ce..2ae1b9b62 100644 --- a/apps/activepedom/widget.js +++ b/apps/activepedom/widget.js @@ -33,27 +33,28 @@ function storeData() { now = new Date(); - month = now.getMonth() + 1; - if (month < 10) month = "0" + month; - filename = filename = "activepedom" + now.getFullYear() + month + now.getDate() + ".data"; + month = now.getMonth() + 1; //month is 0-based + if (month < 10) month = "0" + month; //leading 0 + filename = filename = "activepedom" + now.getFullYear() + month + now.getDate() + ".data"; //new file for each day dataFile = s.open(filename,"a"); - if (dataFile) { + if (dataFile) { //check if filen already exists if (dataFile.getLength() == 0) { - stepsToWrite = 0; - } - else { - stepsToWrite = stepsCounted; + //new day, set steps to 0 + stepsCounted = 0; + stepsTooShort = 0; + stepsTooLong = 0; + stepsOutsideTime = 0; } dataFile.write([ now.getTime(), - stepsToWrite, + stepsCounted, active, stepsTooShort, stepsTooLong, stepsOutsideTime, ].join(",")+"\n"); } - dataFile = undefined; + dataFile = undefined; //save memory } //return setting From 7630f1f23e8580735d8b278789cc8b1d7b26dcfe Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 27 Apr 2020 10:35:59 +0200 Subject: [PATCH 173/878] Active Pedometer 0.04 --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 36498423e..f405e14ab 100644 --- a/apps.json +++ b/apps.json @@ -1127,7 +1127,7 @@ "name": "Active Pedometer", "shortName":"Active Pedometer", "icon": "app.png", - "version":"0.03", + "version":"0.04", "description": "Pedometer that filters out arm movement and displays a step goal progress. Steps are saved to a daily file and can be viewed as graph.", "tags": "outdoors,widget", "readme": "README.md", From e3e57267b48cf927d405deba64e70698c1a1f17a Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 27 Apr 2020 11:43:35 +0100 Subject: [PATCH 174/878] new about page pixels --- apps.json | 2 +- apps/about/ChangeLog | 1 + apps/about/app.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 43e7e4b9d..57ceac04d 100644 --- a/apps.json +++ b/apps.json @@ -53,7 +53,7 @@ { "id": "about", "name": "About", "icon": "app.png", - "version":"0.04", + "version":"0.05", "description": "Bangle.js About page - showing software version, stats, and a collaborative mural from the Bangle.js KickStarter backers", "tags": "tool,system", "allow_emulator":true, diff --git a/apps/about/ChangeLog b/apps/about/ChangeLog index 2c81c0537..16aea0610 100644 --- a/apps/about/ChangeLog +++ b/apps/about/ChangeLog @@ -2,3 +2,4 @@ 0.02: Update version checker for new filename type 0.03: Actual pixels as of 5 Mar 2020 0.04: Actual pixels as of 9 Mar 2020 +0.05: Actual pixels as of 27 Apr 2020 diff --git a/apps/about/app.js b/apps/about/app.js index dc7b0cad8..57c85563d 100644 --- a/apps/about/app.js +++ b/apps/about/app.js @@ -29,5 +29,5 @@ g.drawString(NRF.getAddress(),120,232); g.flip(); // Pixel chooser image -g.drawImage(require("heatshrink").decompress(atob("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")),0,135); +g.drawImage(require("heatshrink").decompress(atob("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")),0,135); g.flip(); From 35470a151e99f851360a216290a615bad151211e Mon Sep 17 00:00:00 2001 From: fredericrous Date: Mon, 27 Apr 2020 12:15:30 +0100 Subject: [PATCH 175/878] improve ui, add 2 player local prepare the ground for 2 players bluetooth --- apps.json | 3 +- apps/pong/ChangeLog | 1 + apps/pong/app.js | 288 +++++++++++++++++++++++++++++++++----------- 3 files changed, 218 insertions(+), 74 deletions(-) diff --git a/apps.json b/apps.json index f167acf5d..5708e6d62 100644 --- a/apps.json +++ b/apps.json @@ -1486,11 +1486,12 @@ "name": "Pong", "shortName": "Pong", "icon": "pong.png", - "version": "0.01", + "version": "0.02", "description": "A clone of the Atari game Pong", "tags": "game", "type": "app", "allow_emulator": true, + "readme": "README.md", "storage": [ {"name":"pong.app.js","url":"app.js"}, {"name":"pong.img","url":"app-icon.js","evaluate":true} diff --git a/apps/pong/ChangeLog b/apps/pong/ChangeLog index 5560f00bc..6433ebce4 100644 --- a/apps/pong/ChangeLog +++ b/apps/pong/ChangeLog @@ -1 +1,2 @@ 0.01: New App! +0.02: 2 players local + improve ai diff --git a/apps/pong/app.js b/apps/pong/app.js index 4531b3af8..272eaf2e7 100644 --- a/apps/pong/app.js +++ b/apps/pong/app.js @@ -8,6 +8,7 @@ * - Let's make pong, One Man Army Studios, Youtube * - Pong.js, KanoComputing, Github * - Coding Challenge #67: Pong!, The Coding Train, Youtube + * - Pixl.js Multiplayer Pong, espruino website */ const SCREEN_WIDTH = 240; @@ -15,6 +16,13 @@ const FPS = 16; const MAX_SCORE = 11; let scores = [0, 0]; let aiSpeedRandom = 0; +let winnerMessage = ''; + +const sound = { + ping: () => Bangle.beep(8, 466), + pong: () => Bangle.beep(8, 220), + fall: () => Bangle.beep(16*3, 494).then(_ => Bangle.beep(32*3, 3322)) +}; function Vector(x, y) { this.x = x; @@ -28,12 +36,18 @@ Vector.prototype.add = function (x) { const constrain = (n, low, high) => Math.max(Math.min(n, high), low); const random = (min, max) => Math.random() * (max - min) + min; -const intersects = (circ, rect) => { - var c1 = circ.pos, c2 = {x: circ.pos.x+circ.r, y: circ.pos.y+circ.r}; - var r1 = rect.pos, r2 = {x: rect.pos.x+rect.width*2, y: rect.pos.y+rect.height}; - return !(c1.x > r2.x || c2.x < r1.x || - c1.y > r2.y || c2.y < r1.y); -}; +const intersects = (circ, rect, right) => { + var c = circ.pos; + c.r = circ.r; + if (c.y - c.r < rect.pos.y + rect.height && c.y + c.r > rect.pos.y) { + if (right) { + return c.x + c.r > rect.pos.x - rect.width*2 && c.x < rect.pos.x + rect.width + } else { + return c.x - c.r < rect.pos.x + rect.width*2 && c.x > rect.pos.x - rect.width + } + } + return false; +} ///////////////////////////// Ball ////////////////////////////////////////// @@ -45,12 +59,26 @@ function Ball() { this.reset(); } -Ball.prototype.show = function () { +Ball.prototype.reset = function() { + this.speed = this.originalSpeed; + var x = scores[0] < scores[1] || (scores[0] === 0 && scores[1] === 0) ? -this.speed : this.speed; + var bounceAngle = Math.PI/6; + this.velocity = new Vector(x * Math.cos(bounceAngle), this.speed * -Math.sin(bounceAngle)); + this.pos = new Vector(SCREEN_WIDTH/2, random(0, SCREEN_WIDTH)); + this.ballReturn = 0; +}; +Ball.prototype.restart = function() { + this.reset(); + ai.pos = new Vector(SCREEN_WIDTH - ai.width*2, SCREEN_WIDTH/2 - ai.height/2); + player.pos = new Vector(player.width*2, SCREEN_WIDTH/2 - player.height/2); + this.pos = new Vector(SCREEN_WIDTH/2, SCREEN_WIDTH/2); +}; +Ball.prototype.show = function (invert) { if (this.prevPos != null) { - g.setColor(0); + g.setColor(invert ? -1 : 0); g.fillCircle(this.prevPos.x, this.prevPos.y, this.prevPos.r); } - g.setColor(-1); + g.setColor(invert ? 0 : -1); g.fillCircle(this.pos.x, this.pos.y, this.r); this.prevPos = { x: this.pos.x, @@ -58,55 +86,62 @@ Ball.prototype.show = function () { r: this.r }; }; -Ball.prototype.bouncePlayer = function (multiplyX, multiplyY, player) { +function bounceAngle(playerY, ballY, playerHeight, maxHangle) { + let relativeIntersectY = (playerY + (playerHeight/2)) - ballY; + let normalizedRelativeIntersectionY = relativeIntersectY / (playerHeight/2); + let bounceAngle = normalizedRelativeIntersectionY * maxHangle; + return { x: Math.cos(bounceAngle), y: -Math.sin(bounceAngle) }; +} +Ball.prototype.bouncePlayer = function (directionX, directionY, player) { + this.ballReturn++; this.speed = constrain(this.speed + 2, this.originalSpeed, this.maxSpeed); - var relativeIntersectY = (player.pos.y+(player.height/2)) - this.pos.y; - var normalizedRelativeIntersectionY = (relativeIntersectY/(player.height/2)); var MAX_BOUNCE_ANGLE = 4 * Math.PI/12; - var bounceAngle = normalizedRelativeIntersectionY * MAX_BOUNCE_ANGLE; - this.velocity.x = this.speed * Math.cos(bounceAngle) * multiplyX; - this.velocity.y = this.speed * -Math.sin(bounceAngle) * multiplyY; + var angle = bounceAngle(player.pos.y, this.pos.y, player.height, MAX_BOUNCE_ANGLE) + this.velocity.x = this.speed * angle.x * directionX; + this.velocity.y = this.speed * angle.y * directionY; + this.ballReturn % 2 === 0 ? sound.ping() : sound.pong(); }; -Ball.prototype.bounce = function (multiplyX, multiplyY, player) { +Ball.prototype.bounce = function (directionX, directionY, player) { if (player) - return this.bouncePlayer(multiplyX, multiplyY, player); + return this.bouncePlayer(directionX, directionY, player); - if (multiplyX) { - this.velocity.x = Math.abs(this.velocity.x) * multiplyX; + if (directionX) { + this.velocity.x = Math.abs(this.velocity.x) * directionX; } - if (multiplyY) { - this.velocity.y = Math.abs(this.velocity.y) * multiplyY; + if (directionY) { + this.velocity.y = Math.abs(this.velocity.y) * directionY; } }; -Ball.prototype.checkWallsCollision = function () { +Ball.prototype.fall = function (playerId) { + scores[playerId]++; + if (scores[playerId] >= MAX_SCORE) { + this.restart(); + state = 3; + if (playerId === 1) { + winnerMessage = startOption === 0 ? "AI Wins!" : "Player 2 Wins!"; + } else { + winnerMessage = startOption === 0 ? "You Win!" : "Player 1 Wins!"; + } + } else { + sound.fall(); + this.reset(); + } +}; +Ball.prototype.wallCollision = function () { if (this.pos.y < 0) { this.bounce(0, 1); } else if (this.pos.y > SCREEN_WIDTH) { this.bounce(0, -1); } else if (this.pos.x < 0) { - scores[1]++; - if (scores[1] >= MAX_SCORE) { - this.restart(); - state = 3; - winnerMessage = "AI Wins!"; - } else { - this.reset(); - } + this.fall(1); } else if (this.pos.x > SCREEN_WIDTH) { - scores[0]++; - if (scores[0] >= MAX_SCORE) { - this.restart(); - state = 3; - winnerMessage = "You Win!"; - } else { - this.reset(); - } + this.fall(0); } else { return false; } return true; }; -Ball.prototype.checkPlayerCollision = function (player) { +Ball.prototype.playerCollision = function (player) { if (intersects(this, player)) { if (this.pos.x < SCREEN_WIDTH/2) { this.bounce(1, 1, player); @@ -120,8 +155,8 @@ Ball.prototype.checkPlayerCollision = function (player) { } return false; }; -Ball.prototype.checkCollisions = function () { - return this.checkWallsCollision() || this.checkPlayerCollision(player) || this.checkPlayerCollision(ai); +Ball.prototype.collisions = function () { + return this.wallCollision() || this.playerCollision(player) || this.playerCollision(ai); }; Ball.prototype.updatePosition = function () { var elapsed = new Date().getTime() - this.lastUpdate; @@ -132,31 +167,20 @@ Ball.prototype.updatePosition = function () { Ball.prototype.update = function () { this.updatePosition(); this.lastUpdate = new Date().getTime(); - this.checkCollisions(); -}; -Ball.prototype.reset = function() { - this.speed = this.originalSpeed; - var x = scores[0] < scores[1] || (scores[0] === 0 && scores[1] === 0) ? -this.speed : this.speed; - var bounceAngle = Math.PI/6; - this.velocity = new Vector(x * Math.cos(bounceAngle), this.speed * -Math.sin(bounceAngle)); - this.pos = new Vector(SCREEN_WIDTH/2, random(0, SCREEN_WIDTH)); -}; -Ball.prototype.restart = function() { - ai.pos = new Vector(SCREEN_WIDTH - ai.width*2, SCREEN_WIDTH/2 - ai.height/2); - player.pos = new Vector(player.width*2, SCREEN_WIDTH/2 - player.height/2); - this.pos = new Vector(SCREEN_WIDTH/2, SCREEN_WIDTH/2); + this.collisions(); }; //////////////////////////// Player ///////////////////////////////////////// -function Player() { +function Player(right) { this.width = 4; this.height = 30; - this.pos = new Vector(this.width*2, SCREEN_WIDTH/2 - this.height/2); + this.pos = new Vector(right ? SCREEN_WIDTH-this.width : this.width, SCREEN_WIDTH/2 - this.height/2); this.acc = new Vector(0, 0); this.speed = 15; this.maxSpeed = 25; this.prevPos = null; + this.right = right; } Player.prototype.show = function () { if (this.prevPos != null) { @@ -196,11 +220,14 @@ function AI() { AI.prototype = Object.create(Player.prototype); AI.prototype.constructor = Player; AI.prototype.update = function () { - var y = ball.pos.y - (this.height/2 * aiSpeedRandom); - var yConstrained = constrain(y, 0, SCREEN_WIDTH-this.height); + var y = ball.pos.y - this.height/2; + var randomizedY = ball.ballReturn < 3 ? y : y + (aiSpeedRandom * this.height/2); + var yConstrained = constrain(randomizedY, 0, SCREEN_WIDTH-this.height); this.pos = new Vector(this.pos.x, yConstrained); }; +/////////////////////////////// Scenes //////////////////////////////////////// + function net() { var dashSize = 5; for (let y = dashSize/2; y < SCREEN_WIDTH; y += dashSize*2) { @@ -210,12 +237,6 @@ function net() { } } -var player = new Player(); -var ai = new AI(); -var ball = new Ball(); -var state = 0; -var prevScores = [0, 0]; - function drawScores() { let x1 = SCREEN_WIDTH/4-5; let x2 = SCREEN_WIDTH*3/4-5; @@ -233,10 +254,80 @@ function drawScores() { function drawGameOver() { g.setFont("Vector", 20); - g.drawString(winnerMessage, 75, SCREEN_WIDTH/2 - 10); + g.drawString(winnerMessage, startOption === 0 ? 55 : 75, SCREEN_WIDTH/2 - 10); } -function draw() { +function showControls(hide) { + g.setColor(hide ? 0 : -1); + g.setFont("Vector", 8); + var topArrowString = ` + ######## + ## + ## ## + ### ## + ### ## + ### +## +`; + + var arrows = [Graphics.createImage(topArrowString), Graphics.createImage(` + ## + ## +#################### + ## + ## +`), Graphics.createImage(topArrowString.split('\n').reverse().join('\n')) + ]; + + g.drawString('UP', 170, 50); + g.drawImage(arrows[0], 200, 40); + g.drawString('DOWN', 156, 120); + g.drawImage(arrows[1], 200, 120); + g.drawString('START', 152, 190); + g.drawImage(arrows[2], 200, 200); +} + +function drawStartScreen(hide) { + g.setColor(hide ? 0 : -1); + g.setFont("Vector", 10); + g.drawString("1 PLAYER", 95, 80); + g.drawString("2 PLAYERS", 95, 110); + + const ball1 = new Ball(); + ball1.prevPos = null; + ball1.pos = new Vector(87, 86); + ball1.show(hide || !(startOption === 0)); + + const ball2 = new Ball(); + ball2.prevPos = null; + ball2.pos = new Vector(87, 116); + ball2.show(hide || !(startOption === 1)); +} + +function drawStartTimer(count, callback) { + setTimeout(_ => { + player.show(); + ai.show(); + net(); + g.setColor(0); + g.fillRect(117-7, 115-7, 117+14, 115+14); + if (count >= 0) { + g.setFont("Vector", 10); + g.drawString(count+1, 115, 115); + g.setColor(-1); + g.drawString(count === 0 ? 'Go!' : count, 115 - (count === 0 ? 4: 0), 115); + drawStartTimer(count - 1, callback); + } else { + g.setColor(0); + g.fillRect(117-7, 115-7, 117+14, 115+14); + callback(); + } + }, 800); +} + +//////////////////////////////// Main ///////////////////////////////////////// + +function onFrame() { if (state === 1) { ball.update(); player.update(); @@ -261,22 +352,73 @@ function draw() { drawScores(); } +function startThatGame() { + player.show(); + ai.show(); + net(); + drawScores(); + drawStartTimer(3, () => setInterval(onFrame, 1000 / FPS)); +} + +var player = new Player(); +var ai; +var ball = new Ball(); +var state = 0; +var prevScores = [0, 0]; +var playerBle = null; +var startOption = 0; + g.clear(); g.setColor(0); g.fillRect(0,0,240,240); +showControls(); +setTimeout(() => { + showControls(true); + drawStartScreen(); +}, 2000); -setInterval(draw, 1000 / FPS); +////////////////////////////// Controls /////////////////////////////////////// -setWatch(o => o.state ? player.up() : player.stop(), BTN1, {repeat: true, edge: 'both'}); -setWatch(o => o.state ? player.down() : player.stop(), BTN3, {repeat: true, edge: 'both'}); -//setWatch(o => o.state ? player.down() : player.stop(), BTN5, {repeat: true, edge: 'both'}); +setWatch(o => { + if (state === 0) { + if (o.state) { + startOption = startOption === 0 ? startOption : startOption - 1; + drawStartScreen(); + } + } else o.state ? player.up() : player.stop(); +}, BTN1, {repeat: true, edge: 'both'}); +setWatch(o => { + if (state === 0) { + if (o.state) { + startOption = startOption === 1 ? startOption : startOption + 1; + drawStartScreen(); + } + } else o.state ? player.down() : player.stop(); +}, BTN2, {repeat: true, edge: 'both'}); setWatch(o => { state++; + clearInterval(); if (state >= 2) { - ball.restart(); g.setColor(0); - g.fillRect(0,0,240,240); + g.fillRect(0, 0, 240, 240); + ball.show(true); scores = [0, 0]; + playerBle = null; + ball = new Ball(); state = 1; + startThatGame(); + } else { + drawStartScreen(true); + showControls(true); + if (startOption === 1) { + ai = new Player(true); + startThatGame(); + } else { + ai = new AI(); + startThatGame(); + } } -}, BTN2, {repeat: true}); +}, BTN3, {repeat: true}); + +setWatch(o => startOption === 1 && (o.state ? ai.up() : ai.stop()), BTN4, {repeat: true, edge: 'both'}); +setWatch(o => startOption === 1 && (o.state ? ai.down() : ai.stop()), BTN5, {repeat: true, edge: 'both'}); From e03d33edc10fef8a720e0f51744d8608f0a4d8e7 Mon Sep 17 00:00:00 2001 From: fredericrous Date: Mon, 27 Apr 2020 14:13:26 +0100 Subject: [PATCH 176/878] add readme, remove impurity --- apps/pong/README.md | 28 ++++++++++++++++++++++++++++ apps/pong/app.js | 8 ++++---- 2 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 apps/pong/README.md diff --git a/apps/pong/README.md b/apps/pong/README.md new file mode 100644 index 000000000..ea4939539 --- /dev/null +++ b/apps/pong/README.md @@ -0,0 +1,28 @@ +# Pong + +A clone of the Atari game Pong + + + +## Features + +- Play against a dumb AI +- Play local Multiplayer against your friends + +## Controls + +Player's controls: +- UP: BTN1 +- DOWN: BTN2 +long press to move faster + +Restart a game: +- RESET: BTN3 + +Buttons for player 2: +- UP: BTN4 +- DOWN: BTN5 + +## Creator + + diff --git a/apps/pong/app.js b/apps/pong/app.js index 272eaf2e7..ba34d60b5 100644 --- a/apps/pong/app.js +++ b/apps/pong/app.js @@ -38,12 +38,12 @@ const constrain = (n, low, high) => Math.max(Math.min(n, high), low); const random = (min, max) => Math.random() * (max - min) + min; const intersects = (circ, rect, right) => { var c = circ.pos; - c.r = circ.r; - if (c.y - c.r < rect.pos.y + rect.height && c.y + c.r > rect.pos.y) { + var r = circ.r; + if (c.y - r < rect.pos.y + rect.height && c.y + r > rect.pos.y) { if (right) { - return c.x + c.r > rect.pos.x - rect.width*2 && c.x < rect.pos.x + rect.width + return c.x + r > rect.pos.x - rect.width*2 && c.x < rect.pos.x + rect.width } else { - return c.x - c.r < rect.pos.x + rect.width*2 && c.x > rect.pos.x - rect.width + return c.x - r < rect.pos.x + rect.width*2 && c.x > rect.pos.x - rect.width } } return false; From 727d7a1452f4ed87952e7b4293cbca4275bca553 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 27 Apr 2020 16:12:13 +0100 Subject: [PATCH 177/878] Online minification test --- index.html | 1 + js/appinfo.js | 10 + js/espruinotools.js | 33208 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 33219 insertions(+) create mode 100644 js/espruinotools.js diff --git a/index.html b/index.html index 3c8b440e4..c13bc0b36 100644 --- a/index.html +++ b/index.html @@ -156,6 +156,7 @@ + diff --git a/js/appinfo.js b/js/appinfo.js index 9fff7c92a..e5e50aa5c 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -11,6 +11,16 @@ var AppInfo = { return Promise.resolve(storageFile); else if (storageFile.url) return fileGetter(`apps/${app.id}/${storageFile.url}`).then(content => { + if (storageFile.url.endsWith(".js") && !storageFile.url.endsWith(".min.js")) { // if original file ends in '.js'... + return Espruino.transform(content, { + SET_TIME_ON_WRITE : false, + //PRETOKENISE : true, // pretokenise still has an issue with number passing + MINIFICATION_LEVEL : "ESPRIMA", + builtinModules : "Flash,Storage,heatshrink,tensorflow,locale" + }); + } else + return content; + }).then(content => { return { name : storageFile.name, content : content, diff --git a/js/espruinotools.js b/js/espruinotools.js new file mode 100644 index 000000000..d40ab7c77 --- /dev/null +++ b/js/espruinotools.js @@ -0,0 +1,33208 @@ +// EspruinoTools (https://github.com/espruino/EspruinoTools) + +if (typeof $ === "undefined") { + var jqReady = []; + var jqShim = { + ready : function(cb) { jqReady.push(cb); }, + css : function() {}, + html : function() {}, + width : function() {}, + height : function() {}, + addClass : function() {}, + removeClass : function() {}, + appendTo : function() { return jqShim; }, + show : function() {}, + hide : function() {}, + }; + var $ = function() { return jqShim; }; +} +/** + Copyright 2014 Gordon Williams (gw@pur3.co.uk) + + This Source Code is subject to the terms of the Mozilla Public + License, v2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + ------------------------------------------------------------------ + Initialisation code + ------------------------------------------------------------------ +**/ +"use strict"; + +var Espruino; + +(function() { + + /** List of processors. These are functions that are called one + * after the other with the data received from the last one. + * + * Common processors are: + * + * sending - sending code to Espruino (no data) + * transformForEspruino - transform code ready to be sent to Espruino + * transformModuleForEspruino({code,name}) + * - transform module code before it's sent to Espruino with Modules.addCached (we only do this if we don't think it's been minified before) + * connected - connected to Espruino (no data) + * disconnected - disconnected from Espruino (no data) + * environmentVar - Board's process.env loaded (object to be saved into Espruino.Env.environmentData) + * boardJSONLoaded - Board's JSON was loaded into environmentVar + * getModule - Called with data={moduleName:"foo", moduleCode:undefined} - moduleCode should be filled in if the module can be found + * getURL - Called with data={url:"http://....", data:undefined) - data should be filled in if the URL is handled (See Espruino.Core.Utils.getURL to use this) + * terminalClear - terminal has been cleared + * terminalPrompt - we've received a '>' character (eg, `>` or `debug>`). The argument is the current line's contents. + * terminalNewLine - When we get a new line on the terminal, this gets called with the last line's contents + * debugMode - called with true or false when debug mode is entered or left + * editorHover - called with { node : htmlNode, showTooltip : function(htmlNode) } when something is hovered over + * notification - called with { mdg, type:"success","error"/"warning"/"info" } + **/ + var processors = {}; + + function init() { + + Espruino.Core.Config.loadConfiguration(function() { + // Initialise all modules + function initModule(modName, mod) { + console.log("Initialising "+modName); + if (mod.init !== undefined) + mod.init(); + } + + var module; + for (module in Espruino.Core) initModule(module, Espruino.Core[module]); + for (module in Espruino.Plugins) initModule(module, Espruino.Plugins[module]); + + callProcessor("initialised", undefined, function() { + // We need the delay because of background.js's url_handler... + setTimeout(function() { + Espruino.initialised = true; + }, 1000); + }); + }); + } + + // workaround for broken chrome on Mac + if (navigator.userAgent.indexOf("Mac OS X")>=0 && + navigator.userAgent.indexOf("Chrome/33.0.1750")>=0) { + $(document).ready(function() { window.setTimeout(init,100); }); + } else { + $(document).ready(init); + } + + /** Add a processor function of type function(data,callback) */ + function addProcessor(eventType, processor) { + if (processors[eventType]===undefined) + processors[eventType] = []; + processors[eventType].push(processor); + } + + /** Call a processor function */ + function callProcessor(eventType, data, callback) { + var p = processors[eventType]; + // no processors + if (p===undefined || p.length==0) { + if (callback!==undefined) callback(data); + return; + } + // now go through all processors + var n = 0; + var cbCalled = false; + var cb = function(inData) { + if (cbCalled) throw new Error("Internal error in "+eventType+" processor. Callback is called TWICE."); + cbCalled = true; + if (n < p.length) { + cbCalled = false; + p[n++](inData, cb); + } else { + if (callback!==undefined) callback(inData); + } + }; + cb(data); + } + + // ----------------------------------- + Espruino = { + Core : { }, + Plugins : { }, + addProcessor : addProcessor, + callProcessor : callProcessor, + initialised : false, + init : init, // just in case we need to initialise this by hand + }; + + return Espruino; +})(); +Espruino.Core.Notifications = { + success : function(e) { console.log(e); }, + error : function(e) { console.error(e); }, + warning : function(e) { console.warn(e); }, + info : function(e) { console.log(e); }, +}; +Espruino.Core.Status = { + setStatus : function(e,len) { console.log(e); }, + hasProgress : function() { return false; }, + incrementProgress : function(amt) {} +}; +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.acorn = {}))); +}(this, (function (exports) { 'use strict'; + +// Reserved word lists for various dialects of the language + +var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" +}; + +// And the keywords + +var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; + +var keywords = { + 5: ecma5AndLessKeywords, + 6: ecma5AndLessKeywords + " const class extends export import super" +}; + +var keywordRelationalOperator = /^in(stanceof)?$/; + +// ## Character categories + +// Big ugly regular expressions that match characters in the +// whitespace, identifier, and identifier-start categories. These +// are only applied when a character is found to actually have a +// code point above 128. +// Generated by `bin/generate-identifier-regex.js`. + +var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; +var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + +var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); +var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; + +// These are a run-length and offset encoded representation of the +// >0xffff code points that are a valid part of identifiers. The +// offset starts at 0x10000, and each pair of numbers represents an +// offset to the next range, and then a size of the range. They were +// generated by bin/generate-identifier-regex.js + +// eslint-disable-next-line comma-spacing +var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541]; + +// eslint-disable-next-line comma-spacing +var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239]; + +// This has a complexity linear to the value of the code. The +// assumption is that looking up astral identifier characters is +// rare. +function isInAstralSet(code, set) { + var pos = 0x10000; + for (var i = 0; i < set.length; i += 2) { + pos += set[i]; + if (pos > code) { return false } + pos += set[i + 1]; + if (pos >= code) { return true } + } +} + +// Test whether a given character code starts an identifier. + +function isIdentifierStart(code, astral) { + if (code < 65) { return code === 36 } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) +} + +// Test whether a given character is part of an identifier. + +function isIdentifierChar(code, astral) { + if (code < 48) { return code === 36 } + if (code < 58) { return true } + if (code < 65) { return false } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) +} + +// ## Token types + +// The assignment of fine-grained, information-carrying type objects +// allows the tokenizer to store the information it has about a +// token in a way that is very cheap for the parser to look up. + +// All token type variables start with an underscore, to make them +// easy to recognize. + +// The `beforeExpr` property is used to disambiguate between regular +// expressions and divisions. It is set on all token types that can +// be followed by an expression (thus, a slash after them would be a +// regular expression). +// +// The `startsExpr` property is used to check if the token ends a +// `yield` expression. It is set on all token types that either can +// directly start an expression (like a quotation mark) or can +// continue an expression (like the body of a string). +// +// `isLoop` marks a keyword as starting a loop, which is important +// to know when parsing a label, in order to allow or disallow +// continue jumps to that label. + +var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop || null; + this.updateContext = null; +}; + +function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) +} +var beforeExpr = {beforeExpr: true}; +var startsExpr = {startsExpr: true}; + +// Map keyword names to token types. + +var keywords$1 = {}; + +// Succinct definitions of keyword token types +function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name; + return keywords$1[name] = new TokenType(name, options) +} + +var types = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + invalidTemplate: new TokenType("invalidTemplate"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=/===/!==", 6), + relational: binop("/<=/>=", 7), + bitShift: binop("<>/>>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class", startsExpr), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import"), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) +}; + +// Matches a whole line break (where CRLF is considered a single +// line break). Used to count lines. + +var lineBreak = /\r\n?|\n|\u2028|\u2029/; +var lineBreakG = new RegExp(lineBreak.source, "g"); + +function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 +} + +var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + +var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + +var ref = Object.prototype; +var hasOwnProperty = ref.hasOwnProperty; +var toString = ref.toString; + +// Checks if an object has a property. + +function has(obj, propName) { + return hasOwnProperty.call(obj, propName) +} + +var isArray = Array.isArray || (function (obj) { return ( + toString.call(obj) === "[object Array]" +); }); + +// These are used when `options.locations` is on, for the +// `startLoc` and `endLoc` properties. + +var Position = function Position(line, col) { + this.line = line; + this.column = col; +}; + +Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) +}; + +var SourceLocation = function SourceLocation(p, start, end) { + this.start = start; + this.end = end; + if (p.sourceFile !== null) { this.source = p.sourceFile; } +}; + +// The `getLineInfo` function is mostly useful when the +// `locations` option is off (for performance reasons) and you +// want to find the line/column position for a given character +// offset. `input` should be the code string that the offset refers +// into. + +function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur; + var match = lineBreakG.exec(input); + if (match && match.index < offset) { + ++line; + cur = match.index + match[0].length; + } else { + return new Position(line, offset - cur) + } + } +} + +// A second optional argument can be given to further configure +// the parser process. These options are recognized: + +var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must + // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support + // for strict mode, the set of reserved words, and support for + // new syntax features. The default is 7. + ecmaVersion: 7, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // th position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false, + plugins: {} +}; + +// Interpret and default an options object + +function getOptions(opts) { + var options = {}; + + for (var opt in defaultOptions) + { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; } + + if (options.ecmaVersion >= 2015) + { options.ecmaVersion -= 2009; } + + if (options.allowReserved == null) + { options.allowReserved = options.ecmaVersion < 5; } + + if (isArray(options.onToken)) { + var tokens = options.onToken; + options.onToken = function (token) { return tokens.push(token); }; + } + if (isArray(options.onComment)) + { options.onComment = pushComment(options, options.onComment); } + + return options +} + +function pushComment(options, array) { + return function(block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? "Block" : "Line", + value: text, + start: start, + end: end + }; + if (options.locations) + { comment.loc = new SourceLocation(this, startLoc, endLoc); } + if (options.ranges) + { comment.range = [start, end]; } + array.push(comment); + } +} + +// Registered plugins +var plugins = {}; + +function keywordRegexp(words) { + return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") +} + +var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options); + this.sourceFile = options.sourceFile; + this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]); + var reserved = ""; + if (!options.allowReserved) { + for (var v = options.ecmaVersion;; v--) + { if (reserved = reservedWords[v]) { break } } + if (options.sourceType == "module") { reserved += " await"; } + } + this.reservedWords = keywordRegexp(reserved); + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; + this.reservedWordsStrict = keywordRegexp(reservedStrict); + this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind); + this.input = String(input); + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false; + + // Load plugins + this.loadPlugins(options.plugins); + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos; + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; + } else { + this.pos = this.lineStart = 0; + this.curLine = 1; + } + + // Properties of the current token: + // Its type + this.type = types.eof; + // For tokens that include more information than their type, the value + this.value = null; + // Its start and end offset + this.start = this.end = this.pos; + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition(); + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext(); + this.exprAllowed = true; + + // Figure out if it's a module code. + this.inModule = options.sourceType === "module"; + this.strict = this.inModule || this.strictDirective(this.pos); + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1; + + // Flags to track whether we are in a function, a generator, an async function. + this.inFunction = this.inGenerator = this.inAsync = false; + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = 0; + // Labels in scope. + this.labels = []; + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") + { this.skipLineComment(2); } + + // Scope tracking for duplicate variable names (see scope.js) + this.scopeStack = []; + this.enterFunctionScope(); +}; + +// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them +Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; +Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; + +Parser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]); +}; + +Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { + var this$1 = this; + + for (var name in pluginConfigs) { + var plugin = plugins[name]; + if (!plugin) { throw new Error("Plugin '" + name + "' not found") } + plugin(this$1, pluginConfigs[name]); + } +}; + +Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode(); + this.nextToken(); + return this.parseTopLevel(node) +}; + +var pp = Parser.prototype; + +// ## Parser utilities + +var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/; +pp.strictDirective = function(start) { + var this$1 = this; + + for (;;) { + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this$1.input)[0].length; + var match = literal.exec(this$1.input.slice(start)); + if (!match) { return false } + if ((match[1] || match[2]) == "use strict") { return true } + start += match[0].length; + } +}; + +// Predicate that tests whether the next token is of the given +// type, and if yes, consumes it as a side effect. + +pp.eat = function(type) { + if (this.type === type) { + this.next(); + return true + } else { + return false + } +}; + +// Tests whether parsed token is a contextual keyword. + +pp.isContextual = function(name) { + return this.type === types.name && this.value === name && !this.containsEsc +}; + +// Consumes contextual keyword if possible. + +pp.eatContextual = function(name) { + if (!this.isContextual(name)) { return false } + this.next(); + return true +}; + +// Asserts that following token is given contextual keyword. + +pp.expectContextual = function(name) { + if (!this.eatContextual(name)) { this.unexpected(); } +}; + +// Test whether a semicolon can be inserted at the current position. + +pp.canInsertSemicolon = function() { + return this.type === types.eof || + this.type === types.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +}; + +pp.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } + return true + } +}; + +// Consume a semicolon, or, failing that, see if we are allowed to +// pretend that there is a semicolon at this position. + +pp.semicolon = function() { + if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); } +}; + +pp.afterTrailingComma = function(tokType, notNext) { + if (this.type == tokType) { + if (this.options.onTrailingComma) + { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } + if (!notNext) + { this.next(); } + return true + } +}; + +// Expect a token of a given type. If found, consume it, otherwise, +// raise an unexpected token error. + +pp.expect = function(type) { + this.eat(type) || this.unexpected(); +}; + +// Raise an unexpected token error. + +pp.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token"); +}; + +function DestructuringErrors() { + this.shorthandAssign = + this.trailingComma = + this.parenthesizedAssign = + this.parenthesizedBind = + this.doubleProto = + -1; +} + +pp.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) { return } + if (refDestructuringErrors.trailingComma > -1) + { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } + var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; + if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); } +}; + +pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + if (!refDestructuringErrors) { return false } + var shorthandAssign = refDestructuringErrors.shorthandAssign; + var doubleProto = refDestructuringErrors.doubleProto; + if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } + if (shorthandAssign >= 0) + { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } + if (doubleProto >= 0) + { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } +}; + +pp.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } + if (this.awaitPos) + { this.raise(this.awaitPos, "Await expression cannot be a default value"); } +}; + +pp.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + { return this.isSimpleAssignTarget(expr.expression) } + return expr.type === "Identifier" || expr.type === "MemberExpression" +}; + +var pp$1 = Parser.prototype; + +// ### Statement parsing + +// Parse a program. Initializes the parser, reads any number of +// statements, and wraps them in a Program node. Optionally takes a +// `program` argument. If present, the statements will be appended +// to its body instead of creating a new node. + +pp$1.parseTopLevel = function(node) { + var this$1 = this; + + var exports = {}; + if (!node.body) { node.body = []; } + while (this.type !== types.eof) { + var stmt = this$1.parseStatement(true, true, exports); + node.body.push(stmt); + } + this.adaptDirectivePrologue(node.body); + this.next(); + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType; + } + return this.finishNode(node, "Program") +}; + +var loopLabel = {kind: "loop"}; +var switchLabel = {kind: "switch"}; + +pp$1.isLet = function() { + if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + if (nextCh === 91 || nextCh == 123) { return true } // '{' and '[' + if (isIdentifierStart(nextCh, true)) { + var pos = next + 1; + while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; } + var ident = this.input.slice(next, pos); + if (!keywordRelationalOperator.test(ident)) { return true } + } + return false +}; + +// check 'async [no LineTerminator here] function' +// - 'async /*foo*/ function' is OK. +// - 'async /*\n*/ function' is invalid. +pp$1.isAsyncFunction = function() { + if (this.options.ecmaVersion < 8 || !this.isContextual("async")) + { return false } + + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length; + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 == this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) +}; + +// Parse a single statement. +// +// If expecting a statement and finding a slash operator, parse a +// regular expression literal. This is to handle cases like +// `if (foo) /blah/.exec(foo)`, where looking at the previous token +// does not help. + +pp$1.parseStatement = function(declaration, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind; + + if (this.isLet()) { + starttype = types._var; + kind = "let"; + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case types._debugger: return this.parseDebuggerStatement(node) + case types._do: return this.parseDoStatement(node) + case types._for: return this.parseForStatement(node) + case types._function: + if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); } + return this.parseFunctionStatement(node, false) + case types._class: + if (!declaration) { this.unexpected(); } + return this.parseClass(node, true) + case types._if: return this.parseIfStatement(node) + case types._return: return this.parseReturnStatement(node) + case types._switch: return this.parseSwitchStatement(node) + case types._throw: return this.parseThrowStatement(node) + case types._try: return this.parseTryStatement(node) + case types._const: case types._var: + kind = kind || this.value; + if (!declaration && kind != "var") { this.unexpected(); } + return this.parseVarStatement(node, kind) + case types._while: return this.parseWhileStatement(node) + case types._with: return this.parseWithStatement(node) + case types.braceL: return this.parseBlock() + case types.semi: return this.parseEmptyStatement(node) + case types._export: + case types._import: + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } + if (!this.inModule) + { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } + } + return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction()) { + if (!declaration) { this.unexpected(); } + this.next(); + return this.parseFunctionStatement(node, true) + } + + var maybeName = this.value, expr = this.parseExpression(); + if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) + { return this.parseLabeledStatement(node, maybeName, expr) } + else { return this.parseExpressionStatement(node, expr) } + } +}; + +pp$1.parseBreakContinueStatement = function(node, keyword) { + var this$1 = this; + + var isBreak = keyword == "break"; + this.next(); + if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; } + else if (this.type !== types.name) { this.unexpected(); } + else { + node.label = this.parseIdent(); + this.semicolon(); + } + + // Verify that there is an actual destination to break or + // continue to. + var i = 0; + for (; i < this.labels.length; ++i) { + var lab = this$1.labels[i]; + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } + if (node.label && isBreak) { break } + } + } + if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") +}; + +pp$1.parseDebuggerStatement = function(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement") +}; + +pp$1.parseDoStatement = function(node) { + this.next(); + this.labels.push(loopLabel); + node.body = this.parseStatement(false); + this.labels.pop(); + this.expect(types._while); + node.test = this.parseParenExpression(); + if (this.options.ecmaVersion >= 6) + { this.eat(types.semi); } + else + { this.semicolon(); } + return this.finishNode(node, "DoWhileStatement") +}; + +// Disambiguating between a `for` and a `for`/`in` or `for`/`of` +// loop is non-trivial. Basically, we have to parse the init `var` +// statement or expression, disallowing the `in` operator (see +// the second parameter to `parseExpression`), and then check +// whether the next token is `in` or `of`. When there is no init +// part (semicolon immediately after the opening parenthesis), it +// is a regular `for` loop. + +pp$1.parseForStatement = function(node) { + this.next(); + var awaitAt = (this.options.ecmaVersion >= 9 && this.inAsync && this.eatContextual("await")) ? this.lastTokStart : -1; + this.labels.push(loopLabel); + this.enterLexicalScope(); + this.expect(types.parenL); + if (this.type === types.semi) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, null) + } + var isLet = this.isLet(); + if (this.type === types._var || this.type === types._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value; + this.next(); + this.parseVar(init$1, true, kind); + this.finishNode(init$1, "VariableDeclaration"); + if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && + !(kind !== "var" && init$1.declarations[0].init)) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + return this.parseForIn(node, init$1) + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init$1) + } + var refDestructuringErrors = new DestructuringErrors; + var init = this.parseExpression(true, refDestructuringErrors); + if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + this.toAssignable(init, false, refDestructuringErrors); + this.checkLVal(init); + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true); + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) +}; + +pp$1.parseFunctionStatement = function(node, isAsync) { + this.next(); + return this.parseFunction(node, true, false, isAsync) +}; + +pp$1.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement(!this.strict && this.type == types._function); + node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type == types._function) : null; + return this.finishNode(node, "IfStatement") +}; + +pp$1.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + { this.raise(this.start, "'return' outside of function"); } + this.next(); + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; } + else { node.argument = this.parseExpression(); this.semicolon(); } + return this.finishNode(node, "ReturnStatement") +}; + +pp$1.parseSwitchStatement = function(node) { + var this$1 = this; + + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(types.braceL); + this.labels.push(switchLabel); + this.enterLexicalScope(); + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + var cur; + for (var sawDefault = false; this.type != types.braceR;) { + if (this$1.type === types._case || this$1.type === types._default) { + var isCase = this$1.type === types._case; + if (cur) { this$1.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this$1.startNode()); + cur.consequent = []; + this$1.next(); + if (isCase) { + cur.test = this$1.parseExpression(); + } else { + if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); } + sawDefault = true; + cur.test = null; + } + this$1.expect(types.colon); + } else { + if (!cur) { this$1.unexpected(); } + cur.consequent.push(this$1.parseStatement(true)); + } + } + this.exitLexicalScope(); + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.next(); // Closing brace + this.labels.pop(); + return this.finishNode(node, "SwitchStatement") +}; + +pp$1.parseThrowStatement = function(node) { + this.next(); + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + { this.raise(this.lastTokEnd, "Illegal newline after throw"); } + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement") +}; + +// Reused empty array added for node fields that are always empty. + +var empty = []; + +pp$1.parseTryStatement = function(node) { + this.next(); + node.block = this.parseBlock(); + node.handler = null; + if (this.type === types._catch) { + var clause = this.startNode(); + this.next(); + this.expect(types.parenL); + clause.param = this.parseBindingAtom(); + this.enterLexicalScope(); + this.checkLVal(clause.param, "let"); + this.expect(types.parenR); + clause.body = this.parseBlock(false); + this.exitLexicalScope(); + node.handler = this.finishNode(clause, "CatchClause"); + } + node.finalizer = this.eat(types._finally) ? this.parseBlock() : null; + if (!node.handler && !node.finalizer) + { this.raise(node.start, "Missing catch or finally clause"); } + return this.finishNode(node, "TryStatement") +}; + +pp$1.parseVarStatement = function(node, kind) { + this.next(); + this.parseVar(node, false, kind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") +}; + +pp$1.parseWhileStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + this.labels.push(loopLabel); + node.body = this.parseStatement(false); + this.labels.pop(); + return this.finishNode(node, "WhileStatement") +}; + +pp$1.parseWithStatement = function(node) { + if (this.strict) { this.raise(this.start, "'with' in strict mode"); } + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement(false); + return this.finishNode(node, "WithStatement") +}; + +pp$1.parseEmptyStatement = function(node) { + this.next(); + return this.finishNode(node, "EmptyStatement") +}; + +pp$1.parseLabeledStatement = function(node, maybeName, expr) { + var this$1 = this; + + for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1) + { + var label = list[i$1]; + + if (label.name === maybeName) + { this$1.raise(expr.start, "Label '" + maybeName + "' is already declared"); + } } + var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null; + for (var i = this.labels.length - 1; i >= 0; i--) { + var label$1 = this$1.labels[i]; + if (label$1.statementStart == node.start) { + // Update information about previous labels on this node + label$1.statementStart = this$1.start; + label$1.kind = kind; + } else { break } + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); + node.body = this.parseStatement(true); + if (node.body.type == "ClassDeclaration" || + node.body.type == "VariableDeclaration" && node.body.kind != "var" || + node.body.type == "FunctionDeclaration" && (this.strict || node.body.generator)) + { this.raiseRecoverable(node.body.start, "Invalid labeled declaration"); } + this.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement") +}; + +pp$1.parseExpressionStatement = function(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") +}; + +// Parse a semicolon-enclosed block of statements, handling `"use +// strict"` declarations when `allowStrict` is true (used for +// function bodies). + +pp$1.parseBlock = function(createNewLexicalScope) { + var this$1 = this; + if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; + + var node = this.startNode(); + node.body = []; + this.expect(types.braceL); + if (createNewLexicalScope) { + this.enterLexicalScope(); + } + while (!this.eat(types.braceR)) { + var stmt = this$1.parseStatement(true); + node.body.push(stmt); + } + if (createNewLexicalScope) { + this.exitLexicalScope(); + } + return this.finishNode(node, "BlockStatement") +}; + +// Parse a regular `for` loop. The disambiguation code in +// `parseStatement` will already have parsed the init statement or +// expression. + +pp$1.parseFor = function(node, init) { + node.init = init; + this.expect(types.semi); + node.test = this.type === types.semi ? null : this.parseExpression(); + this.expect(types.semi); + node.update = this.type === types.parenR ? null : this.parseExpression(); + this.expect(types.parenR); + this.exitLexicalScope(); + node.body = this.parseStatement(false); + this.labels.pop(); + return this.finishNode(node, "ForStatement") +}; + +// Parse a `for`/`in` and `for`/`of` loop, which are almost +// same from parser's perspective. + +pp$1.parseForIn = function(node, init) { + var type = this.type === types._in ? "ForInStatement" : "ForOfStatement"; + this.next(); + if (type == "ForInStatement") { + if (init.type === "AssignmentPattern" || + (init.type === "VariableDeclaration" && init.declarations[0].init != null && + (this.strict || init.declarations[0].id.type !== "Identifier"))) + { this.raise(init.start, "Invalid assignment in for-in loop head"); } + } + node.left = init; + node.right = type == "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types.parenR); + this.exitLexicalScope(); + node.body = this.parseStatement(false); + this.labels.pop(); + return this.finishNode(node, type) +}; + +// Parse a list of variable declarations. + +pp$1.parseVar = function(node, isFor, kind) { + var this$1 = this; + + node.declarations = []; + node.kind = kind; + for (;;) { + var decl = this$1.startNode(); + this$1.parseVarId(decl, kind); + if (this$1.eat(types.eq)) { + decl.init = this$1.parseMaybeAssign(isFor); + } else if (kind === "const" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { + this$1.unexpected(); + } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === types._in || this$1.isContextual("of")))) { + this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")); + if (!this$1.eat(types.comma)) { break } + } + return node +}; + +pp$1.parseVarId = function(decl, kind) { + decl.id = this.parseBindingAtom(kind); + this.checkLVal(decl.id, kind, false); +}; + +// Parse a function declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) { + this.initFunction(node); + if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) + { node.generator = this.eat(types.star); } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + if (isStatement) { + node.id = isStatement === "nullableID" && this.type != types.name ? null : this.parseIdent(); + if (node.id) { + this.checkLVal(node.id, "var"); + } + } + + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; + this.inGenerator = node.generator; + this.inAsync = node.async; + this.yieldPos = 0; + this.awaitPos = 0; + this.inFunction = true; + this.enterFunctionScope(); + + if (!isStatement) + { node.id = this.type == types.name ? this.parseIdent() : null; } + + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody); + + this.inGenerator = oldInGen; + this.inAsync = oldInAsync; + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.inFunction = oldInFunc; + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +}; + +pp$1.parseFunctionParams = function(node) { + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); +}; + +// Parse a class declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseClass = function(node, isStatement) { + var this$1 = this; + + this.next(); + + this.parseClassId(node, isStatement); + this.parseClassSuper(node); + var classBody = this.startNode(); + var hadConstructor = false; + classBody.body = []; + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + var member = this$1.parseClassMember(classBody); + if (member && member.type === "MethodDefinition" && member.kind === "constructor") { + if (hadConstructor) { this$1.raise(member.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } + } + node.body = this.finishNode(classBody, "ClassBody"); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +}; + +pp$1.parseClassMember = function(classBody) { + var this$1 = this; + + if (this.eat(types.semi)) { return null } + + var method = this.startNode(); + var tryContextual = function (k, noLineBreak) { + if ( noLineBreak === void 0 ) noLineBreak = false; + + var start = this$1.start, startLoc = this$1.startLoc; + if (!this$1.eatContextual(k)) { return false } + if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true } + if (method.key) { this$1.unexpected(); } + method.computed = false; + method.key = this$1.startNodeAt(start, startLoc); + method.key.name = k; + this$1.finishNode(method.key, "Identifier"); + return false + }; + + method.kind = "method"; + method.static = tryContextual("static"); + var isGenerator = this.eat(types.star); + var isAsync = false; + if (!isGenerator) { + if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); + } else if (tryContextual("get")) { + method.kind = "get"; + } else if (tryContextual("set")) { + method.kind = "set"; + } + } + if (!method.key) { this.parsePropertyName(method); } + var key = method.key; + if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || + key.type === "Literal" && key.value === "constructor")) { + if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); } + if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } + if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } + method.kind = "constructor"; + } else if (method.static && key.type === "Identifier" && key.name === "prototype") { + this.raise(key.start, "Classes may not have a static property named prototype"); + } + this.parseClassMethod(classBody, method, isGenerator, isAsync); + if (method.kind === "get" && method.value.params.length !== 0) + { this.raiseRecoverable(method.value.start, "getter should have no params"); } + if (method.kind === "set" && method.value.params.length !== 1) + { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); } + if (method.kind === "set" && method.value.params[0].type === "RestElement") + { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); } + return method +}; + +pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) { + method.value = this.parseMethod(isGenerator, isAsync); + classBody.body.push(this.finishNode(method, "MethodDefinition")); +}; + +pp$1.parseClassId = function(node, isStatement) { + node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null; +}; + +pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; +}; + +// Parses module export declaration. + +pp$1.parseExport = function(node, exports) { + var this$1 = this; + + this.next(); + // export * from '...' + if (this.eat(types.star)) { + this.expectContextual("from"); + if (this.type !== types.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(types._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart); + var isAsync; + if (this.type === types._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + node.declaration = this.parseFunction(fNode, "nullableID", false, isAsync); + } else if (this.type === types._class) { + var cNode = this.startNode(); + node.declaration = this.parseClass(cNode, "nullableID"); + } else { + node.declaration = this.parseMaybeAssign(); + this.semicolon(); + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(true); + if (node.declaration.type === "VariableDeclaration") + { this.checkVariableExport(exports, node.declaration.declarations); } + else + { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); } + node.specifiers = []; + node.source = null; + } else { // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports); + if (this.eatContextual("from")) { + if (this.type !== types.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + } else { + // check for keywords used as local names + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + var spec = list[i]; + + this$1.checkUnreserved(spec.local); + } + + node.source = null; + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") +}; + +pp$1.checkExport = function(exports, name, pos) { + if (!exports) { return } + if (has(exports, name)) + { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } + exports[name] = true; +}; + +pp$1.checkPatternExport = function(exports, pat) { + var this$1 = this; + + var type = pat.type; + if (type == "Identifier") + { this.checkExport(exports, pat.name, pat.start); } + else if (type == "ObjectPattern") + { for (var i = 0, list = pat.properties; i < list.length; i += 1) + { + var prop = list[i]; + + this$1.checkPatternExport(exports, prop); + } } + else if (type == "ArrayPattern") + { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { + var elt = list$1[i$1]; + + if (elt) { this$1.checkPatternExport(exports, elt); } + } } + else if (type == "Property") + { this.checkPatternExport(exports, pat.value); } + else if (type == "AssignmentPattern") + { this.checkPatternExport(exports, pat.left); } + else if (type == "RestElement") + { this.checkPatternExport(exports, pat.argument); } + else if (type == "ParenthesizedExpression") + { this.checkPatternExport(exports, pat.expression); } +}; + +pp$1.checkVariableExport = function(exports, decls) { + var this$1 = this; + + if (!exports) { return } + for (var i = 0, list = decls; i < list.length; i += 1) + { + var decl = list[i]; + + this$1.checkPatternExport(exports, decl.id); + } +}; + +pp$1.shouldParseExportStatement = function() { + return this.type.keyword === "var" || + this.type.keyword === "const" || + this.type.keyword === "class" || + this.type.keyword === "function" || + this.isLet() || + this.isAsyncFunction() +}; + +// Parses a comma-separated list of module exports. + +pp$1.parseExportSpecifiers = function(exports) { + var this$1 = this; + + var nodes = [], first = true; + // export { x, y as z } [from '...'] + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this$1.expect(types.comma); + if (this$1.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var node = this$1.startNode(); + node.local = this$1.parseIdent(true); + node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local; + this$1.checkExport(exports, node.exported.name, node.exported.start); + nodes.push(this$1.finishNode(node, "ExportSpecifier")); + } + return nodes +}; + +// Parses import declaration. + +pp$1.parseImport = function(node) { + this.next(); + // import '...' + if (this.type === types.string) { + node.specifiers = empty; + node.source = this.parseExprAtom(); + } else { + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected(); + } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration") +}; + +// Parses a comma-separated list of module imports. + +pp$1.parseImportSpecifiers = function() { + var this$1 = this; + + var nodes = [], first = true; + if (this.type === types.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode(); + node.local = this.parseIdent(); + this.checkLVal(node.local, "let"); + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); + if (!this.eat(types.comma)) { return nodes } + } + if (this.type === types.star) { + var node$1 = this.startNode(); + this.next(); + this.expectContextual("as"); + node$1.local = this.parseIdent(); + this.checkLVal(node$1.local, "let"); + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); + return nodes + } + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this$1.expect(types.comma); + if (this$1.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var node$2 = this$1.startNode(); + node$2.imported = this$1.parseIdent(true); + if (this$1.eatContextual("as")) { + node$2.local = this$1.parseIdent(); + } else { + this$1.checkUnreserved(node$2.imported); + node$2.local = node$2.imported; + } + this$1.checkLVal(node$2.local, "let"); + nodes.push(this$1.finishNode(node$2, "ImportSpecifier")); + } + return nodes +}; + +// Set `ExpressionStatement#directive` property for directive prologues. +pp$1.adaptDirectivePrologue = function(statements) { + for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { + statements[i].directive = statements[i].expression.raw.slice(1, -1); + } +}; +pp$1.isDirectiveCandidate = function(statement) { + return ( + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + typeof statement.expression.value === "string" && + // Reject parenthesized strings. + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) +}; + +var pp$2 = Parser.prototype; + +// Convert existing expression atom to assignable pattern +// if possible. + +pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { + var this$1 = this; + + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + { this.raise(node.start, "Can not use 'await' as identifier inside an async function"); } + break + + case "ObjectPattern": + case "ArrayPattern": + case "RestElement": + break + + case "ObjectExpression": + node.type = "ObjectPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + this$1.toAssignable(prop, isBinding); + // Early error: + // AssignmentRestProperty[Yield, Await] : + // `...` DestructuringAssignmentTarget[Yield, Await] + // + // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this$1.raise(prop.argument.start, "Unexpected token"); + } + } + break + + case "Property": + // AssignmentProperty has type == "Property" + if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } + this.toAssignable(node.value, isBinding); + break + + case "ArrayExpression": + node.type = "ArrayPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + this.toAssignableList(node.elements, isBinding); + break + + case "SpreadElement": + node.type = "RestElement"; + this.toAssignable(node.argument, isBinding); + if (node.argument.type === "AssignmentPattern") + { this.raise(node.argument.start, "Rest elements cannot have a default value"); } + break + + case "AssignmentExpression": + if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } + node.type = "AssignmentPattern"; + delete node.operator; + this.toAssignable(node.left, isBinding); + // falls through to AssignmentPattern + + case "AssignmentPattern": + break + + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding); + break + + case "MemberExpression": + if (!isBinding) { break } + + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node +}; + +// Convert list of expression atoms to binding list. + +pp$2.toAssignableList = function(exprList, isBinding) { + var this$1 = this; + + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this$1.toAssignable(elt, isBinding); } + } + if (end) { + var last = exprList[end - 1]; + if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + { this.unexpected(last.argument.start); } + } + return exprList +}; + +// Parses spread element. + +pp$2.parseSpread = function(refDestructuringErrors) { + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssign(false, refDestructuringErrors); + return this.finishNode(node, "SpreadElement") +}; + +pp$2.parseRestBinding = function() { + var node = this.startNode(); + this.next(); + + // RestElement inside of a function parameter must be an identifier + if (this.options.ecmaVersion === 6 && this.type !== types.name) + { this.unexpected(); } + + node.argument = this.parseBindingAtom(); + + return this.finishNode(node, "RestElement") +}; + +// Parses lvalue (assignable) atom. + +pp$2.parseBindingAtom = function() { + if (this.options.ecmaVersion >= 6) { + switch (this.type) { + case types.bracketL: + var node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(types.bracketR, true, true); + return this.finishNode(node, "ArrayPattern") + + case types.braceL: + return this.parseObj(true) + } + } + return this.parseIdent() +}; + +pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) { + var this$1 = this; + + var elts = [], first = true; + while (!this.eat(close)) { + if (first) { first = false; } + else { this$1.expect(types.comma); } + if (allowEmpty && this$1.type === types.comma) { + elts.push(null); + } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { + break + } else if (this$1.type === types.ellipsis) { + var rest = this$1.parseRestBinding(); + this$1.parseBindingListItem(rest); + elts.push(rest); + if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } + this$1.expect(close); + break + } else { + var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc); + this$1.parseBindingListItem(elem); + elts.push(elem); + } + } + return elts +}; + +pp$2.parseBindingListItem = function(param) { + return param +}; + +// Parses assignment pattern around given atom if possible. + +pp$2.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom(); + if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentPattern") +}; + +// Verify that a node is an lval — something that can be assigned +// to. +// bindingType can be either: +// 'var' indicating that the lval creates a 'var' binding +// 'let' indicating that the lval creates a lexical ('let' or 'const') binding +// 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references + +pp$2.checkLVal = function(expr, bindingType, checkClashes) { + var this$1 = this; + + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } + if (checkClashes) { + if (has(checkClashes, expr.name)) + { this.raiseRecoverable(expr.start, "Argument name clash"); } + checkClashes[expr.name] = true; + } + if (bindingType && bindingType !== "none") { + if ( + bindingType === "var" && !this.canDeclareVarName(expr.name) || + bindingType !== "var" && !this.canDeclareLexicalName(expr.name) + ) { + this.raiseRecoverable(expr.start, ("Identifier '" + (expr.name) + "' has already been declared")); + } + if (bindingType === "var") { + this.declareVarName(expr.name); + } else { + this.declareLexicalName(expr.name); + } + } + break + + case "MemberExpression": + if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); } + break + + case "ObjectPattern": + for (var i = 0, list = expr.properties; i < list.length; i += 1) + { + var prop = list[i]; + + this$1.checkLVal(prop, bindingType, checkClashes); + } + break + + case "Property": + // AssignmentProperty has type == "Property" + this.checkLVal(expr.value, bindingType, checkClashes); + break + + case "ArrayPattern": + for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { + var elem = list$1[i$1]; + + if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); } + } + break + + case "AssignmentPattern": + this.checkLVal(expr.left, bindingType, checkClashes); + break + + case "RestElement": + this.checkLVal(expr.argument, bindingType, checkClashes); + break + + case "ParenthesizedExpression": + this.checkLVal(expr.expression, bindingType, checkClashes); + break + + default: + this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue"); + } +}; + +// A recursive descent parser operates by defining functions for all +// syntactic elements, and recursively calling those, each function +// advancing the input stream and returning an AST node. Precedence +// of constructs (for example, the fact that `!x[1]` means `!(x[1])` +// instead of `(!x)[1]` is handled by the fact that the parser +// function that parses unary prefix operators is called first, and +// in turn calls the function that parses `[]` subscripts — that +// way, it'll receive the node for `x[1]` already parsed, and wraps +// *that* in the unary operator node. +// +// Acorn uses an [operator precedence parser][opp] to handle binary +// operator precedence, because it is much more compact than using +// the technique outlined above, which uses different, nesting +// functions to specify precedence, for all of the ten binary +// precedence levels that JavaScript defines. +// +// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser + +var pp$3 = Parser.prototype; + +// Check if property name clashes with already added. +// Object/class getters and setters are not allowed to clash — +// either with each other or with an init property — and in +// strict mode, init properties are also not allowed to be repeated. + +pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) { + if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") + { return } + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + { return } + var key = prop.key; + var name; + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) { + if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; } + // Backwards-compat kludge. Can be removed in version 6.0 + else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } + } + propHash.proto = true; + } + return + } + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; + } else { + redefinition = other.init || other[kind]; + } + if (redefinition) + { this.raiseRecoverable(key.start, "Redefinition of property"); } + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + }; + } + other[kind] = true; +}; + +// ### Expression parsing + +// These nest, from the most general expression type at the top to +// 'atomic', nondivisible expression types at the bottom. Most of +// the functions will simply let the function(s) below them parse, +// and, *if* the syntactic construct they handle is present, wrap +// the AST node that the inner parser gave them in another node. + +// Parse a full expression. The optional arguments are used to +// forbid the `in` operator (in for loops initalization expressions) +// and provide reference for storing '=' operator inside shorthand +// property assignment in contexts where both object expression +// and object pattern might appear (so it's possible to raise +// delayed syntax error at correct position). + +pp$3.parseExpression = function(noIn, refDestructuringErrors) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeAssign(noIn, refDestructuringErrors); + if (this.type === types.comma) { + var node = this.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); } + return this.finishNode(node, "SequenceExpression") + } + return expr +}; + +// Parse an assignment expression. This includes applications of +// operators like `+=`. + +pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.inGenerator && this.isContextual("yield")) { return this.parseYield() } + + var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1; + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign; + oldTrailingComma = refDestructuringErrors.trailingComma; + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; + } else { + refDestructuringErrors = new DestructuringErrors; + ownDestructuringErrors = true; + } + + var startPos = this.start, startLoc = this.startLoc; + if (this.type == types.parenL || this.type == types.name) + { this.potentialArrowAt = this.start; } + var left = this.parseMaybeConditional(noIn, refDestructuringErrors); + if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } + if (this.type.isAssign) { + var node = this.startNodeAt(startPos, startLoc); + node.operator = this.value; + node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; + if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); } + refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly + this.checkLVal(left); + this.next(); + node.right = this.parseMaybeAssign(noIn); + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } + } + if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } + if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } + return left +}; + +// Parse a ternary conditional (`?:`) operator. + +pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprOps(noIn, refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + if (this.eat(types.question)) { + var node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + this.expect(types.colon); + node.alternate = this.parseMaybeAssign(noIn); + return this.finishNode(node, "ConditionalExpression") + } + return expr +}; + +// Start the precedence parser. + +pp$3.parseExprOps = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeUnary(refDestructuringErrors, false); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + return expr.start == startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn) +}; + +// Parse binary operators with the operator precedence parsing +// algorithm. `left` is the left-hand side of the operator. +// `minPrec` provides context that allows the function to stop and +// defer further parser to one of its callers when it encounters an +// operator that has a lower precedence than the set it is parsing. + +pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { + var prec = this.type.binop; + if (prec != null && (!noIn || this.type !== types._in)) { + if (prec > minPrec) { + var logical = this.type === types.logicalOR || this.type === types.logicalAND; + var op = this.value; + this.next(); + var startPos = this.start, startLoc = this.startLoc; + var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn); + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical); + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) + } + } + return left +}; + +pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.operator = op; + node.right = right; + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") +}; + +// Parse unary operators, both prefix and postfix. + +pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, expr; + if (this.inAsync && this.isContextual("await")) { + expr = this.parseAwait(); + sawUnary = true; + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === types.incDec; + node.operator = this.value; + node.prefix = true; + this.next(); + node.argument = this.parseMaybeUnary(null, true); + this.checkExpressionErrors(refDestructuringErrors, true); + if (update) { this.checkLVal(node.argument); } + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } + else { sawUnary = true; } + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } else { + expr = this.parseExprSubscripts(refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this$1.startNodeAt(startPos, startLoc); + node$1.operator = this$1.value; + node$1.prefix = false; + node$1.argument = expr; + this$1.checkLVal(expr); + this$1.next(); + expr = this$1.finishNode(node$1, "UpdateExpression"); + } + } + + if (!sawUnary && this.eat(types.starstar)) + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } + else + { return expr } +}; + +// Parse call, dot, and `[]`-subscript expressions. + +pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprAtom(refDestructuringErrors); + var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")"; + if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr } + var result = this.parseSubscripts(expr, startPos, startLoc); + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } + if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } + } + return result +}; + +pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { + var this$1 = this; + + var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd == base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async"; + for (var computed = (void 0);;) { + if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) { + var node = this$1.startNodeAt(startPos, startLoc); + node.object = base; + node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true); + node.computed = !!computed; + if (computed) { this$1.expect(types.bracketR); } + base = this$1.finishNode(node, "MemberExpression"); + } else if (!noCalls && this$1.eat(types.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos; + this$1.yieldPos = 0; + this$1.awaitPos = 0; + var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors); + if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) { + this$1.checkPatternErrors(refDestructuringErrors, false); + this$1.checkYieldAwaitInDefaultParams(); + this$1.yieldPos = oldYieldPos; + this$1.awaitPos = oldAwaitPos; + return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true) + } + this$1.checkExpressionErrors(refDestructuringErrors, true); + this$1.yieldPos = oldYieldPos || this$1.yieldPos; + this$1.awaitPos = oldAwaitPos || this$1.awaitPos; + var node$1 = this$1.startNodeAt(startPos, startLoc); + node$1.callee = base; + node$1.arguments = exprList; + base = this$1.finishNode(node$1, "CallExpression"); + } else if (this$1.type === types.backQuote) { + var node$2 = this$1.startNodeAt(startPos, startLoc); + node$2.tag = base; + node$2.quasi = this$1.parseTemplate({isTagged: true}); + base = this$1.finishNode(node$2, "TaggedTemplateExpression"); + } else { + return base + } + } +}; + +// Parse an atomic expression — either a single token that is an +// expression, an expression started by a keyword like `function` or +// `new`, or an expression wrapped in punctuation like `()`, `[]`, +// or `{}`. + +pp$3.parseExprAtom = function(refDestructuringErrors) { + var node, canBeArrow = this.potentialArrowAt == this.start; + switch (this.type) { + case types._super: + if (!this.inFunction) + { this.raise(this.start, "'super' outside of function or class"); } + node = this.startNode(); + this.next(); + // The `super` keyword can appear at below: + // SuperProperty: + // super [ Expression ] + // super . IdentifierName + // SuperCall: + // super Arguments + if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL) + { this.unexpected(); } + return this.finishNode(node, "Super") + + case types._this: + node = this.startNode(); + this.next(); + return this.finishNode(node, "ThisExpression") + + case types.name: + var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; + var id = this.parseIdent(this.type !== types.name); + if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function)) + { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) } + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(types.arrow)) + { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) } + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) { + id = this.parseIdent(); + if (this.canInsertSemicolon() || !this.eat(types.arrow)) + { this.unexpected(); } + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) + } + } + return id + + case types.regexp: + var value = this.value; + node = this.parseLiteral(value.value); + node.regex = {pattern: value.pattern, flags: value.flags}; + return node + + case types.num: case types.string: + return this.parseLiteral(this.value) + + case types._null: case types._true: case types._false: + node = this.startNode(); + node.value = this.type === types._null ? null : this.type === types._true; + node.raw = this.type.keyword; + this.next(); + return this.finishNode(node, "Literal") + + case types.parenL: + var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow); + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + { refDestructuringErrors.parenthesizedAssign = start; } + if (refDestructuringErrors.parenthesizedBind < 0) + { refDestructuringErrors.parenthesizedBind = start; } + } + return expr + + case types.bracketL: + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors); + return this.finishNode(node, "ArrayExpression") + + case types.braceL: + return this.parseObj(false, refDestructuringErrors) + + case types._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, false) + + case types._class: + return this.parseClass(this.startNode(), false) + + case types._new: + return this.parseNew() + + case types.backQuote: + return this.parseTemplate() + + default: + this.unexpected(); + } +}; + +pp$3.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); + this.next(); + return this.finishNode(node, "Literal") +}; + +pp$3.parseParenExpression = function() { + this.expect(types.parenL); + var val = this.parseExpression(); + this.expect(types.parenR); + return val +}; + +pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; + if (this.options.ecmaVersion >= 6) { + this.next(); + + var innerStartPos = this.start, innerStartLoc = this.startLoc; + var exprList = [], first = true, lastIsComma = false; + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; + this.yieldPos = 0; + this.awaitPos = 0; + while (this.type !== types.parenR) { + first ? first = false : this$1.expect(types.comma); + if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) { + lastIsComma = true; + break + } else if (this$1.type === types.ellipsis) { + spreadStart = this$1.start; + exprList.push(this$1.parseParenItem(this$1.parseRestBinding())); + if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } + break + } else { + exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)); + } + } + var innerEndPos = this.start, innerEndLoc = this.startLoc; + this.expect(types.parenR); + + if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + return this.parseParenArrowList(startPos, startLoc, exprList) + } + + if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } + if (spreadStart) { this.unexpected(spreadStart); } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); + } else { + val = exprList[0]; + } + } else { + val = this.parseParenExpression(); + } + + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc); + par.expression = val; + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } +}; + +pp$3.parseParenItem = function(item) { + return item +}; + +pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) +}; + +// New's precedence is slightly tricky. It must allow its argument to +// be a `[]` or dot subscript expression, but not a call — at least, +// not without wrapping it in parentheses. Thus, it uses the noCalls +// argument to parseSubscripts to prevent it from consuming the +// argument list. + +var empty$1 = []; + +pp$3.parseNew = function() { + var node = this.startNode(); + var meta = this.parseIdent(true); + if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) { + node.meta = meta; + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + if (node.property.name !== "target" || containsEsc) + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); } + if (!this.inFunction) + { this.raiseRecoverable(node.start, "new.target can only be used in functions"); } + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc; + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); + if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); } + else { node.arguments = empty$1; } + return this.finishNode(node, "NewExpression") +}; + +// Parse template expression. + +pp$3.parseTemplateElement = function(ref) { + var isTagged = ref.isTagged; + + var elem = this.startNode(); + if (this.type === types.invalidTemplate) { + if (!isTagged) { + this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); + } + elem.value = { + raw: this.value, + cooked: null + }; + } else { + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), + cooked: this.value + }; + } + this.next(); + elem.tail = this.type === types.backQuote; + return this.finishNode(elem, "TemplateElement") +}; + +pp$3.parseTemplate = function(ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; + + var node = this.startNode(); + this.next(); + node.expressions = []; + var curElt = this.parseTemplateElement({isTagged: isTagged}); + node.quasis = [curElt]; + while (!curElt.tail) { + this$1.expect(types.dollarBraceL); + node.expressions.push(this$1.parseExpression()); + this$1.expect(types.braceR); + node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged})); + } + this.next(); + return this.finishNode(node, "TemplateLiteral") +}; + +pp$3.isAsyncProp = function(prop) { + return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && + (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) && + !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +}; + +// Parse an object literal or binding pattern. + +pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var this$1 = this; + + var node = this.startNode(), first = true, propHash = {}; + node.properties = []; + this.next(); + while (!this.eat(types.braceR)) { + if (!first) { + this$1.expect(types.comma); + if (this$1.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var prop = this$1.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); } + node.properties.push(prop); + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") +}; + +pp$3.parseProperty = function(isPattern, refDestructuringErrors) { + var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; + if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) { + if (isPattern) { + prop.argument = this.parseIdent(false); + if (this.type === types.comma) { + this.raise(this.start, "Comma is not permitted after the rest element"); + } + return this.finishNode(prop, "RestElement") + } + // To disallow parenthesized identifier via `this.toAssignable()`. + if (this.type === types.parenL && refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0) { + refDestructuringErrors.parenthesizedAssign = this.start; + } + if (refDestructuringErrors.parenthesizedBind < 0) { + refDestructuringErrors.parenthesizedBind = this.start; + } + } + // Parse argument. + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + // To disallow trailing comma via `this.toAssignable()`. + if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + // Finish + return this.finishNode(prop, "SpreadElement") + } + if (this.options.ecmaVersion >= 6) { + prop.method = false; + prop.shorthand = false; + if (isPattern || refDestructuringErrors) { + startPos = this.start; + startLoc = this.startLoc; + } + if (!isPattern) + { isGenerator = this.eat(types.star); } + } + var containsEsc = this.containsEsc; + this.parsePropertyName(prop); + if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); + this.parsePropertyName(prop, refDestructuringErrors); + } else { + isAsync = false; + } + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); + return this.finishNode(prop, "Property") +}; + +pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { + if ((isGenerator || isAsync) && this.type === types.colon) + { this.unexpected(); } + + if (this.eat(types.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); + prop.kind = "init"; + } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) { + if (isPattern) { this.unexpected(); } + prop.kind = "init"; + prop.method = true; + prop.value = this.parseMethod(isGenerator, isAsync); + } else if (!isPattern && !containsEsc && + this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type != types.comma && this.type != types.braceR)) { + if (isGenerator || isAsync) { this.unexpected(); } + prop.kind = prop.key.name; + this.parsePropertyName(prop); + prop.value = this.parseMethod(false); + var paramCount = prop.kind === "get" ? 0 : 1; + if (prop.value.params.length !== paramCount) { + var start = prop.value.start; + if (prop.kind === "get") + { this.raiseRecoverable(start, "getter should have no params"); } + else + { this.raiseRecoverable(start, "setter should have exactly one param"); } + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } + } + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + this.checkUnreserved(prop.key); + prop.kind = "init"; + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); + } else if (this.type === types.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + { refDestructuringErrors.shorthandAssign = this.start; } + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); + } else { + prop.value = prop.key; + } + prop.shorthand = true; + } else { this.unexpected(); } +}; + +pp$3.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(types.bracketL)) { + prop.computed = true; + prop.key = this.parseMaybeAssign(); + this.expect(types.bracketR); + return prop.key + } else { + prop.computed = false; + } + } + return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true) +}; + +// Initialize empty function node. + +pp$3.initFunction = function(node) { + node.id = null; + if (this.options.ecmaVersion >= 6) { + node.generator = false; + node.expression = false; + } + if (this.options.ecmaVersion >= 8) + { node.async = false; } +}; + +// Parse object or class method. + +pp$3.parseMethod = function(isGenerator, isAsync) { + var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; + + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + this.inGenerator = node.generator; + this.inAsync = node.async; + this.yieldPos = 0; + this.awaitPos = 0; + this.inFunction = true; + this.enterFunctionScope(); + + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + this.parseFunctionBody(node, false); + + this.inGenerator = oldInGen; + this.inAsync = oldInAsync; + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.inFunction = oldInFunc; + return this.finishNode(node, "FunctionExpression") +}; + +// Parse arrow function expression with given parameters. + +pp$3.parseArrowExpression = function(node, params, isAsync) { + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; + + this.enterFunctionScope(); + this.initFunction(node); + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + this.inGenerator = false; + this.inAsync = node.async; + this.yieldPos = 0; + this.awaitPos = 0; + this.inFunction = true; + + node.params = this.toAssignableList(params, true); + this.parseFunctionBody(node, true); + + this.inGenerator = oldInGen; + this.inAsync = oldInAsync; + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.inFunction = oldInFunc; + return this.finishNode(node, "ArrowFunctionExpression") +}; + +// Parse function body and check parameters. + +pp$3.parseFunctionBody = function(node, isArrowFunction) { + var isExpression = isArrowFunction && this.type !== types.braceL; + var oldStrict = this.strict, useStrict = false; + + if (isExpression) { + node.body = this.parseMaybeAssign(); + node.expression = true; + this.checkParams(node, false); + } else { + var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end); + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels; + this.labels = []; + if (useStrict) { this.strict = true; } + + // Add the params to varDeclaredNames to ensure that an error is thrown + // if a let/const declaration in the function clashes with one of the params. + this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params)); + node.body = this.parseBlock(false); + node.expression = false; + this.adaptDirectivePrologue(node.body.body); + this.labels = oldLabels; + } + this.exitFunctionScope(); + + if (this.strict && node.id) { + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + this.checkLVal(node.id, "none"); + } + this.strict = oldStrict; +}; + +pp$3.isSimpleParamList = function(params) { + for (var i = 0, list = params; i < list.length; i += 1) + { + var param = list[i]; + + if (param.type !== "Identifier") { return false + } } + return true +}; + +// Checks function params for various disallowed patterns such as using "eval" +// or "arguments" and duplicate parameters. + +pp$3.checkParams = function(node, allowDuplicates) { + var this$1 = this; + + var nameHash = {}; + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + this$1.checkLVal(param, "var", allowDuplicates ? null : nameHash); + } +}; + +// Parses a comma-separated list of expressions, and returns them as +// an array. `close` is the token type that ends the list, and +// `allowEmpty` can be turned on to allow subsequent commas with +// nothing in between them to be parsed as `null` (which is needed +// for array literals). + +pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var this$1 = this; + + var elts = [], first = true; + while (!this.eat(close)) { + if (!first) { + this$1.expect(types.comma); + if (allowTrailingComma && this$1.afterTrailingComma(close)) { break } + } else { first = false; } + + var elt = (void 0); + if (allowEmpty && this$1.type === types.comma) + { elt = null; } + else if (this$1.type === types.ellipsis) { + elt = this$1.parseSpread(refDestructuringErrors); + if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0) + { refDestructuringErrors.trailingComma = this$1.start; } + } else { + elt = this$1.parseMaybeAssign(false, refDestructuringErrors); + } + elts.push(elt); + } + return elts +}; + +pp$3.checkUnreserved = function(ref) { + var start = ref.start; + var end = ref.end; + var name = ref.name; + + if (this.inGenerator && name === "yield") + { this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator"); } + if (this.inAsync && name === "await") + { this.raiseRecoverable(start, "Can not use 'await' as identifier inside an async function"); } + if (this.isKeyword(name)) + { this.raise(start, ("Unexpected keyword '" + name + "'")); } + if (this.options.ecmaVersion < 6 && + this.input.slice(start, end).indexOf("\\") != -1) { return } + var re = this.strict ? this.reservedWordsStrict : this.reservedWords; + if (re.test(name)) { + if (!this.inAsync && name === "await") + { this.raiseRecoverable(start, "Can not use keyword 'await' outside an async function"); } + this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); + } +}; + +// Parse the next token as an identifier. If `liberal` is true (used +// when parsing properties), it will also convert keywords into +// identifiers. + +pp$3.parseIdent = function(liberal, isBinding) { + var node = this.startNode(); + if (liberal && this.options.allowReserved == "never") { liberal = false; } + if (this.type === types.name) { + node.name = this.value; + } else if (this.type.keyword) { + node.name = this.type.keyword; + + // To fix https://github.com/acornjs/acorn/issues/575 + // `class` and `function` keywords push new context into this.context. + // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. + // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); + } + } else { + this.unexpected(); + } + this.next(); + this.finishNode(node, "Identifier"); + if (!liberal) { this.checkUnreserved(node); } + return node +}; + +// Parses yield expression inside generator. + +pp$3.parseYield = function() { + if (!this.yieldPos) { this.yieldPos = this.start; } + + var node = this.startNode(); + this.next(); + if (this.type == types.semi || this.canInsertSemicolon() || (this.type != types.star && !this.type.startsExpr)) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(types.star); + node.argument = this.parseMaybeAssign(); + } + return this.finishNode(node, "YieldExpression") +}; + +pp$3.parseAwait = function() { + if (!this.awaitPos) { this.awaitPos = this.start; } + + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeUnary(null, true); + return this.finishNode(node, "AwaitExpression") +}; + +var pp$4 = Parser.prototype; + +// This function is used to raise exceptions on parse errors. It +// takes an offset integer (into the current `input`) to indicate +// the location of the error, attaches the position to the end +// of the error message, and then raises a `SyntaxError` with that +// message. + +pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos); + message += " (" + loc.line + ":" + loc.column + ")"; + var err = new SyntaxError(message); + err.pos = pos; err.loc = loc; err.raisedAt = this.pos; + throw err +}; + +pp$4.raiseRecoverable = pp$4.raise; + +pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } +}; + +var pp$5 = Parser.prototype; + +// Object.assign polyfill +var assign = Object.assign || function(target) { + var sources = [], len = arguments.length - 1; + while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ]; + + for (var i = 0, list = sources; i < list.length; i += 1) { + var source = list[i]; + + for (var key in source) { + if (has(source, key)) { + target[key] = source[key]; + } + } + } + return target +}; + +// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. + +pp$5.enterFunctionScope = function() { + // var: a hash of var-declared names in the current lexical scope + // lexical: a hash of lexically-declared names in the current lexical scope + // childVar: a hash of var-declared names in all child lexical scopes of the current lexical scope (within the current function scope) + // parentLexical: a hash of lexically-declared names in all parent lexical scopes of the current lexical scope (within the current function scope) + this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}}); +}; + +pp$5.exitFunctionScope = function() { + this.scopeStack.pop(); +}; + +pp$5.enterLexicalScope = function() { + var parentScope = this.scopeStack[this.scopeStack.length - 1]; + var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}}; + + this.scopeStack.push(childScope); + assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical); +}; + +pp$5.exitLexicalScope = function() { + var childScope = this.scopeStack.pop(); + var parentScope = this.scopeStack[this.scopeStack.length - 1]; + + assign(parentScope.childVar, childScope.var, childScope.childVar); +}; + +/** + * A name can be declared with `var` if there are no variables with the same name declared with `let`/`const` + * in the current lexical scope or any of the parent lexical scopes in this function. + */ +pp$5.canDeclareVarName = function(name) { + var currentScope = this.scopeStack[this.scopeStack.length - 1]; + + return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name) +}; + +/** + * A name can be declared with `let`/`const` if there are no variables with the same name declared with `let`/`const` + * in the current scope, and there are no variables with the same name declared with `var` in the current scope or in + * any child lexical scopes in this function. + */ +pp$5.canDeclareLexicalName = function(name) { + var currentScope = this.scopeStack[this.scopeStack.length - 1]; + + return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name) +}; + +pp$5.declareVarName = function(name) { + this.scopeStack[this.scopeStack.length - 1].var[name] = true; +}; + +pp$5.declareLexicalName = function(name) { + this.scopeStack[this.scopeStack.length - 1].lexical[name] = true; +}; + +var Node = function Node(parser, pos, loc) { + this.type = ""; + this.start = pos; + this.end = 0; + if (parser.options.locations) + { this.loc = new SourceLocation(parser, loc); } + if (parser.options.directSourceFile) + { this.sourceFile = parser.options.directSourceFile; } + if (parser.options.ranges) + { this.range = [pos, 0]; } +}; + +// Start an AST node, attaching a start offset. + +var pp$6 = Parser.prototype; + +pp$6.startNode = function() { + return new Node(this, this.start, this.startLoc) +}; + +pp$6.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) +}; + +// Finish an AST node, adding `type` and `end` properties. + +function finishNodeAt(node, type, pos, loc) { + node.type = type; + node.end = pos; + if (this.options.locations) + { node.loc.end = loc; } + if (this.options.ranges) + { node.range[1] = pos; } + return node +} + +pp$6.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) +}; + +// Finish node at given position + +pp$6.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) +}; + +// The algorithm used to determine whether a regexp can appear at a +// given point in the program is loosely based on sweet.js' approach. +// See https://github.com/mozilla/sweet.js/wiki/design + +var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { + this.token = token; + this.isExpr = !!isExpr; + this.preserveSpace = !!preserveSpace; + this.override = override; + this.generator = !!generator; +}; + +var types$1 = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", false), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), + f_stat: new TokContext("function", false), + f_expr: new TokContext("function", true), + f_expr_gen: new TokContext("function", true, false, null, true), + f_gen: new TokContext("function", false, false, null, true) +}; + +var pp$7 = Parser.prototype; + +pp$7.initialContext = function() { + return [types$1.b_stat] +}; + +pp$7.braceIsBlock = function(prevType) { + var parent = this.curContext(); + if (parent === types$1.f_expr || parent === types$1.f_stat) + { return true } + if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr)) + { return !parent.isExpr } + + // The check for `tt.name && exprAllowed` detects whether we are + // after a `yield` or `of` construct. See the `updateContext` for + // `tt.name`. + if (prevType === types._return || prevType == types.name && this.exprAllowed) + { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } + if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType == types.arrow) + { return true } + if (prevType == types.braceL) + { return parent === types$1.b_stat } + if (prevType == types._var || prevType == types.name) + { return false } + return !this.exprAllowed +}; + +pp$7.inGeneratorContext = function() { + var this$1 = this; + + for (var i = this.context.length - 1; i >= 1; i--) { + var context = this$1.context[i]; + if (context.token === "function") + { return context.generator } + } + return false +}; + +pp$7.updateContext = function(prevType) { + var update, type = this.type; + if (type.keyword && prevType == types.dot) + { this.exprAllowed = false; } + else if (update = type.updateContext) + { update.call(this, prevType); } + else + { this.exprAllowed = type.beforeExpr; } +}; + +// Token-specific context update code + +types.parenR.updateContext = types.braceR.updateContext = function() { + if (this.context.length == 1) { + this.exprAllowed = true; + return + } + var out = this.context.pop(); + if (out === types$1.b_stat && this.curContext().token === "function") { + out = this.context.pop(); + } + this.exprAllowed = !out.isExpr; +}; + +types.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr); + this.exprAllowed = true; +}; + +types.dollarBraceL.updateContext = function() { + this.context.push(types$1.b_tmpl); + this.exprAllowed = true; +}; + +types.parenL.updateContext = function(prevType) { + var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while; + this.context.push(statementParens ? types$1.p_stat : types$1.p_expr); + this.exprAllowed = true; +}; + +types.incDec.updateContext = function() { + // tokExprAllowed stays unchanged +}; + +types._function.updateContext = types._class.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && + !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) + { this.context.push(types$1.f_expr); } + else + { this.context.push(types$1.f_stat); } + this.exprAllowed = false; +}; + +types.backQuote.updateContext = function() { + if (this.curContext() === types$1.q_tmpl) + { this.context.pop(); } + else + { this.context.push(types$1.q_tmpl); } + this.exprAllowed = false; +}; + +types.star.updateContext = function(prevType) { + if (prevType == types._function) { + var index = this.context.length - 1; + if (this.context[index] === types$1.f_expr) + { this.context[index] = types$1.f_expr_gen; } + else + { this.context[index] = types$1.f_gen; } + } + this.exprAllowed = true; +}; + +types.name.updateContext = function(prevType) { + var allowed = false; + if (this.options.ecmaVersion >= 6) { + if (this.value == "of" && !this.exprAllowed || + this.value == "yield" && this.inGeneratorContext()) + { allowed = true; } + } + this.exprAllowed = allowed; +}; + +// Object type used to represent tokens. Note that normally, tokens +// simply exist as properties on the parser object. This is only +// used for the onToken callback and the external tokenizer. + +var Token = function Token(p) { + this.type = p.type; + this.value = p.value; + this.start = p.start; + this.end = p.end; + if (p.options.locations) + { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } + if (p.options.ranges) + { this.range = [p.start, p.end]; } +}; + +// ## Tokenizer + +var pp$8 = Parser.prototype; + +// Are we running under Rhino? +var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]"; + +// Move to the next token + +pp$8.next = function() { + if (this.options.onToken) + { this.options.onToken(new Token(this)); } + + this.lastTokEnd = this.end; + this.lastTokStart = this.start; + this.lastTokEndLoc = this.endLoc; + this.lastTokStartLoc = this.startLoc; + this.nextToken(); +}; + +pp$8.getToken = function() { + this.next(); + return new Token(this) +}; + +// If we're in an ES6 environment, make parsers iterable +if (typeof Symbol !== "undefined") + { pp$8[Symbol.iterator] = function() { + var this$1 = this; + + return { + next: function () { + var token = this$1.getToken(); + return { + done: token.type === types.eof, + value: token + } + } + } + }; } + +// Toggle strict mode. Re-reads the next number or string to please +// pedantic tests (`"use strict"; 010;` should fail). + +pp$8.curContext = function() { + return this.context[this.context.length - 1] +}; + +// Read a single token, updating the parser object's token-related +// properties. + +pp$8.nextToken = function() { + var curContext = this.curContext(); + if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } + + this.start = this.pos; + if (this.options.locations) { this.startLoc = this.curPosition(); } + if (this.pos >= this.input.length) { return this.finishToken(types.eof) } + + if (curContext.override) { return curContext.override(this) } + else { this.readToken(this.fullCharCodeAtPos()); } +}; + +pp$8.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + { return this.readWord() } + + return this.getTokenFromCode(code) +}; + +pp$8.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos); + if (code <= 0xd7ff || code >= 0xe000) { return code } + var next = this.input.charCodeAt(this.pos + 1); + return (code << 10) + next - 0x35fdc00 +}; + +pp$8.skipBlockComment = function() { + var this$1 = this; + + var startLoc = this.options.onComment && this.curPosition(); + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); + if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } + this.pos = end + 2; + if (this.options.locations) { + lineBreakG.lastIndex = start; + var match; + while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { + ++this$1.curLine; + this$1.lineStart = match.index + match[0].length; + } + } + if (this.options.onComment) + { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()); } +}; + +pp$8.skipLineComment = function(startSkip) { + var this$1 = this; + + var start = this.pos; + var startLoc = this.options.onComment && this.curPosition(); + var ch = this.input.charCodeAt(this.pos += startSkip); + while (this.pos < this.input.length && !isNewLine(ch)) { + ch = this$1.input.charCodeAt(++this$1.pos); + } + if (this.options.onComment) + { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()); } +}; + +// Called at the start of the parse and after every token. Skips +// whitespace and comments, and. + +pp$8.skipSpace = function() { + var this$1 = this; + + loop: while (this.pos < this.input.length) { + var ch = this$1.input.charCodeAt(this$1.pos); + switch (ch) { + case 32: case 160: // ' ' + ++this$1.pos; + break + case 13: + if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { + ++this$1.pos; + } + case 10: case 8232: case 8233: + ++this$1.pos; + if (this$1.options.locations) { + ++this$1.curLine; + this$1.lineStart = this$1.pos; + } + break + case 47: // '/' + switch (this$1.input.charCodeAt(this$1.pos + 1)) { + case 42: // '*' + this$1.skipBlockComment(); + break + case 47: + this$1.skipLineComment(2); + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this$1.pos; + } else { + break loop + } + } + } +}; + +// Called at the end of every token. Sets `end`, `val`, and +// maintains `context` and `exprAllowed`, and skips the space after +// the token, so that the next one's `start` will point at the +// right position. + +pp$8.finishToken = function(type, val) { + this.end = this.pos; + if (this.options.locations) { this.endLoc = this.curPosition(); } + var prevType = this.type; + this.type = type; + this.value = val; + + this.updateContext(prevType); +}; + +// ### Token reading + +// This is the function that is called to fetch the next token. It +// is somewhat obscure, because it works in character codes rather +// than characters, and because operator parsing has been inlined +// into it. +// +// All in the name of speed. +// +pp$8.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1); + if (next >= 48 && next <= 57) { return this.readNumber(true) } + var next2 = this.input.charCodeAt(this.pos + 2); + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3; + return this.finishToken(types.ellipsis) + } else { + ++this.pos; + return this.finishToken(types.dot) + } +}; + +pp$8.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1); + if (this.exprAllowed) { ++this.pos; return this.readRegexp() } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.slash, 1) +}; + +pp$8.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + var tokentype = code === 42 ? types.star : types.modulo; + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && code == 42 && next === 42) { + ++size; + tokentype = types.starstar; + next = this.input.charCodeAt(this.pos + 2); + } + + if (next === 61) { return this.finishOp(types.assign, size + 1) } + return this.finishOp(tokentype, size) +}; + +pp$8.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1) +}; + +pp$8.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1); + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.bitwiseXOR, 1) +}; + +pp$8.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (next == 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 62 && + (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { + // A `-->` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types.incDec, 2) + } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.plusMin, 1) +}; + +pp$8.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) } + return this.finishOp(types.bitShift, size) + } + if (next == 33 && code == 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + // `",device.name); + device.getPorts(function(devicePorts, instantPorts) { + //console.log("getPorts <--",device.name); + if (instantPorts===false) shouldCallAgain = true; + if (devicePorts) { + devicePorts.forEach(function(port) { + var ignored = false; + if (Espruino.Config.SERIAL_IGNORE) + Espruino.Config.SERIAL_IGNORE.split("|").forEach(function(wildcard) { + var regexp = "^"+wildcard.replace(/\./g,"\\.").replace(/\*/g,".*")+"$"; + if (port.path.match(new RegExp(regexp))) + ignored = true; + }); + + if (!ignored) { + if (port.usb && port.usb[0]==0x0483 && port.usb[1]==0x5740) + port.description = "Espruino board"; + ports.push(port); + newPortToDevice[port.path] = device; + } + }); + } + responses++; + if (responses == devices.length) { + portToDevice = newPortToDevice; + ports.sort(function(a,b) { + if (a.unimportant && !b.unimportant) return 1; + if (b.unimportant && !a.unimportant) return -1; + return 0; + }); + callback(ports, shouldCallAgain); + } + }); + }); + }; + + var openSerial=function(serialPort, connectCallback, disconnectCallback) { + return openSerialInternal(serialPort, connectCallback, disconnectCallback, 2); + } + + var openSerialInternal=function(serialPort, connectCallback, disconnectCallback, attempts) { + /* If openSerial is called, we need to have called getPorts first + in order to figure out which one of the serial_ implementations + we must call into. */ + if (portToDevice === undefined) { + portToDevice = []; // stop recursive calls if something errors + return getPorts(function() { + openSerialInternal(serialPort, connectCallback, disconnectCallback, attempts); + }); + } + + if (!(serialPort in portToDevice)) { + if (serialPort.toLowerCase() in portToDevice) { + serialPort = serialPort.toLowerCase(); + } else { + if (attempts>0) { + console.log("Port "+JSON.stringify(serialPort)+" not found - checking ports again ("+attempts+" attempts left)"); + return getPorts(function() { + openSerialInternal(serialPort, connectCallback, disconnectCallback, attempts-1); + }); + } else { + console.error("Port "+JSON.stringify(serialPort)+" not found"); + return connectCallback(undefined); + } + } + } + + connectionInfo = undefined; + flowControlXOFF = false; + currentDevice = portToDevice[serialPort]; + currentDevice.open(serialPort, function(cInfo) { // CONNECT + if (!cInfo) { +// Espruino.Core.Notifications.error("Unable to connect"); + console.error("Unable to open device (connectionInfo="+cInfo+")"); + connectCallback(undefined); + } else { + connectionInfo = cInfo; + connectedPort = serialPort; + console.log("Connected", cInfo); + var portInfo = { port:serialPort }; + if (connectionInfo.portName) + portInfo.portName = connectionInfo.portName; + Espruino.callProcessor("connected", portInfo, function() { + connectCallback(cInfo); + }); + } + }, function(data) { // RECEIEVE DATA + if (!(data instanceof ArrayBuffer)) console.warn("Serial port implementation is not returning ArrayBuffers"); + if (Espruino.Config.SERIAL_FLOW_CONTROL) { + var u = new Uint8Array(data); + for (var i=0;i resume upload"); + flowControlXOFF = false; + } + if (u[i]==19) { // XOFF + console.log("XOFF received => pause upload"); + flowControlXOFF = true; + } + } + } + if (readListener) readListener(data); + }, function() { // DISCONNECT + currentDevice = undefined; + if (!connectionInfo) { + // we got a disconnect when we hadn't connected... + // Just call connectCallback(undefined), don't bother sending disconnect + connectCallback(undefined); + return; + } + connectionInfo = undefined; + if (writeTimeout!==undefined) + clearTimeout(writeTimeout); + writeTimeout = undefined; + writeData = []; + sendingBinary = false; + flowControlXOFF = false; + + Espruino.callProcessor("disconnected", undefined, function() { + disconnectCallback(); + }); + }); + }; + + var str2ab=function(str) { + var buf=new ArrayBuffer(str.length); + var bufView=new Uint8Array(buf); + for (var i=0; i=256) { + console.warn("Attempted to send non-8 bit character - code "+ch); + ch = "?".charCodeAt(0); + } + bufView[i] = ch; + } + return buf; + }; + + var closeSerial=function() { + if (currentDevice) { + currentDevice.close(); + currentDevice = undefined; + } else + console.error("Close called, but serial port not open"); + }; + + var isConnected = function() { + return currentDevice!==undefined; + }; + + var writeSerialWorker = function(isStarting) { + writeTimeout = undefined; // we've been called + // check flow control + if (flowControlXOFF) { + /* flow control was enabled - bit hacky (we could use a callback) + but safe - just check again in a bit to see if we should send */ + writeTimeout = setTimeout(function() { + writeSerialWorker(); + }, 50); + return; + } + + // if we disconnected while sending, empty queue + if (currentDevice === undefined) { + if (writeData[0].callback) + writeData[0].callback(); + writeData.shift(); + if (writeData.length) setTimeout(function() { + writeSerialWorker(false); + }, 1); + return; + } + + if (writeData[0].data === "") { + if (writeData[0].showStatus) + Espruino.Core.Status.setStatus("Sent"); + if (writeData[0].callback) + writeData[0].callback(); + writeData.shift(); // remove this empty first element + if (!writeData.length) return; // anything left to do? + isStarting = true; + } + + if (isStarting) { + var blockSize = 512; + if (currentDevice.maxWriteLength) + blockSize = currentDevice.maxWriteLength; + /* if we're throttling our writes we want to send small + * blocks of data at once. We still limit the size of + * sent blocks to 512 because on Mac we seem to lose + * data otherwise (not on any other platforms!) */ + if (slowWrite) blockSize=19; + writeData[0].blockSize = blockSize; + + writeData[0].showStatus &= writeData[0].data.length>writeData[0].blockSize; + if (writeData[0].showStatus) { + Espruino.Core.Status.setStatus("Sending...", writeData[0].data.length); + console.log("---> "+JSON.stringify(writeData[0].data)); + } + } + + // Initial split use previous, or don't + var d = undefined; + var split = writeData[0].nextSplit || { start:0, end:writeData[0].data.length, delay:0 }; + // if we get something like Ctrl-C or `reset`, wait a bit for it to complete + if (!sendingBinary) { + function findSplitIdx(prev, substr, delay, reason) { + var match = writeData[0].data.match(substr); + // not found + if (match===null) return prev; + // or previous find was earlier in str + var end = match.index + match[0].length; + if (end > prev.end) return prev; + // found, and earlier + prev.start = match.index; + prev.end = end; + prev.delay = delay; + prev.match = match[0]; + prev.reason = reason; + return prev; + } + split = findSplitIdx(split, /\x03/, 250, "Ctrl-C"); // Ctrl-C + split = findSplitIdx(split, /reset\(\);\n/, 250, "reset()"); // Reset + split = findSplitIdx(split, /load\(\);\n/, 250, "load()"); // Load + split = findSplitIdx(split, /Modules.addCached\("[^\n]*"\);\n/, 250, "Modules.addCached"); // Adding a module + split = findSplitIdx(split, /\x10require\("Storage"\).write\([^\n]*\);\n/, 500, "Storage.write"); // Write chunk of data + } + // Otherwise split based on block size + if (!split.match || split.end >= writeData[0].blockSize) { + if (split.match) writeData[0].nextSplit = split; + split = { start:0, end:writeData[0].blockSize, delay:0 }; + } + if (split.match) console.log("Splitting for "+split.reason+", delay "+split.delay); + // Only send some of the data + if (writeData[0].data.length>split.end) { + if (slowWrite && split.delay==0) split.delay=50; + d = writeData[0].data.substr(0,split.end); + writeData[0].data = writeData[0].data.substr(split.end); + if (writeData[0].nextSplit) { + writeData[0].nextSplit.start -= split.end; + writeData[0].nextSplit.end -= split.end; + if (writeData[0].nextSplit.end<=0) + writeData[0].nextSplit = undefined; + } + } else { + d = writeData[0].data; + writeData[0].data = ""; + writeData[0].nextSplit = undefined; + } + // update status + if (writeData[0].showStatus) + Espruino.Core.Status.incrementProgress(d.length); + // actually write data + //console.log("Sending block "+JSON.stringify(d)+", wait "+split.delay+"ms"); + currentDevice.write(d, function() { + // Once written, start timeout + writeTimeout = setTimeout(function() { + writeSerialWorker(); + }, split.delay); + }); + } + + // Throttled serial write + var writeSerial = function(data, showStatus, callback) { + if (showStatus===undefined) showStatus=true; + + /* Queue our data to write. If there was previous data and no callback to + invoke on this data or the previous then just append data. This would happen + if typing in the terminal for example. */ + if (!callback && writeData.length && !writeData[writeData.length-1].callback) { + writeData[writeData.length-1].data += data; + } else { + writeData.push({data:data,callback:callback,showStatus:showStatus}); + /* if this is our first data, start sending now. Otherwise we're already + busy sending and will pull data off writeData when ready */ + if (writeData.length==1) + writeSerialWorker(true); + } + }; + + + // ---------------------------------------------------------- + Espruino.Core.Serial = { + "devices" : [], // List of devices that can provide a serial API + "init" : init, + "getPorts": getPorts, + "open": openSerial, + "isConnected": isConnected, + "startListening": startListening, + "write": writeSerial, + "close": closeSerial, + "isSlowWrite": function() { return slowWrite; }, + "setSlowWrite": function(isOn, force) { + if ((!force) && Espruino.Config.SERIAL_THROTTLE_SEND) { + console.log("ForceThrottle option is set - set Slow Write = true"); + isOn = true; + } else + console.log("Set Slow Write = "+isOn); + slowWrite = isOn; + }, + "setBinary": function(isOn) { + sendingBinary = isOn; + } + }; +})(); +/** + Copyright 2014 Gordon Williams (gw@pur3.co.uk) + + This Source Code is subject to the terms of the Mozilla Public + License, v2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + ------------------------------------------------------------------ + The plugin that actually writes code out to Espruino + ------------------------------------------------------------------ +**/ +"use strict"; +(function(){ + + function init() { + Espruino.Core.Config.add("RESET_BEFORE_SEND", { + section : "Communications", + name : "Reset before Send", + description : "Reset Espruino before sending code from the editor pane?", + type : "boolean", + defaultValue : true + }); + Espruino.Core.Config.add("STORE_LINE_NUMBERS", { + section : "Communications", + name : "Store line numbers", + description : "Should Espruino store line numbers for each function? This uses one extra variable per function, but allows you to get source code debugging in the Web IDE", + type : "boolean", + defaultValue : true + }); + + } + + function writeToEspruino(code, callback) { + /* hack around non-K&R code formatting that would have + broken Espruino CLI's bracket counting */ + code = reformatCode(code); + if (code === undefined) return; // it should already have errored + + // We want to make sure we've got a prompt before sending. If not, + // this will issue a Ctrl+C + Espruino.Core.Utils.getEspruinoPrompt(function() { + // Make sure code ends in 2 newlines + while (code[code.length-2]!="\n" || code[code.length-1]!="\n") + code += "\n"; + + // If we're supposed to reset Espruino before sending... + if (Espruino.Config.RESET_BEFORE_SEND) { + code = "\x10reset();\n"+code; + } + + //console.log("Sending... "+data); + Espruino.Core.Serial.write(code, true, function() { + // give 5 seconds for sending with save and 2 seconds without save + var count = Espruino.Config.SAVE_ON_SEND ? 50 : 20; + setTimeout(function cb() { + if (Espruino.Core.Terminal!==undefined && + Espruino.Core.Terminal.getTerminalLine()!=">") { + count--; + if (count>0) { + setTimeout(cb, 100); + } else { + Espruino.Core.Notifications.error("Prompt not detected - upload failed. Trying to recover..."); + Espruino.Core.Serial.write("\x03\x03echo(1)\n", false, callback); + } + } else { + if (callback) callback(); + } + }, 100); + }); + }); + }; + + /// Parse and fix issues like `if (false)\n foo` in the root scope + function reformatCode(code) { + var APPLY_LINE_NUMBERS = false; + var lineNumberOffset = 0; + var ENV = Espruino.Core.Env.getData(); + if (ENV && ENV.VERSION_MAJOR && ENV.VERSION_MINOR) { + if (ENV.VERSION_MAJOR>1 || + ENV.VERSION_MINOR>=81.086) { + if (Espruino.Config.STORE_LINE_NUMBERS) + APPLY_LINE_NUMBERS = true; + } + } + // Turn cr/lf into just lf (eg. windows -> unix) + code = code.replace(/\r\n/g,"\n"); + // First off, try and fix funky characters + for (var i=0;i255) && ch!=9/*Tab*/ && ch!=10/*LF*/ && ch!=13/*CR*/) { + console.warn("Funky character code "+ch+" at position "+i+". Replacing with ?"); + code = code.substr(0,i)+"?"+code.substr(i+1); + } + } + + /* Search for lines added to the start of the code by the module handler. + Ideally there would be a better way of doing this so line numbers stayed correct, + but this hack works for now. Fixes EspruinoWebIDE#140 */ + if (APPLY_LINE_NUMBERS) { + var l = code.split("\n"); + var i = 0; + while (l[i] && (l[i].substr(0,8)=="Modules." || + l[i].substr(0,8)=="setTime(")) i++; + lineNumberOffset = -i; + } + + var resultCode = "\x10"; // 0x10 = echo off for line + /** we're looking for: + * `a = \n b` + * `for (.....) \n X` + * `if (.....) \n X` + * `if (.....) { } \n else foo` + * `while (.....) \n X` + * `do \n X` + * `function (.....) \n X` + * `function N(.....) \n X` + * `var a \n , b` `var a = 0 \n, b` + * `var a, \n b` `var a = 0, \n b` + * `a \n . b` + * `foo() \n . b` + * `try { } \n catch \n () \n {}` + * + * These are divided into two groups - where there are brackets + * after the keyword (statementBeforeBrackets) and where there aren't + * (statement) + * + * We fix them by replacing \n with what you get when you press + * Alt+Enter (Ctrl + LF). This tells Espruino that it's a newline + * but NOT to execute. + */ + var lex = Espruino.Core.Utils.getLexer(code); + var brackets = 0; + var curlyBrackets = 0; + var statementBeforeBrackets = false; + var statement = false; + var varDeclaration = false; + var lastIdx = 0; + var lastTok = {str:""}; + var tok = lex.next(); + while (tok!==undefined) { + var previousString = code.substring(lastIdx, tok.startIdx); + var tokenString = code.substring(tok.startIdx, tok.endIdx); + //console.log("prev "+JSON.stringify(previousString)+" next "+tokenString); + + /* Inserting Alt-Enter newline, which adds newline without trying + to execute */ + if (brackets>0 || // we have brackets - sending the alt-enter special newline means Espruino doesn't have to do a search itself - faster. + statement || // statement was before brackets - expecting something else + statementBeforeBrackets || // we have an 'if'/etc + varDeclaration || // variable declaration then newline + tok.str=="," || // comma on newline - there was probably something before + tok.str=="." || // dot on newline - there was probably something before + tok.str=="+" || tok.str=="-" || // +/- on newline - there was probably something before + tok.str=="=" || // equals on newline - there was probably something before + tok.str=="else" || // else on newline + lastTok.str=="else" || // else befgore newline + tok.str=="catch" || // catch on newline - part of try..catch + lastTok.str=="catch" + ) { + //console.log("Possible"+JSON.stringify(previousString)); + previousString = previousString.replace(/\n/g, "\x1B\x0A"); + } + + var previousBrackets = brackets; + if (tok.str=="(" || tok.str=="{" || tok.str=="[") brackets++; + if (tok.str=="{") curlyBrackets++; + if (tok.str==")" || tok.str=="}" || tok.str=="]") brackets--; + if (tok.str=="}") curlyBrackets--; + + if (brackets==0) { + if (tok.str=="for" || tok.str=="if" || tok.str=="while" || tok.str=="function" || tok.str=="throw") { + statementBeforeBrackets = true; + varDeclaration = false; + } else if (tok.str=="var") { + varDeclaration = true; + } else if (tok.type=="ID" && lastTok.str=="function") { + statementBeforeBrackets = true; + } else if (tok.str=="try" || tok.str=="catch") { + statementBeforeBrackets = true; + } else if (tok.str==")" && statementBeforeBrackets) { + statementBeforeBrackets = false; + statement = true; + } else if (["=","^","&&","||","+","+=","-","-=","*","*=","/","/=","%","%=","&","&=","|","|="].indexOf(tok.str)>=0) { + statement = true; + } else { + if (tok.str==";") varDeclaration = false; + statement = false; + statementBeforeBrackets = false; + } + } + /* If we're at root scope and had whitespace/comments between code, + remove it all and replace it with a single newline and a + 0x10 (echo off for line) character. However DON'T do this if we had + an alt-enter in the line, as it was there to stop us executing + prematurely */ + if (previousBrackets==0 && + previousString.indexOf("\n")>=0 && + previousString.indexOf("\x1B\x0A")<0) { + previousString = "\n\x10"; + // Apply line numbers to each new line sent, to aid debugger + if (APPLY_LINE_NUMBERS && tok.lineNumber && (tok.lineNumber+lineNumberOffset)>0) { + // Esc [ 1234 d + // This is the 'set line number' command that we're abusing :) + previousString += "\x1B\x5B"+(tok.lineNumber+lineNumberOffset)+"d"; + } + } + + // add our stuff back together + resultCode += previousString+tokenString; + // next + lastIdx = tok.endIdx; + lastTok = tok; + tok = lex.next(); + } + //console.log(resultCode); + if (brackets>0) { + Espruino.Core.Notifications.error("You have more open brackets than close brackets. Please see the hints in the Editor window."); + return undefined; + } + if (brackets<0) { + Espruino.Core.Notifications.error("You have more close brackets than open brackets. Please see the hints in the Editor window."); + return undefined; + } + return resultCode; + }; + + Espruino.Core.CodeWriter = { + init : init, + writeToEspruino : writeToEspruino, + }; +}()); +/** + Copyright 2014 Gordon Williams (gw@pur3.co.uk) + + This Source Code is subject to the terms of the Mozilla Public + License, v2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + ------------------------------------------------------------------ + Automatically load any referenced modules + ------------------------------------------------------------------ +**/ +"use strict"; +(function(){ + + function init() { + Espruino.Core.Config.add("MODULE_URL", { + section : "Communications", + name : "Module URL", + description : "Where to search online for modules when `require()` is used", + type : "string", + defaultValue : "https://www.espruino.com/modules" + }); + Espruino.Core.Config.add("MODULE_EXTENSIONS", { + section : "Communications", + name : "Module Extensions", + description : "The file extensions to use for each module. These are checked in order and the first that exists is used. One or more file extensions (including the dot) separated by `|`", + type : "string", + defaultValue : ".min.js|.js" + }); + Espruino.Core.Config.add("MODULE_AS_FUNCTION", { + section : "Communications", + name : "Modules uploaded as functions", + description : "Espruino 1v90 and later ONLY. Upload modules as Functions, allowing any functions inside them to be loaded directly from flash when 'Save on Send' is enabled.", + type : "boolean", + defaultValue : true + }); + + Espruino.Core.Config.add("MODULE_PROXY_ENABLED", { + section : "Communications", + name : "Enable Proxy", + description : "Enable Proxy for loading the modules when `require()` is used (only in native IDE)", + type : "boolean", + defaultValue : false + }); + + Espruino.Core.Config.add("MODULE_PROXY_URL", { + section : "Communications", + name : "Proxy URL", + description : "Proxy URL for loading the modules when `require()` is used (only in native IDE)", + type : "string", + defaultValue : "" + }); + + Espruino.Core.Config.add("MODULE_PROXY_PORT", { + section : "Communications", + name : "Proxy Port", + description : "Proxy Port for loading the modules when `require()` is used (only in native IDE)", + type : "string", + defaultValue : "" + }); + + // When code is sent to Espruino, search it for modules and add extra code required to load them + Espruino.addProcessor("transformForEspruino", function(code, callback) { + loadModules(code, callback); + }); + + // Append the 'getModule' processor as the last (plugins get initialized after Espruino.Core modules) + Espruino.Plugins.CoreModules = { + init: function() { + Espruino.addProcessor("getModule", function(data, callback) { + if (data.moduleCode!==undefined) { // already provided be previous getModule processor + return callback(data); + } + + fetchGetModule(data, callback); + }); + } + }; + } + + function isBuiltIn(module) { + var d = Espruino.Core.Env.getData(); + // If we got data from the device itself, use that as the + // definitive answer + if ("string" == typeof d.MODULES) + return d.MODULES.split(",").indexOf(module)>=0; + // Otherwise try and figure it out from JSON + if ("info" in d && + "builtin_modules" in d.info && + d.info.builtin_modules.indexOf(module)>=0) + return true; + // Otherwise assume we don't have it + return false; + } + + /** Find any instances of require(...) in the code string and return a list */ + var getModulesRequired = function(code) { + var modules = []; + + var lex = Espruino.Core.Utils.getLexer(code); + var tok = lex.next(); + var state = 0; + while (tok!==undefined) { + if (state==0 && tok.str=="require") { + state=1; + } else if (state==1 && tok.str=="(") { + state=2; + } else if (state==2 && (tok.type=="STRING")) { + state=0; + var module = tok.value; + if (!isBuiltIn(module) && modules.indexOf(module)<0) + modules.push(module); + } else + state = 0; + tok = lex.next(); + } + + return modules; + }; + + /** Download modules from MODULE_URL/.. */ + function fetchGetModule(data, callback) { + var fullModuleName = data.moduleName; + + // try and load the module the old way... + console.log("loadModule("+fullModuleName+")"); + + var urls = []; // Array of where to look for this module + var modName; // Simple name of the module + if(Espruino.Core.Utils.isURL(fullModuleName)) { + modName = fullModuleName.substr(fullModuleName.lastIndexOf("/") + 1).split(".")[0]; + urls = [ fullModuleName ]; + } else { + modName = fullModuleName; + Espruino.Config.MODULE_URL.split("|").forEach(function (url) { + url = url.trim(); + if (url.length!=0) + Espruino.Config.MODULE_EXTENSIONS.split("|").forEach(function (extension) { + urls.push(url + "/" + fullModuleName + extension); + }) + }); + }; + + // Recursively go through all the urls + (function download(urls) { + if (urls.length==0) { + return callback(data); + } + var dlUrl = urls[0]; + Espruino.Core.Utils.getURL(dlUrl, function (code) { + if (code!==undefined) { + // we got it! + data.moduleCode = code; + data.isMinified = dlUrl.substr(-7)==".min.js"; + return callback(data); + } else { + // else try next + download(urls.slice(1)); + } + }); + })(urls); + } + + + /** Called from loadModule when a module is loaded. Parse it for other modules it might use + * and resolve dfd after all submodules have been loaded */ + function moduleLoaded(resolve, requires, modName, data, loadedModuleData, alreadyMinified){ + // Check for any modules used from this module that we don't already have + var newRequires = getModulesRequired(data); + console.log(" - "+modName+" requires "+JSON.stringify(newRequires)); + // if we need new modules, set them to load and get their promises + var newPromises = []; + for (var i in newRequires) { + if (requires.indexOf(newRequires[i])<0) { + console.log(" Queueing "+newRequires[i]); + requires.push(newRequires[i]); + newPromises.push(loadModule(requires, newRequires[i], loadedModuleData)); + } else { + console.log(" Already loading "+newRequires[i]); + } + } + + var loadProcessedModule = function (module) { + // if we needed to load something, wait until it's loaded before resolving this + Promise.all(newPromises).then(function(){ + // add the module to end of our array + if (Espruino.Config.MODULE_AS_FUNCTION) + loadedModuleData.push("Modules.addCached(" + JSON.stringify(module.name) + ",function(){" + module.code + "});"); + else + loadedModuleData.push("Modules.addCached(" + JSON.stringify(module.name) + "," + JSON.stringify(module.code) + ");"); + // We're done + resolve(); + }); + } + if (alreadyMinified) + loadProcessedModule({code:data,name:modName}); + else + Espruino.callProcessor("transformModuleForEspruino", {code:data,name:modName}, loadProcessedModule); + } + + /** Given a module name (which could be a URL), try and find it. Return + * a deferred thingybob which signals when we're done. */ + function loadModule(requires, fullModuleName, loadedModuleData) { + return new Promise(function(resolve, reject) { + // First off, try and find this module using callProcessor + Espruino.callProcessor("getModule", + { moduleName:fullModuleName, moduleCode:undefined, isMinified:false }, + function(data) { + if (data.moduleCode===undefined) { + Espruino.Core.Notifications.warning("Module "+fullModuleName+" not found"); + return resolve(); + } + + // great! it found something. Use it. + moduleLoaded(resolve, requires, fullModuleName, data.moduleCode, loadedModuleData, data.isMinified); + }); + }); + } + + /** Finds instances of 'require' and then ensures that + those modules are loaded into the module cache beforehand + (by inserting the relevant 'addCached' commands into 'code' */ + function loadModules(code, callback){ + var loadedModuleData = []; + var requires = getModulesRequired(code); + if (requires.length == 0) { + // no modules needed - just return + callback(code); + } else { + Espruino.Core.Status.setStatus("Loading modules"); + // Kick off the module loading (each returns a promise) + var promises = requires.map(function (moduleName) { + return loadModule(requires, moduleName, loadedModuleData); + }); + // When all promises are complete + Promise.all(promises).then(function(){ + callback(loadedModuleData.join("\n") + "\n" + code); + }); + } + }; + + + Espruino.Core.Modules = { + init : init + }; +}()); +/** + Copyright 2014 Gordon Williams (gw@pur3.co.uk) + + This Source Code is subject to the terms of the Mozilla Public + License, v2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + ------------------------------------------------------------------ + Board Environment variables (process.env) - queried when board connects + ------------------------------------------------------------------ +**/ +"use strict"; +(function(){ + + var environmentData = {}; + var boardData = {}; + + function init() { + Espruino.Core.Config.add("ENV_ON_CONNECT", { + section : "Communications", + name : "Request board details on connect", + description : 'Just after the board is connected, should we query `process.env` to find out which board we\'re connected to? '+ + 'This enables the Web IDE\'s code completion, compiler features, and firmware update notice.', + type : "boolean", + defaultValue : true, + }); + + Espruino.addProcessor("connected", function(data, callback) { + // Give us some time for any stored data to come in + setTimeout(queryBoardProcess, 200, data, callback); + }); + } + + function queryBoardProcess(data, callback) { + if ((!Espruino.Config.ENV_ON_CONNECT) || + (Espruino.Core.MenuFlasher && Espruino.Core.MenuFlasher.isFlashing())) { + return callback(data); + } + + Espruino.Core.Utils.executeExpression("process.env", function(result) { + var json = {}; + if (result!==undefined) { + try { + json = JSON.parse(result); + } catch (e) { + console.log("JSON parse failed - " + e + " in " + JSON.stringify(result)); + } + } + if (Object.keys(json).length==0) { + Espruino.Core.Notifications.error("Unable to retrieve board information.\nConnection Error?"); + // make sure we don't remember a previous board's info + json = { + VERSION : undefined, + BOARD : undefined, + MODULES : undefined, + EXPTR : undefined + }; + } else { + if (json.BOARD && json.VERSION) + Espruino.Core.Notifications.info("Found " +json.BOARD+", "+json.VERSION); + } + // now process the enviroment variables + for (var k in json) { + boardData[k] = json[k]; + environmentData[k] = json[k]; + } + if (environmentData.VERSION) { + var v = environmentData.VERSION; + var vIdx = v.indexOf("v"); + if (vIdx>=0) { + environmentData.VERSION_MAJOR = parseInt(v.substr(0,vIdx)); + var minor = v.substr(vIdx+1); + var dot = minor.indexOf("."); + if (dot>=0) + environmentData.VERSION_MINOR = parseInt(minor.substr(0,dot)) + parseInt(minor.substr(dot+1))*0.001; + else + environmentData.VERSION_MINOR = parseFloat(minor); + } + } + + Espruino.callProcessor("environmentVar", environmentData, function(envData) { + environmentData = envData; + callback(data); + }); + }); + } + + /** Get all data merged in from the board */ + function getData() { + return environmentData; + } + + /** Get just the board's environment data */ + function getBoardData() { + return boardData; + } + + /** Get a list of boards that we know about */ + function getBoardList(callback) { + var jsonDir = Espruino.Config.BOARD_JSON_URL; + + // ensure jsonDir ends with slash + if (jsonDir.indexOf('/', jsonDir.length - 1) === -1) { + jsonDir += '/'; + } + + Espruino.Core.Utils.getJSONURL(jsonDir + "boards.json", function(boards){ + // now load all the individual JSON files + var promises = []; + for (var boardId in boards) { + promises.push((function() { + var id = boardId; + return new Promise(function(resolve, reject) { + Espruino.Core.Utils.getJSONURL(jsonDir + boards[boardId].json, function (data) { + boards[id]["json"] = data; + resolve(); + }); + }); + })()); + } + + // When all are loaded, load the callback + Promise.all(promises).then(function() { + callback(boards); + }); + }); + } + + Espruino.Core.Env = { + init : init, + getData : getData, + getBoardData : getBoardData, + getBoardList : getBoardList, + }; +}()); +/** + Copyright 2014 Gordon Williams (gw@pur3.co.uk) + + This Source Code is subject to the terms of the Mozilla Public + License, v2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + ------------------------------------------------------------------ + Try and get any URLS that are from GitHub + ------------------------------------------------------------------ +**/ +"use strict"; +(function(){ + + function init() { + Espruino.addProcessor("getURL", getGitHub); + } + + function getGitHub(data, callback) { + var match = data.url.match(/^https?:\/\/github.com\/([^\/]+)\/([^\/]+)\/blob\/([^\/]+)\/(.*)$/); + if (match) { + var git = { + owner : match[1], + repo : match[2], + branch : match[3], + path : match[4] + }; + + var url = "https://raw.githubusercontent.com/"+git.owner+"/"+git.repo+"/"+git.branch+"/"+git.path; + console.log("Found GitHub", JSON.stringify(git)); + callback({url: url}); + } else + callback(data); // no match - continue as normal + } + + Espruino.Plugins.GetGitHub = { + init : init, + }; +}()); +/*! https://mths.be/utf8js v2.0.0 by @mathias */ +;(function(root) { + + // Detect free variables `exports` + var freeExports = typeof exports == 'object' && exports; + + // Detect free variable `module` + var freeModule = typeof module == 'object' && module && + module.exports == freeExports && module; + + // Detect free variable `global`, from Node.js or Browserified code, + // and use it as `root` + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + var stringFromCharCode = String.fromCharCode; + + // Taken from https://mths.be/punycode + function ucs2decode(string) { + var output = []; + var counter = 0; + var length = string.length; + var value; + var extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // high surrogate, and there is a next character + extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // low surrogate + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // unmatched surrogate; only append this code unit, in case the next + // code unit is the high surrogate of a surrogate pair + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } + + // Taken from https://mths.be/punycode + function ucs2encode(array) { + var length = array.length; + var index = -1; + var value; + var output = ''; + while (++index < length) { + value = array[index]; + if (value > 0xFFFF) { + value -= 0x10000; + output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); + value = 0xDC00 | value & 0x3FF; + } + output += stringFromCharCode(value); + } + return output; + } + + function checkScalarValue(codePoint) { + if (codePoint >= 0xD800 && codePoint <= 0xDFFF) { + throw Error( + 'Lone surrogate U+' + codePoint.toString(16).toUpperCase() + + ' is not a scalar value' + ); + } + } + /*--------------------------------------------------------------------------*/ + + function createByte(codePoint, shift) { + return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80); + } + + function encodeCodePoint(codePoint) { + if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence + return stringFromCharCode(codePoint); + } + var symbol = ''; + if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence + symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0); + } + else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence + checkScalarValue(codePoint); + symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0); + symbol += createByte(codePoint, 6); + } + else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence + symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0); + symbol += createByte(codePoint, 12); + symbol += createByte(codePoint, 6); + } + symbol += stringFromCharCode((codePoint & 0x3F) | 0x80); + return symbol; + } + + function utf8encode(string) { + var codePoints = ucs2decode(string); + var length = codePoints.length; + var index = -1; + var codePoint; + var byteString = ''; + while (++index < length) { + codePoint = codePoints[index]; + byteString += encodeCodePoint(codePoint); + } + return byteString; + } + + /*--------------------------------------------------------------------------*/ + + function readContinuationByte() { + if (byteIndex >= byteCount) { + throw Error('Invalid byte index'); + } + + var continuationByte = byteArray[byteIndex] & 0xFF; + byteIndex++; + + if ((continuationByte & 0xC0) == 0x80) { + return continuationByte & 0x3F; + } + + // If we end up here, it’s not a continuation byte + throw Error('Invalid continuation byte'); + } + + function decodeSymbol() { + var byte1; + var byte2; + var byte3; + var byte4; + var codePoint; + + if (byteIndex > byteCount) { + throw Error('Invalid byte index'); + } + + if (byteIndex == byteCount) { + return false; + } + + // Read first byte + byte1 = byteArray[byteIndex] & 0xFF; + byteIndex++; + + // 1-byte sequence (no continuation bytes) + if ((byte1 & 0x80) == 0) { + return byte1; + } + + // 2-byte sequence + if ((byte1 & 0xE0) == 0xC0) { + var byte2 = readContinuationByte(); + codePoint = ((byte1 & 0x1F) << 6) | byte2; + if (codePoint >= 0x80) { + return codePoint; + } else { + throw Error('Invalid continuation byte'); + } + } + + // 3-byte sequence (may include unpaired surrogates) + if ((byte1 & 0xF0) == 0xE0) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3; + if (codePoint >= 0x0800) { + checkScalarValue(codePoint); + return codePoint; + } else { + throw Error('Invalid continuation byte'); + } + } + + // 4-byte sequence + if ((byte1 & 0xF8) == 0xF0) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + byte4 = readContinuationByte(); + codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) | + (byte3 << 0x06) | byte4; + if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) { + return codePoint; + } + } + + throw Error('Invalid UTF-8 detected'); + } + + var byteArray; + var byteCount; + var byteIndex; + function utf8decode(byteString) { + byteArray = ucs2decode(byteString); + byteCount = byteArray.length; + byteIndex = 0; + var codePoints = []; + var tmp; + while ((tmp = decodeSymbol()) !== false) { + codePoints.push(tmp); + } + return ucs2encode(codePoints); + } + + /*--------------------------------------------------------------------------*/ + + var utf8 = { + 'version': '2.0.0', + 'encode': utf8encode, + 'decode': utf8decode + }; + + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + typeof define == 'function' && + typeof define.amd == 'object' && + define.amd + ) { + define(function() { + return utf8; + }); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { // in Node.js or RingoJS v0.8.0+ + freeModule.exports = utf8; + } else { // in Narwhal or RingoJS v0.7.0- + var object = {}; + var hasOwnProperty = object.hasOwnProperty; + for (var key in utf8) { + hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]); + } + } + } else { // in Rhino or a web browser + root.utf8 = utf8; + } + +}(this)); +/** + Copyright 2015 Gordon Williams (gw@pur3.co.uk), + Victor Nakoryakov (victor@amperka.ru) + + This Source Code is subject to the terms of the Mozilla Public + License, v2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + ------------------------------------------------------------------ + Escape non-ASCII characters into \xHH UTF-8 sequences before send + ------------------------------------------------------------------ +**/ +"use strict"; +(function(){ + + // Node.js doesn't have utf8 installed + var utf8lib; + if ("undefined"==typeof utf8) { + if ("undefined"!=typeof require) { + console.log("Loading UTF8 with require"); + utf8lib = require('utf8'); + } else { + console.log("WARNING: Loading placeholder UTF8"); + utf8lib = { encode : function(c){return c} }; + } + } else { + console.log("UTF8 Library loaded successfully"); + utf8lib = utf8; + } + + function init() { + Espruino.addProcessor("transformForEspruino", function(code, callback) { + escapeUnicode(code, callback); + }); + } + + function escapeUnicode(code, callback) { + // Only correct unicode inside strings + var newCode = ""; + var lex = Espruino.Core.Utils.getLexer(code); + var lastIdx = 0; + var tok = lex.next(); + while (tok!==undefined) { + var previousString = code.substring(lastIdx, tok.startIdx); + var tokenString = code.substring(tok.startIdx, tok.endIdx); + if (tok.type=="STRING") { + var newTokenString = ""; + for (var i=0;i= 255) + newTokenString += escapeChar(tokenString[i]); + else + newTokenString += tokenString[i]; + } + tokenString = newTokenString; + } + newCode += previousString+tokenString; + // next + lastIdx = tok.endIdx; + tok = lex.next(); + } + newCode += code.substring(lastIdx); + callback(newCode); + } + + function escapeChar(c) { + // encode char into UTF-8 sequence in form of \xHH codes + var result = ''; + utf8lib.encode(c).split('').forEach(function(c) { + var code = c.charCodeAt(0) & 0xFF; + result += "\\x"; + if (code < 0x10) result += '0'; + result += code.toString(16).toUpperCase(); + }); + + return result; + } + + Espruino.Plugins.Unicode = { + init : init, + }; +}()); +(function webpackUniversalModuleDefinition(root, factory) { +/* istanbul ignore next */ + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); +/* istanbul ignore next */ + else if(typeof exports === 'object') + exports["esprima"] = factory(); + else + root["esprima"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/* istanbul ignore if */ +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + /* + Copyright JS Foundation and other contributors, https://js.foundation/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + Object.defineProperty(exports, "__esModule", { value: true }); + var comment_handler_1 = __webpack_require__(1); + var jsx_parser_1 = __webpack_require__(3); + var parser_1 = __webpack_require__(8); + var tokenizer_1 = __webpack_require__(15); + function parse(code, options, delegate) { + var commentHandler = null; + var proxyDelegate = function (node, metadata) { + if (delegate) { + delegate(node, metadata); + } + if (commentHandler) { + commentHandler.visit(node, metadata); + } + }; + var parserDelegate = (typeof delegate === 'function') ? proxyDelegate : null; + var collectComment = false; + if (options) { + collectComment = (typeof options.comment === 'boolean' && options.comment); + var attachComment = (typeof options.attachComment === 'boolean' && options.attachComment); + if (collectComment || attachComment) { + commentHandler = new comment_handler_1.CommentHandler(); + commentHandler.attach = attachComment; + options.comment = true; + parserDelegate = proxyDelegate; + } + } + var isModule = false; + if (options && typeof options.sourceType === 'string') { + isModule = (options.sourceType === 'module'); + } + var parser; + if (options && typeof options.jsx === 'boolean' && options.jsx) { + parser = new jsx_parser_1.JSXParser(code, options, parserDelegate); + } + else { + parser = new parser_1.Parser(code, options, parserDelegate); + } + var program = isModule ? parser.parseModule() : parser.parseScript(); + var ast = program; + if (collectComment && commentHandler) { + ast.comments = commentHandler.comments; + } + if (parser.config.tokens) { + ast.tokens = parser.tokens; + } + if (parser.config.tolerant) { + ast.errors = parser.errorHandler.errors; + } + return ast; + } + exports.parse = parse; + function parseModule(code, options, delegate) { + var parsingOptions = options || {}; + parsingOptions.sourceType = 'module'; + return parse(code, parsingOptions, delegate); + } + exports.parseModule = parseModule; + function parseScript(code, options, delegate) { + var parsingOptions = options || {}; + parsingOptions.sourceType = 'script'; + return parse(code, parsingOptions, delegate); + } + exports.parseScript = parseScript; + function tokenize(code, options, delegate) { + var tokenizer = new tokenizer_1.Tokenizer(code, options); + var tokens; + tokens = []; + try { + while (true) { + var token = tokenizer.getNextToken(); + if (!token) { + break; + } + if (delegate) { + token = delegate(token); + } + tokens.push(token); + } + } + catch (e) { + tokenizer.errorHandler.tolerate(e); + } + if (tokenizer.errorHandler.tolerant) { + tokens.errors = tokenizer.errors(); + } + return tokens; + } + exports.tokenize = tokenize; + var syntax_1 = __webpack_require__(2); + exports.Syntax = syntax_1.Syntax; + // Sync with *.json manifests. + exports.version = '4.0.1'; + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + var syntax_1 = __webpack_require__(2); + var CommentHandler = (function () { + function CommentHandler() { + this.attach = false; + this.comments = []; + this.stack = []; + this.leading = []; + this.trailing = []; + } + CommentHandler.prototype.insertInnerComments = function (node, metadata) { + // innnerComments for properties empty block + // `function a() {/** comments **\/}` + if (node.type === syntax_1.Syntax.BlockStatement && node.body.length === 0) { + var innerComments = []; + for (var i = this.leading.length - 1; i >= 0; --i) { + var entry = this.leading[i]; + if (metadata.end.offset >= entry.start) { + innerComments.unshift(entry.comment); + this.leading.splice(i, 1); + this.trailing.splice(i, 1); + } + } + if (innerComments.length) { + node.innerComments = innerComments; + } + } + }; + CommentHandler.prototype.findTrailingComments = function (metadata) { + var trailingComments = []; + if (this.trailing.length > 0) { + for (var i = this.trailing.length - 1; i >= 0; --i) { + var entry_1 = this.trailing[i]; + if (entry_1.start >= metadata.end.offset) { + trailingComments.unshift(entry_1.comment); + } + } + this.trailing.length = 0; + return trailingComments; + } + var entry = this.stack[this.stack.length - 1]; + if (entry && entry.node.trailingComments) { + var firstComment = entry.node.trailingComments[0]; + if (firstComment && firstComment.range[0] >= metadata.end.offset) { + trailingComments = entry.node.trailingComments; + delete entry.node.trailingComments; + } + } + return trailingComments; + }; + CommentHandler.prototype.findLeadingComments = function (metadata) { + var leadingComments = []; + var target; + while (this.stack.length > 0) { + var entry = this.stack[this.stack.length - 1]; + if (entry && entry.start >= metadata.start.offset) { + target = entry.node; + this.stack.pop(); + } + else { + break; + } + } + if (target) { + var count = target.leadingComments ? target.leadingComments.length : 0; + for (var i = count - 1; i >= 0; --i) { + var comment = target.leadingComments[i]; + if (comment.range[1] <= metadata.start.offset) { + leadingComments.unshift(comment); + target.leadingComments.splice(i, 1); + } + } + if (target.leadingComments && target.leadingComments.length === 0) { + delete target.leadingComments; + } + return leadingComments; + } + for (var i = this.leading.length - 1; i >= 0; --i) { + var entry = this.leading[i]; + if (entry.start <= metadata.start.offset) { + leadingComments.unshift(entry.comment); + this.leading.splice(i, 1); + } + } + return leadingComments; + }; + CommentHandler.prototype.visitNode = function (node, metadata) { + if (node.type === syntax_1.Syntax.Program && node.body.length > 0) { + return; + } + this.insertInnerComments(node, metadata); + var trailingComments = this.findTrailingComments(metadata); + var leadingComments = this.findLeadingComments(metadata); + if (leadingComments.length > 0) { + node.leadingComments = leadingComments; + } + if (trailingComments.length > 0) { + node.trailingComments = trailingComments; + } + this.stack.push({ + node: node, + start: metadata.start.offset + }); + }; + CommentHandler.prototype.visitComment = function (node, metadata) { + var type = (node.type[0] === 'L') ? 'Line' : 'Block'; + var comment = { + type: type, + value: node.value + }; + if (node.range) { + comment.range = node.range; + } + if (node.loc) { + comment.loc = node.loc; + } + this.comments.push(comment); + if (this.attach) { + var entry = { + comment: { + type: type, + value: node.value, + range: [metadata.start.offset, metadata.end.offset] + }, + start: metadata.start.offset + }; + if (node.loc) { + entry.comment.loc = node.loc; + } + node.type = type; + this.leading.push(entry); + this.trailing.push(entry); + } + }; + CommentHandler.prototype.visit = function (node, metadata) { + if (node.type === 'LineComment') { + this.visitComment(node, metadata); + } + else if (node.type === 'BlockComment') { + this.visitComment(node, metadata); + } + else if (this.attach) { + this.visitNode(node, metadata); + } + }; + return CommentHandler; + }()); + exports.CommentHandler = CommentHandler; + + +/***/ }, +/* 2 */ +/***/ function(module, exports) { + + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.Syntax = { + AssignmentExpression: 'AssignmentExpression', + AssignmentPattern: 'AssignmentPattern', + ArrayExpression: 'ArrayExpression', + ArrayPattern: 'ArrayPattern', + ArrowFunctionExpression: 'ArrowFunctionExpression', + AwaitExpression: 'AwaitExpression', + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ClassBody: 'ClassBody', + ClassDeclaration: 'ClassDeclaration', + ClassExpression: 'ClassExpression', + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DoWhileStatement: 'DoWhileStatement', + DebuggerStatement: 'DebuggerStatement', + EmptyStatement: 'EmptyStatement', + ExportAllDeclaration: 'ExportAllDeclaration', + ExportDefaultDeclaration: 'ExportDefaultDeclaration', + ExportNamedDeclaration: 'ExportNamedDeclaration', + ExportSpecifier: 'ExportSpecifier', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForOfStatement: 'ForOfStatement', + ForInStatement: 'ForInStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + Identifier: 'Identifier', + IfStatement: 'IfStatement', + ImportDeclaration: 'ImportDeclaration', + ImportDefaultSpecifier: 'ImportDefaultSpecifier', + ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', + ImportSpecifier: 'ImportSpecifier', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + MetaProperty: 'MetaProperty', + MethodDefinition: 'MethodDefinition', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + ObjectPattern: 'ObjectPattern', + Program: 'Program', + Property: 'Property', + RestElement: 'RestElement', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SpreadElement: 'SpreadElement', + Super: 'Super', + SwitchCase: 'SwitchCase', + SwitchStatement: 'SwitchStatement', + TaggedTemplateExpression: 'TaggedTemplateExpression', + TemplateElement: 'TemplateElement', + TemplateLiteral: 'TemplateLiteral', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement', + YieldExpression: 'YieldExpression' + }; + + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; +/* istanbul ignore next */ + var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + var character_1 = __webpack_require__(4); + var JSXNode = __webpack_require__(5); + var jsx_syntax_1 = __webpack_require__(6); + var Node = __webpack_require__(7); + var parser_1 = __webpack_require__(8); + var token_1 = __webpack_require__(13); + var xhtml_entities_1 = __webpack_require__(14); + token_1.TokenName[100 /* Identifier */] = 'JSXIdentifier'; + token_1.TokenName[101 /* Text */] = 'JSXText'; + // Fully qualified element name, e.g. returns "svg:path" + function getQualifiedElementName(elementName) { + var qualifiedName; + switch (elementName.type) { + case jsx_syntax_1.JSXSyntax.JSXIdentifier: + var id = elementName; + qualifiedName = id.name; + break; + case jsx_syntax_1.JSXSyntax.JSXNamespacedName: + var ns = elementName; + qualifiedName = getQualifiedElementName(ns.namespace) + ':' + + getQualifiedElementName(ns.name); + break; + case jsx_syntax_1.JSXSyntax.JSXMemberExpression: + var expr = elementName; + qualifiedName = getQualifiedElementName(expr.object) + '.' + + getQualifiedElementName(expr.property); + break; + /* istanbul ignore next */ + default: + break; + } + return qualifiedName; + } + var JSXParser = (function (_super) { + __extends(JSXParser, _super); + function JSXParser(code, options, delegate) { + return _super.call(this, code, options, delegate) || this; + } + JSXParser.prototype.parsePrimaryExpression = function () { + return this.match('<') ? this.parseJSXRoot() : _super.prototype.parsePrimaryExpression.call(this); + }; + JSXParser.prototype.startJSX = function () { + // Unwind the scanner before the lookahead token. + this.scanner.index = this.startMarker.index; + this.scanner.lineNumber = this.startMarker.line; + this.scanner.lineStart = this.startMarker.index - this.startMarker.column; + }; + JSXParser.prototype.finishJSX = function () { + // Prime the next lookahead. + this.nextToken(); + }; + JSXParser.prototype.reenterJSX = function () { + this.startJSX(); + this.expectJSX('}'); + // Pop the closing '}' added from the lookahead. + if (this.config.tokens) { + this.tokens.pop(); + } + }; + JSXParser.prototype.createJSXNode = function () { + this.collectComments(); + return { + index: this.scanner.index, + line: this.scanner.lineNumber, + column: this.scanner.index - this.scanner.lineStart + }; + }; + JSXParser.prototype.createJSXChildNode = function () { + return { + index: this.scanner.index, + line: this.scanner.lineNumber, + column: this.scanner.index - this.scanner.lineStart + }; + }; + JSXParser.prototype.scanXHTMLEntity = function (quote) { + var result = '&'; + var valid = true; + var terminated = false; + var numeric = false; + var hex = false; + while (!this.scanner.eof() && valid && !terminated) { + var ch = this.scanner.source[this.scanner.index]; + if (ch === quote) { + break; + } + terminated = (ch === ';'); + result += ch; + ++this.scanner.index; + if (!terminated) { + switch (result.length) { + case 2: + // e.g. '{' + numeric = (ch === '#'); + break; + case 3: + if (numeric) { + // e.g. 'A' + hex = (ch === 'x'); + valid = hex || character_1.Character.isDecimalDigit(ch.charCodeAt(0)); + numeric = numeric && !hex; + } + break; + default: + valid = valid && !(numeric && !character_1.Character.isDecimalDigit(ch.charCodeAt(0))); + valid = valid && !(hex && !character_1.Character.isHexDigit(ch.charCodeAt(0))); + break; + } + } + } + if (valid && terminated && result.length > 2) { + // e.g. 'A' becomes just '#x41' + var str = result.substr(1, result.length - 2); + if (numeric && str.length > 1) { + result = String.fromCharCode(parseInt(str.substr(1), 10)); + } + else if (hex && str.length > 2) { + result = String.fromCharCode(parseInt('0' + str.substr(1), 16)); + } + else if (!numeric && !hex && xhtml_entities_1.XHTMLEntities[str]) { + result = xhtml_entities_1.XHTMLEntities[str]; + } + } + return result; + }; + // Scan the next JSX token. This replaces Scanner#lex when in JSX mode. + JSXParser.prototype.lexJSX = function () { + var cp = this.scanner.source.charCodeAt(this.scanner.index); + // < > / : = { } + if (cp === 60 || cp === 62 || cp === 47 || cp === 58 || cp === 61 || cp === 123 || cp === 125) { + var value = this.scanner.source[this.scanner.index++]; + return { + type: 7 /* Punctuator */, + value: value, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: this.scanner.index - 1, + end: this.scanner.index + }; + } + // " ' + if (cp === 34 || cp === 39) { + var start = this.scanner.index; + var quote = this.scanner.source[this.scanner.index++]; + var str = ''; + while (!this.scanner.eof()) { + var ch = this.scanner.source[this.scanner.index++]; + if (ch === quote) { + break; + } + else if (ch === '&') { + str += this.scanXHTMLEntity(quote); + } + else { + str += ch; + } + } + return { + type: 8 /* StringLiteral */, + value: str, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: start, + end: this.scanner.index + }; + } + // ... or . + if (cp === 46) { + var n1 = this.scanner.source.charCodeAt(this.scanner.index + 1); + var n2 = this.scanner.source.charCodeAt(this.scanner.index + 2); + var value = (n1 === 46 && n2 === 46) ? '...' : '.'; + var start = this.scanner.index; + this.scanner.index += value.length; + return { + type: 7 /* Punctuator */, + value: value, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: start, + end: this.scanner.index + }; + } + // ` + if (cp === 96) { + // Only placeholder, since it will be rescanned as a real assignment expression. + return { + type: 10 /* Template */, + value: '', + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: this.scanner.index, + end: this.scanner.index + }; + } + // Identifer can not contain backslash (char code 92). + if (character_1.Character.isIdentifierStart(cp) && (cp !== 92)) { + var start = this.scanner.index; + ++this.scanner.index; + while (!this.scanner.eof()) { + var ch = this.scanner.source.charCodeAt(this.scanner.index); + if (character_1.Character.isIdentifierPart(ch) && (ch !== 92)) { + ++this.scanner.index; + } + else if (ch === 45) { + // Hyphen (char code 45) can be part of an identifier. + ++this.scanner.index; + } + else { + break; + } + } + var id = this.scanner.source.slice(start, this.scanner.index); + return { + type: 100 /* Identifier */, + value: id, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: start, + end: this.scanner.index + }; + } + return this.scanner.lex(); + }; + JSXParser.prototype.nextJSXToken = function () { + this.collectComments(); + this.startMarker.index = this.scanner.index; + this.startMarker.line = this.scanner.lineNumber; + this.startMarker.column = this.scanner.index - this.scanner.lineStart; + var token = this.lexJSX(); + this.lastMarker.index = this.scanner.index; + this.lastMarker.line = this.scanner.lineNumber; + this.lastMarker.column = this.scanner.index - this.scanner.lineStart; + if (this.config.tokens) { + this.tokens.push(this.convertToken(token)); + } + return token; + }; + JSXParser.prototype.nextJSXText = function () { + this.startMarker.index = this.scanner.index; + this.startMarker.line = this.scanner.lineNumber; + this.startMarker.column = this.scanner.index - this.scanner.lineStart; + var start = this.scanner.index; + var text = ''; + while (!this.scanner.eof()) { + var ch = this.scanner.source[this.scanner.index]; + if (ch === '{' || ch === '<') { + break; + } + ++this.scanner.index; + text += ch; + if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) { + ++this.scanner.lineNumber; + if (ch === '\r' && this.scanner.source[this.scanner.index] === '\n') { + ++this.scanner.index; + } + this.scanner.lineStart = this.scanner.index; + } + } + this.lastMarker.index = this.scanner.index; + this.lastMarker.line = this.scanner.lineNumber; + this.lastMarker.column = this.scanner.index - this.scanner.lineStart; + var token = { + type: 101 /* Text */, + value: text, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart, + start: start, + end: this.scanner.index + }; + if ((text.length > 0) && this.config.tokens) { + this.tokens.push(this.convertToken(token)); + } + return token; + }; + JSXParser.prototype.peekJSXToken = function () { + var state = this.scanner.saveState(); + this.scanner.scanComments(); + var next = this.lexJSX(); + this.scanner.restoreState(state); + return next; + }; + // Expect the next JSX token to match the specified punctuator. + // If not, an exception will be thrown. + JSXParser.prototype.expectJSX = function (value) { + var token = this.nextJSXToken(); + if (token.type !== 7 /* Punctuator */ || token.value !== value) { + this.throwUnexpectedToken(token); + } + }; + // Return true if the next JSX token matches the specified punctuator. + JSXParser.prototype.matchJSX = function (value) { + var next = this.peekJSXToken(); + return next.type === 7 /* Punctuator */ && next.value === value; + }; + JSXParser.prototype.parseJSXIdentifier = function () { + var node = this.createJSXNode(); + var token = this.nextJSXToken(); + if (token.type !== 100 /* Identifier */) { + this.throwUnexpectedToken(token); + } + return this.finalize(node, new JSXNode.JSXIdentifier(token.value)); + }; + JSXParser.prototype.parseJSXElementName = function () { + var node = this.createJSXNode(); + var elementName = this.parseJSXIdentifier(); + if (this.matchJSX(':')) { + var namespace = elementName; + this.expectJSX(':'); + var name_1 = this.parseJSXIdentifier(); + elementName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_1)); + } + else if (this.matchJSX('.')) { + while (this.matchJSX('.')) { + var object = elementName; + this.expectJSX('.'); + var property = this.parseJSXIdentifier(); + elementName = this.finalize(node, new JSXNode.JSXMemberExpression(object, property)); + } + } + return elementName; + }; + JSXParser.prototype.parseJSXAttributeName = function () { + var node = this.createJSXNode(); + var attributeName; + var identifier = this.parseJSXIdentifier(); + if (this.matchJSX(':')) { + var namespace = identifier; + this.expectJSX(':'); + var name_2 = this.parseJSXIdentifier(); + attributeName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_2)); + } + else { + attributeName = identifier; + } + return attributeName; + }; + JSXParser.prototype.parseJSXStringLiteralAttribute = function () { + var node = this.createJSXNode(); + var token = this.nextJSXToken(); + if (token.type !== 8 /* StringLiteral */) { + this.throwUnexpectedToken(token); + } + var raw = this.getTokenRaw(token); + return this.finalize(node, new Node.Literal(token.value, raw)); + }; + JSXParser.prototype.parseJSXExpressionAttribute = function () { + var node = this.createJSXNode(); + this.expectJSX('{'); + this.finishJSX(); + if (this.match('}')) { + this.tolerateError('JSX attributes must only be assigned a non-empty expression'); + } + var expression = this.parseAssignmentExpression(); + this.reenterJSX(); + return this.finalize(node, new JSXNode.JSXExpressionContainer(expression)); + }; + JSXParser.prototype.parseJSXAttributeValue = function () { + return this.matchJSX('{') ? this.parseJSXExpressionAttribute() : + this.matchJSX('<') ? this.parseJSXElement() : this.parseJSXStringLiteralAttribute(); + }; + JSXParser.prototype.parseJSXNameValueAttribute = function () { + var node = this.createJSXNode(); + var name = this.parseJSXAttributeName(); + var value = null; + if (this.matchJSX('=')) { + this.expectJSX('='); + value = this.parseJSXAttributeValue(); + } + return this.finalize(node, new JSXNode.JSXAttribute(name, value)); + }; + JSXParser.prototype.parseJSXSpreadAttribute = function () { + var node = this.createJSXNode(); + this.expectJSX('{'); + this.expectJSX('...'); + this.finishJSX(); + var argument = this.parseAssignmentExpression(); + this.reenterJSX(); + return this.finalize(node, new JSXNode.JSXSpreadAttribute(argument)); + }; + JSXParser.prototype.parseJSXAttributes = function () { + var attributes = []; + while (!this.matchJSX('/') && !this.matchJSX('>')) { + var attribute = this.matchJSX('{') ? this.parseJSXSpreadAttribute() : + this.parseJSXNameValueAttribute(); + attributes.push(attribute); + } + return attributes; + }; + JSXParser.prototype.parseJSXOpeningElement = function () { + var node = this.createJSXNode(); + this.expectJSX('<'); + var name = this.parseJSXElementName(); + var attributes = this.parseJSXAttributes(); + var selfClosing = this.matchJSX('/'); + if (selfClosing) { + this.expectJSX('/'); + } + this.expectJSX('>'); + return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes)); + }; + JSXParser.prototype.parseJSXBoundaryElement = function () { + var node = this.createJSXNode(); + this.expectJSX('<'); + if (this.matchJSX('/')) { + this.expectJSX('/'); + var name_3 = this.parseJSXElementName(); + this.expectJSX('>'); + return this.finalize(node, new JSXNode.JSXClosingElement(name_3)); + } + var name = this.parseJSXElementName(); + var attributes = this.parseJSXAttributes(); + var selfClosing = this.matchJSX('/'); + if (selfClosing) { + this.expectJSX('/'); + } + this.expectJSX('>'); + return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes)); + }; + JSXParser.prototype.parseJSXEmptyExpression = function () { + var node = this.createJSXChildNode(); + this.collectComments(); + this.lastMarker.index = this.scanner.index; + this.lastMarker.line = this.scanner.lineNumber; + this.lastMarker.column = this.scanner.index - this.scanner.lineStart; + return this.finalize(node, new JSXNode.JSXEmptyExpression()); + }; + JSXParser.prototype.parseJSXExpressionContainer = function () { + var node = this.createJSXNode(); + this.expectJSX('{'); + var expression; + if (this.matchJSX('}')) { + expression = this.parseJSXEmptyExpression(); + this.expectJSX('}'); + } + else { + this.finishJSX(); + expression = this.parseAssignmentExpression(); + this.reenterJSX(); + } + return this.finalize(node, new JSXNode.JSXExpressionContainer(expression)); + }; + JSXParser.prototype.parseJSXChildren = function () { + var children = []; + while (!this.scanner.eof()) { + var node = this.createJSXChildNode(); + var token = this.nextJSXText(); + if (token.start < token.end) { + var raw = this.getTokenRaw(token); + var child = this.finalize(node, new JSXNode.JSXText(token.value, raw)); + children.push(child); + } + if (this.scanner.source[this.scanner.index] === '{') { + var container = this.parseJSXExpressionContainer(); + children.push(container); + } + else { + break; + } + } + return children; + }; + JSXParser.prototype.parseComplexJSXElement = function (el) { + var stack = []; + while (!this.scanner.eof()) { + el.children = el.children.concat(this.parseJSXChildren()); + var node = this.createJSXChildNode(); + var element = this.parseJSXBoundaryElement(); + if (element.type === jsx_syntax_1.JSXSyntax.JSXOpeningElement) { + var opening = element; + if (opening.selfClosing) { + var child = this.finalize(node, new JSXNode.JSXElement(opening, [], null)); + el.children.push(child); + } + else { + stack.push(el); + el = { node: node, opening: opening, closing: null, children: [] }; + } + } + if (element.type === jsx_syntax_1.JSXSyntax.JSXClosingElement) { + el.closing = element; + var open_1 = getQualifiedElementName(el.opening.name); + var close_1 = getQualifiedElementName(el.closing.name); + if (open_1 !== close_1) { + this.tolerateError('Expected corresponding JSX closing tag for %0', open_1); + } + if (stack.length > 0) { + var child = this.finalize(el.node, new JSXNode.JSXElement(el.opening, el.children, el.closing)); + el = stack[stack.length - 1]; + el.children.push(child); + stack.pop(); + } + else { + break; + } + } + } + return el; + }; + JSXParser.prototype.parseJSXElement = function () { + var node = this.createJSXNode(); + var opening = this.parseJSXOpeningElement(); + var children = []; + var closing = null; + if (!opening.selfClosing) { + var el = this.parseComplexJSXElement({ node: node, opening: opening, closing: closing, children: children }); + children = el.children; + closing = el.closing; + } + return this.finalize(node, new JSXNode.JSXElement(opening, children, closing)); + }; + JSXParser.prototype.parseJSXRoot = function () { + // Pop the opening '<' added from the lookahead. + if (this.config.tokens) { + this.tokens.pop(); + } + this.startJSX(); + var element = this.parseJSXElement(); + this.finishJSX(); + return element; + }; + JSXParser.prototype.isStartOfExpression = function () { + return _super.prototype.isStartOfExpression.call(this) || this.match('<'); + }; + return JSXParser; + }(parser_1.Parser)); + exports.JSXParser = JSXParser; + + +/***/ }, +/* 4 */ +/***/ function(module, exports) { + + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + // See also tools/generate-unicode-regex.js. + var Regex = { + // Unicode v8.0.0 NonAsciiIdentifierStart: + NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/, + // Unicode v8.0.0 NonAsciiIdentifierPart: + NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ + }; + exports.Character = { + /* tslint:disable:no-bitwise */ + fromCodePoint: function (cp) { + return (cp < 0x10000) ? String.fromCharCode(cp) : + String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) + + String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023)); + }, + // https://tc39.github.io/ecma262/#sec-white-space + isWhiteSpace: function (cp) { + return (cp === 0x20) || (cp === 0x09) || (cp === 0x0B) || (cp === 0x0C) || (cp === 0xA0) || + (cp >= 0x1680 && [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(cp) >= 0); + }, + // https://tc39.github.io/ecma262/#sec-line-terminators + isLineTerminator: function (cp) { + return (cp === 0x0A) || (cp === 0x0D) || (cp === 0x2028) || (cp === 0x2029); + }, + // https://tc39.github.io/ecma262/#sec-names-and-keywords + isIdentifierStart: function (cp) { + return (cp === 0x24) || (cp === 0x5F) || + (cp >= 0x41 && cp <= 0x5A) || + (cp >= 0x61 && cp <= 0x7A) || + (cp === 0x5C) || + ((cp >= 0x80) && Regex.NonAsciiIdentifierStart.test(exports.Character.fromCodePoint(cp))); + }, + isIdentifierPart: function (cp) { + return (cp === 0x24) || (cp === 0x5F) || + (cp >= 0x41 && cp <= 0x5A) || + (cp >= 0x61 && cp <= 0x7A) || + (cp >= 0x30 && cp <= 0x39) || + (cp === 0x5C) || + ((cp >= 0x80) && Regex.NonAsciiIdentifierPart.test(exports.Character.fromCodePoint(cp))); + }, + // https://tc39.github.io/ecma262/#sec-literals-numeric-literals + isDecimalDigit: function (cp) { + return (cp >= 0x30 && cp <= 0x39); // 0..9 + }, + isHexDigit: function (cp) { + return (cp >= 0x30 && cp <= 0x39) || + (cp >= 0x41 && cp <= 0x46) || + (cp >= 0x61 && cp <= 0x66); // a..f + }, + isOctalDigit: function (cp) { + return (cp >= 0x30 && cp <= 0x37); // 0..7 + } + }; + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + var jsx_syntax_1 = __webpack_require__(6); + /* tslint:disable:max-classes-per-file */ + var JSXClosingElement = (function () { + function JSXClosingElement(name) { + this.type = jsx_syntax_1.JSXSyntax.JSXClosingElement; + this.name = name; + } + return JSXClosingElement; + }()); + exports.JSXClosingElement = JSXClosingElement; + var JSXElement = (function () { + function JSXElement(openingElement, children, closingElement) { + this.type = jsx_syntax_1.JSXSyntax.JSXElement; + this.openingElement = openingElement; + this.children = children; + this.closingElement = closingElement; + } + return JSXElement; + }()); + exports.JSXElement = JSXElement; + var JSXEmptyExpression = (function () { + function JSXEmptyExpression() { + this.type = jsx_syntax_1.JSXSyntax.JSXEmptyExpression; + } + return JSXEmptyExpression; + }()); + exports.JSXEmptyExpression = JSXEmptyExpression; + var JSXExpressionContainer = (function () { + function JSXExpressionContainer(expression) { + this.type = jsx_syntax_1.JSXSyntax.JSXExpressionContainer; + this.expression = expression; + } + return JSXExpressionContainer; + }()); + exports.JSXExpressionContainer = JSXExpressionContainer; + var JSXIdentifier = (function () { + function JSXIdentifier(name) { + this.type = jsx_syntax_1.JSXSyntax.JSXIdentifier; + this.name = name; + } + return JSXIdentifier; + }()); + exports.JSXIdentifier = JSXIdentifier; + var JSXMemberExpression = (function () { + function JSXMemberExpression(object, property) { + this.type = jsx_syntax_1.JSXSyntax.JSXMemberExpression; + this.object = object; + this.property = property; + } + return JSXMemberExpression; + }()); + exports.JSXMemberExpression = JSXMemberExpression; + var JSXAttribute = (function () { + function JSXAttribute(name, value) { + this.type = jsx_syntax_1.JSXSyntax.JSXAttribute; + this.name = name; + this.value = value; + } + return JSXAttribute; + }()); + exports.JSXAttribute = JSXAttribute; + var JSXNamespacedName = (function () { + function JSXNamespacedName(namespace, name) { + this.type = jsx_syntax_1.JSXSyntax.JSXNamespacedName; + this.namespace = namespace; + this.name = name; + } + return JSXNamespacedName; + }()); + exports.JSXNamespacedName = JSXNamespacedName; + var JSXOpeningElement = (function () { + function JSXOpeningElement(name, selfClosing, attributes) { + this.type = jsx_syntax_1.JSXSyntax.JSXOpeningElement; + this.name = name; + this.selfClosing = selfClosing; + this.attributes = attributes; + } + return JSXOpeningElement; + }()); + exports.JSXOpeningElement = JSXOpeningElement; + var JSXSpreadAttribute = (function () { + function JSXSpreadAttribute(argument) { + this.type = jsx_syntax_1.JSXSyntax.JSXSpreadAttribute; + this.argument = argument; + } + return JSXSpreadAttribute; + }()); + exports.JSXSpreadAttribute = JSXSpreadAttribute; + var JSXText = (function () { + function JSXText(value, raw) { + this.type = jsx_syntax_1.JSXSyntax.JSXText; + this.value = value; + this.raw = raw; + } + return JSXText; + }()); + exports.JSXText = JSXText; + + +/***/ }, +/* 6 */ +/***/ function(module, exports) { + + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.JSXSyntax = { + JSXAttribute: 'JSXAttribute', + JSXClosingElement: 'JSXClosingElement', + JSXElement: 'JSXElement', + JSXEmptyExpression: 'JSXEmptyExpression', + JSXExpressionContainer: 'JSXExpressionContainer', + JSXIdentifier: 'JSXIdentifier', + JSXMemberExpression: 'JSXMemberExpression', + JSXNamespacedName: 'JSXNamespacedName', + JSXOpeningElement: 'JSXOpeningElement', + JSXSpreadAttribute: 'JSXSpreadAttribute', + JSXText: 'JSXText' + }; + + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + var syntax_1 = __webpack_require__(2); + /* tslint:disable:max-classes-per-file */ + var ArrayExpression = (function () { + function ArrayExpression(elements) { + this.type = syntax_1.Syntax.ArrayExpression; + this.elements = elements; + } + return ArrayExpression; + }()); + exports.ArrayExpression = ArrayExpression; + var ArrayPattern = (function () { + function ArrayPattern(elements) { + this.type = syntax_1.Syntax.ArrayPattern; + this.elements = elements; + } + return ArrayPattern; + }()); + exports.ArrayPattern = ArrayPattern; + var ArrowFunctionExpression = (function () { + function ArrowFunctionExpression(params, body, expression) { + this.type = syntax_1.Syntax.ArrowFunctionExpression; + this.id = null; + this.params = params; + this.body = body; + this.generator = false; + this.expression = expression; + this.async = false; + } + return ArrowFunctionExpression; + }()); + exports.ArrowFunctionExpression = ArrowFunctionExpression; + var AssignmentExpression = (function () { + function AssignmentExpression(operator, left, right) { + this.type = syntax_1.Syntax.AssignmentExpression; + this.operator = operator; + this.left = left; + this.right = right; + } + return AssignmentExpression; + }()); + exports.AssignmentExpression = AssignmentExpression; + var AssignmentPattern = (function () { + function AssignmentPattern(left, right) { + this.type = syntax_1.Syntax.AssignmentPattern; + this.left = left; + this.right = right; + } + return AssignmentPattern; + }()); + exports.AssignmentPattern = AssignmentPattern; + var AsyncArrowFunctionExpression = (function () { + function AsyncArrowFunctionExpression(params, body, expression) { + this.type = syntax_1.Syntax.ArrowFunctionExpression; + this.id = null; + this.params = params; + this.body = body; + this.generator = false; + this.expression = expression; + this.async = true; + } + return AsyncArrowFunctionExpression; + }()); + exports.AsyncArrowFunctionExpression = AsyncArrowFunctionExpression; + var AsyncFunctionDeclaration = (function () { + function AsyncFunctionDeclaration(id, params, body) { + this.type = syntax_1.Syntax.FunctionDeclaration; + this.id = id; + this.params = params; + this.body = body; + this.generator = false; + this.expression = false; + this.async = true; + } + return AsyncFunctionDeclaration; + }()); + exports.AsyncFunctionDeclaration = AsyncFunctionDeclaration; + var AsyncFunctionExpression = (function () { + function AsyncFunctionExpression(id, params, body) { + this.type = syntax_1.Syntax.FunctionExpression; + this.id = id; + this.params = params; + this.body = body; + this.generator = false; + this.expression = false; + this.async = true; + } + return AsyncFunctionExpression; + }()); + exports.AsyncFunctionExpression = AsyncFunctionExpression; + var AwaitExpression = (function () { + function AwaitExpression(argument) { + this.type = syntax_1.Syntax.AwaitExpression; + this.argument = argument; + } + return AwaitExpression; + }()); + exports.AwaitExpression = AwaitExpression; + var BinaryExpression = (function () { + function BinaryExpression(operator, left, right) { + var logical = (operator === '||' || operator === '&&'); + this.type = logical ? syntax_1.Syntax.LogicalExpression : syntax_1.Syntax.BinaryExpression; + this.operator = operator; + this.left = left; + this.right = right; + } + return BinaryExpression; + }()); + exports.BinaryExpression = BinaryExpression; + var BlockStatement = (function () { + function BlockStatement(body) { + this.type = syntax_1.Syntax.BlockStatement; + this.body = body; + } + return BlockStatement; + }()); + exports.BlockStatement = BlockStatement; + var BreakStatement = (function () { + function BreakStatement(label) { + this.type = syntax_1.Syntax.BreakStatement; + this.label = label; + } + return BreakStatement; + }()); + exports.BreakStatement = BreakStatement; + var CallExpression = (function () { + function CallExpression(callee, args) { + this.type = syntax_1.Syntax.CallExpression; + this.callee = callee; + this.arguments = args; + } + return CallExpression; + }()); + exports.CallExpression = CallExpression; + var CatchClause = (function () { + function CatchClause(param, body) { + this.type = syntax_1.Syntax.CatchClause; + this.param = param; + this.body = body; + } + return CatchClause; + }()); + exports.CatchClause = CatchClause; + var ClassBody = (function () { + function ClassBody(body) { + this.type = syntax_1.Syntax.ClassBody; + this.body = body; + } + return ClassBody; + }()); + exports.ClassBody = ClassBody; + var ClassDeclaration = (function () { + function ClassDeclaration(id, superClass, body) { + this.type = syntax_1.Syntax.ClassDeclaration; + this.id = id; + this.superClass = superClass; + this.body = body; + } + return ClassDeclaration; + }()); + exports.ClassDeclaration = ClassDeclaration; + var ClassExpression = (function () { + function ClassExpression(id, superClass, body) { + this.type = syntax_1.Syntax.ClassExpression; + this.id = id; + this.superClass = superClass; + this.body = body; + } + return ClassExpression; + }()); + exports.ClassExpression = ClassExpression; + var ComputedMemberExpression = (function () { + function ComputedMemberExpression(object, property) { + this.type = syntax_1.Syntax.MemberExpression; + this.computed = true; + this.object = object; + this.property = property; + } + return ComputedMemberExpression; + }()); + exports.ComputedMemberExpression = ComputedMemberExpression; + var ConditionalExpression = (function () { + function ConditionalExpression(test, consequent, alternate) { + this.type = syntax_1.Syntax.ConditionalExpression; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + } + return ConditionalExpression; + }()); + exports.ConditionalExpression = ConditionalExpression; + var ContinueStatement = (function () { + function ContinueStatement(label) { + this.type = syntax_1.Syntax.ContinueStatement; + this.label = label; + } + return ContinueStatement; + }()); + exports.ContinueStatement = ContinueStatement; + var DebuggerStatement = (function () { + function DebuggerStatement() { + this.type = syntax_1.Syntax.DebuggerStatement; + } + return DebuggerStatement; + }()); + exports.DebuggerStatement = DebuggerStatement; + var Directive = (function () { + function Directive(expression, directive) { + this.type = syntax_1.Syntax.ExpressionStatement; + this.expression = expression; + this.directive = directive; + } + return Directive; + }()); + exports.Directive = Directive; + var DoWhileStatement = (function () { + function DoWhileStatement(body, test) { + this.type = syntax_1.Syntax.DoWhileStatement; + this.body = body; + this.test = test; + } + return DoWhileStatement; + }()); + exports.DoWhileStatement = DoWhileStatement; + var EmptyStatement = (function () { + function EmptyStatement() { + this.type = syntax_1.Syntax.EmptyStatement; + } + return EmptyStatement; + }()); + exports.EmptyStatement = EmptyStatement; + var ExportAllDeclaration = (function () { + function ExportAllDeclaration(source) { + this.type = syntax_1.Syntax.ExportAllDeclaration; + this.source = source; + } + return ExportAllDeclaration; + }()); + exports.ExportAllDeclaration = ExportAllDeclaration; + var ExportDefaultDeclaration = (function () { + function ExportDefaultDeclaration(declaration) { + this.type = syntax_1.Syntax.ExportDefaultDeclaration; + this.declaration = declaration; + } + return ExportDefaultDeclaration; + }()); + exports.ExportDefaultDeclaration = ExportDefaultDeclaration; + var ExportNamedDeclaration = (function () { + function ExportNamedDeclaration(declaration, specifiers, source) { + this.type = syntax_1.Syntax.ExportNamedDeclaration; + this.declaration = declaration; + this.specifiers = specifiers; + this.source = source; + } + return ExportNamedDeclaration; + }()); + exports.ExportNamedDeclaration = ExportNamedDeclaration; + var ExportSpecifier = (function () { + function ExportSpecifier(local, exported) { + this.type = syntax_1.Syntax.ExportSpecifier; + this.exported = exported; + this.local = local; + } + return ExportSpecifier; + }()); + exports.ExportSpecifier = ExportSpecifier; + var ExpressionStatement = (function () { + function ExpressionStatement(expression) { + this.type = syntax_1.Syntax.ExpressionStatement; + this.expression = expression; + } + return ExpressionStatement; + }()); + exports.ExpressionStatement = ExpressionStatement; + var ForInStatement = (function () { + function ForInStatement(left, right, body) { + this.type = syntax_1.Syntax.ForInStatement; + this.left = left; + this.right = right; + this.body = body; + this.each = false; + } + return ForInStatement; + }()); + exports.ForInStatement = ForInStatement; + var ForOfStatement = (function () { + function ForOfStatement(left, right, body) { + this.type = syntax_1.Syntax.ForOfStatement; + this.left = left; + this.right = right; + this.body = body; + } + return ForOfStatement; + }()); + exports.ForOfStatement = ForOfStatement; + var ForStatement = (function () { + function ForStatement(init, test, update, body) { + this.type = syntax_1.Syntax.ForStatement; + this.init = init; + this.test = test; + this.update = update; + this.body = body; + } + return ForStatement; + }()); + exports.ForStatement = ForStatement; + var FunctionDeclaration = (function () { + function FunctionDeclaration(id, params, body, generator) { + this.type = syntax_1.Syntax.FunctionDeclaration; + this.id = id; + this.params = params; + this.body = body; + this.generator = generator; + this.expression = false; + this.async = false; + } + return FunctionDeclaration; + }()); + exports.FunctionDeclaration = FunctionDeclaration; + var FunctionExpression = (function () { + function FunctionExpression(id, params, body, generator) { + this.type = syntax_1.Syntax.FunctionExpression; + this.id = id; + this.params = params; + this.body = body; + this.generator = generator; + this.expression = false; + this.async = false; + } + return FunctionExpression; + }()); + exports.FunctionExpression = FunctionExpression; + var Identifier = (function () { + function Identifier(name) { + this.type = syntax_1.Syntax.Identifier; + this.name = name; + } + return Identifier; + }()); + exports.Identifier = Identifier; + var IfStatement = (function () { + function IfStatement(test, consequent, alternate) { + this.type = syntax_1.Syntax.IfStatement; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + } + return IfStatement; + }()); + exports.IfStatement = IfStatement; + var ImportDeclaration = (function () { + function ImportDeclaration(specifiers, source) { + this.type = syntax_1.Syntax.ImportDeclaration; + this.specifiers = specifiers; + this.source = source; + } + return ImportDeclaration; + }()); + exports.ImportDeclaration = ImportDeclaration; + var ImportDefaultSpecifier = (function () { + function ImportDefaultSpecifier(local) { + this.type = syntax_1.Syntax.ImportDefaultSpecifier; + this.local = local; + } + return ImportDefaultSpecifier; + }()); + exports.ImportDefaultSpecifier = ImportDefaultSpecifier; + var ImportNamespaceSpecifier = (function () { + function ImportNamespaceSpecifier(local) { + this.type = syntax_1.Syntax.ImportNamespaceSpecifier; + this.local = local; + } + return ImportNamespaceSpecifier; + }()); + exports.ImportNamespaceSpecifier = ImportNamespaceSpecifier; + var ImportSpecifier = (function () { + function ImportSpecifier(local, imported) { + this.type = syntax_1.Syntax.ImportSpecifier; + this.local = local; + this.imported = imported; + } + return ImportSpecifier; + }()); + exports.ImportSpecifier = ImportSpecifier; + var LabeledStatement = (function () { + function LabeledStatement(label, body) { + this.type = syntax_1.Syntax.LabeledStatement; + this.label = label; + this.body = body; + } + return LabeledStatement; + }()); + exports.LabeledStatement = LabeledStatement; + var Literal = (function () { + function Literal(value, raw) { + this.type = syntax_1.Syntax.Literal; + this.value = value; + this.raw = raw; + } + return Literal; + }()); + exports.Literal = Literal; + var MetaProperty = (function () { + function MetaProperty(meta, property) { + this.type = syntax_1.Syntax.MetaProperty; + this.meta = meta; + this.property = property; + } + return MetaProperty; + }()); + exports.MetaProperty = MetaProperty; + var MethodDefinition = (function () { + function MethodDefinition(key, computed, value, kind, isStatic) { + this.type = syntax_1.Syntax.MethodDefinition; + this.key = key; + this.computed = computed; + this.value = value; + this.kind = kind; + this.static = isStatic; + } + return MethodDefinition; + }()); + exports.MethodDefinition = MethodDefinition; + var Module = (function () { + function Module(body) { + this.type = syntax_1.Syntax.Program; + this.body = body; + this.sourceType = 'module'; + } + return Module; + }()); + exports.Module = Module; + var NewExpression = (function () { + function NewExpression(callee, args) { + this.type = syntax_1.Syntax.NewExpression; + this.callee = callee; + this.arguments = args; + } + return NewExpression; + }()); + exports.NewExpression = NewExpression; + var ObjectExpression = (function () { + function ObjectExpression(properties) { + this.type = syntax_1.Syntax.ObjectExpression; + this.properties = properties; + } + return ObjectExpression; + }()); + exports.ObjectExpression = ObjectExpression; + var ObjectPattern = (function () { + function ObjectPattern(properties) { + this.type = syntax_1.Syntax.ObjectPattern; + this.properties = properties; + } + return ObjectPattern; + }()); + exports.ObjectPattern = ObjectPattern; + var Property = (function () { + function Property(kind, key, computed, value, method, shorthand) { + this.type = syntax_1.Syntax.Property; + this.key = key; + this.computed = computed; + this.value = value; + this.kind = kind; + this.method = method; + this.shorthand = shorthand; + } + return Property; + }()); + exports.Property = Property; + var RegexLiteral = (function () { + function RegexLiteral(value, raw, pattern, flags) { + this.type = syntax_1.Syntax.Literal; + this.value = value; + this.raw = raw; + this.regex = { pattern: pattern, flags: flags }; + } + return RegexLiteral; + }()); + exports.RegexLiteral = RegexLiteral; + var RestElement = (function () { + function RestElement(argument) { + this.type = syntax_1.Syntax.RestElement; + this.argument = argument; + } + return RestElement; + }()); + exports.RestElement = RestElement; + var ReturnStatement = (function () { + function ReturnStatement(argument) { + this.type = syntax_1.Syntax.ReturnStatement; + this.argument = argument; + } + return ReturnStatement; + }()); + exports.ReturnStatement = ReturnStatement; + var Script = (function () { + function Script(body) { + this.type = syntax_1.Syntax.Program; + this.body = body; + this.sourceType = 'script'; + } + return Script; + }()); + exports.Script = Script; + var SequenceExpression = (function () { + function SequenceExpression(expressions) { + this.type = syntax_1.Syntax.SequenceExpression; + this.expressions = expressions; + } + return SequenceExpression; + }()); + exports.SequenceExpression = SequenceExpression; + var SpreadElement = (function () { + function SpreadElement(argument) { + this.type = syntax_1.Syntax.SpreadElement; + this.argument = argument; + } + return SpreadElement; + }()); + exports.SpreadElement = SpreadElement; + var StaticMemberExpression = (function () { + function StaticMemberExpression(object, property) { + this.type = syntax_1.Syntax.MemberExpression; + this.computed = false; + this.object = object; + this.property = property; + } + return StaticMemberExpression; + }()); + exports.StaticMemberExpression = StaticMemberExpression; + var Super = (function () { + function Super() { + this.type = syntax_1.Syntax.Super; + } + return Super; + }()); + exports.Super = Super; + var SwitchCase = (function () { + function SwitchCase(test, consequent) { + this.type = syntax_1.Syntax.SwitchCase; + this.test = test; + this.consequent = consequent; + } + return SwitchCase; + }()); + exports.SwitchCase = SwitchCase; + var SwitchStatement = (function () { + function SwitchStatement(discriminant, cases) { + this.type = syntax_1.Syntax.SwitchStatement; + this.discriminant = discriminant; + this.cases = cases; + } + return SwitchStatement; + }()); + exports.SwitchStatement = SwitchStatement; + var TaggedTemplateExpression = (function () { + function TaggedTemplateExpression(tag, quasi) { + this.type = syntax_1.Syntax.TaggedTemplateExpression; + this.tag = tag; + this.quasi = quasi; + } + return TaggedTemplateExpression; + }()); + exports.TaggedTemplateExpression = TaggedTemplateExpression; + var TemplateElement = (function () { + function TemplateElement(value, tail) { + this.type = syntax_1.Syntax.TemplateElement; + this.value = value; + this.tail = tail; + } + return TemplateElement; + }()); + exports.TemplateElement = TemplateElement; + var TemplateLiteral = (function () { + function TemplateLiteral(quasis, expressions) { + this.type = syntax_1.Syntax.TemplateLiteral; + this.quasis = quasis; + this.expressions = expressions; + } + return TemplateLiteral; + }()); + exports.TemplateLiteral = TemplateLiteral; + var ThisExpression = (function () { + function ThisExpression() { + this.type = syntax_1.Syntax.ThisExpression; + } + return ThisExpression; + }()); + exports.ThisExpression = ThisExpression; + var ThrowStatement = (function () { + function ThrowStatement(argument) { + this.type = syntax_1.Syntax.ThrowStatement; + this.argument = argument; + } + return ThrowStatement; + }()); + exports.ThrowStatement = ThrowStatement; + var TryStatement = (function () { + function TryStatement(block, handler, finalizer) { + this.type = syntax_1.Syntax.TryStatement; + this.block = block; + this.handler = handler; + this.finalizer = finalizer; + } + return TryStatement; + }()); + exports.TryStatement = TryStatement; + var UnaryExpression = (function () { + function UnaryExpression(operator, argument) { + this.type = syntax_1.Syntax.UnaryExpression; + this.operator = operator; + this.argument = argument; + this.prefix = true; + } + return UnaryExpression; + }()); + exports.UnaryExpression = UnaryExpression; + var UpdateExpression = (function () { + function UpdateExpression(operator, argument, prefix) { + this.type = syntax_1.Syntax.UpdateExpression; + this.operator = operator; + this.argument = argument; + this.prefix = prefix; + } + return UpdateExpression; + }()); + exports.UpdateExpression = UpdateExpression; + var VariableDeclaration = (function () { + function VariableDeclaration(declarations, kind) { + this.type = syntax_1.Syntax.VariableDeclaration; + this.declarations = declarations; + this.kind = kind; + } + return VariableDeclaration; + }()); + exports.VariableDeclaration = VariableDeclaration; + var VariableDeclarator = (function () { + function VariableDeclarator(id, init) { + this.type = syntax_1.Syntax.VariableDeclarator; + this.id = id; + this.init = init; + } + return VariableDeclarator; + }()); + exports.VariableDeclarator = VariableDeclarator; + var WhileStatement = (function () { + function WhileStatement(test, body) { + this.type = syntax_1.Syntax.WhileStatement; + this.test = test; + this.body = body; + } + return WhileStatement; + }()); + exports.WhileStatement = WhileStatement; + var WithStatement = (function () { + function WithStatement(object, body) { + this.type = syntax_1.Syntax.WithStatement; + this.object = object; + this.body = body; + } + return WithStatement; + }()); + exports.WithStatement = WithStatement; + var YieldExpression = (function () { + function YieldExpression(argument, delegate) { + this.type = syntax_1.Syntax.YieldExpression; + this.argument = argument; + this.delegate = delegate; + } + return YieldExpression; + }()); + exports.YieldExpression = YieldExpression; + + +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + var assert_1 = __webpack_require__(9); + var error_handler_1 = __webpack_require__(10); + var messages_1 = __webpack_require__(11); + var Node = __webpack_require__(7); + var scanner_1 = __webpack_require__(12); + var syntax_1 = __webpack_require__(2); + var token_1 = __webpack_require__(13); + var ArrowParameterPlaceHolder = 'ArrowParameterPlaceHolder'; + var Parser = (function () { + function Parser(code, options, delegate) { + if (options === void 0) { options = {}; } + this.config = { + range: (typeof options.range === 'boolean') && options.range, + loc: (typeof options.loc === 'boolean') && options.loc, + source: null, + tokens: (typeof options.tokens === 'boolean') && options.tokens, + comment: (typeof options.comment === 'boolean') && options.comment, + tolerant: (typeof options.tolerant === 'boolean') && options.tolerant + }; + if (this.config.loc && options.source && options.source !== null) { + this.config.source = String(options.source); + } + this.delegate = delegate; + this.errorHandler = new error_handler_1.ErrorHandler(); + this.errorHandler.tolerant = this.config.tolerant; + this.scanner = new scanner_1.Scanner(code, this.errorHandler); + this.scanner.trackComment = this.config.comment; + this.operatorPrecedence = { + ')': 0, + ';': 0, + ',': 0, + '=': 0, + ']': 0, + '||': 1, + '&&': 2, + '|': 3, + '^': 4, + '&': 5, + '==': 6, + '!=': 6, + '===': 6, + '!==': 6, + '<': 7, + '>': 7, + '<=': 7, + '>=': 7, + '<<': 8, + '>>': 8, + '>>>': 8, + '+': 9, + '-': 9, + '*': 11, + '/': 11, + '%': 11 + }; + this.lookahead = { + type: 2 /* EOF */, + value: '', + lineNumber: this.scanner.lineNumber, + lineStart: 0, + start: 0, + end: 0 + }; + this.hasLineTerminator = false; + this.context = { + isModule: false, + await: false, + allowIn: true, + allowStrictDirective: true, + allowYield: true, + firstCoverInitializedNameError: null, + isAssignmentTarget: false, + isBindingElement: false, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + labelSet: {}, + strict: false + }; + this.tokens = []; + this.startMarker = { + index: 0, + line: this.scanner.lineNumber, + column: 0 + }; + this.lastMarker = { + index: 0, + line: this.scanner.lineNumber, + column: 0 + }; + this.nextToken(); + this.lastMarker = { + index: this.scanner.index, + line: this.scanner.lineNumber, + column: this.scanner.index - this.scanner.lineStart + }; + } + Parser.prototype.throwError = function (messageFormat) { + var values = []; + for (var _i = 1; _i < arguments.length; _i++) { + values[_i - 1] = arguments[_i]; + } + var args = Array.prototype.slice.call(arguments, 1); + var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) { + assert_1.assert(idx < args.length, 'Message reference must be in range'); + return args[idx]; + }); + var index = this.lastMarker.index; + var line = this.lastMarker.line; + var column = this.lastMarker.column + 1; + throw this.errorHandler.createError(index, line, column, msg); + }; + Parser.prototype.tolerateError = function (messageFormat) { + var values = []; + for (var _i = 1; _i < arguments.length; _i++) { + values[_i - 1] = arguments[_i]; + } + var args = Array.prototype.slice.call(arguments, 1); + var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) { + assert_1.assert(idx < args.length, 'Message reference must be in range'); + return args[idx]; + }); + var index = this.lastMarker.index; + var line = this.scanner.lineNumber; + var column = this.lastMarker.column + 1; + this.errorHandler.tolerateError(index, line, column, msg); + }; + // Throw an exception because of the token. + Parser.prototype.unexpectedTokenError = function (token, message) { + var msg = message || messages_1.Messages.UnexpectedToken; + var value; + if (token) { + if (!message) { + msg = (token.type === 2 /* EOF */) ? messages_1.Messages.UnexpectedEOS : + (token.type === 3 /* Identifier */) ? messages_1.Messages.UnexpectedIdentifier : + (token.type === 6 /* NumericLiteral */) ? messages_1.Messages.UnexpectedNumber : + (token.type === 8 /* StringLiteral */) ? messages_1.Messages.UnexpectedString : + (token.type === 10 /* Template */) ? messages_1.Messages.UnexpectedTemplate : + messages_1.Messages.UnexpectedToken; + if (token.type === 4 /* Keyword */) { + if (this.scanner.isFutureReservedWord(token.value)) { + msg = messages_1.Messages.UnexpectedReserved; + } + else if (this.context.strict && this.scanner.isStrictModeReservedWord(token.value)) { + msg = messages_1.Messages.StrictReservedWord; + } + } + } + value = token.value; + } + else { + value = 'ILLEGAL'; + } + msg = msg.replace('%0', value); + if (token && typeof token.lineNumber === 'number') { + var index = token.start; + var line = token.lineNumber; + var lastMarkerLineStart = this.lastMarker.index - this.lastMarker.column; + var column = token.start - lastMarkerLineStart + 1; + return this.errorHandler.createError(index, line, column, msg); + } + else { + var index = this.lastMarker.index; + var line = this.lastMarker.line; + var column = this.lastMarker.column + 1; + return this.errorHandler.createError(index, line, column, msg); + } + }; + Parser.prototype.throwUnexpectedToken = function (token, message) { + throw this.unexpectedTokenError(token, message); + }; + Parser.prototype.tolerateUnexpectedToken = function (token, message) { + this.errorHandler.tolerate(this.unexpectedTokenError(token, message)); + }; + Parser.prototype.collectComments = function () { + if (!this.config.comment) { + this.scanner.scanComments(); + } + else { + var comments = this.scanner.scanComments(); + if (comments.length > 0 && this.delegate) { + for (var i = 0; i < comments.length; ++i) { + var e = comments[i]; + var node = void 0; + node = { + type: e.multiLine ? 'BlockComment' : 'LineComment', + value: this.scanner.source.slice(e.slice[0], e.slice[1]) + }; + if (this.config.range) { + node.range = e.range; + } + if (this.config.loc) { + node.loc = e.loc; + } + var metadata = { + start: { + line: e.loc.start.line, + column: e.loc.start.column, + offset: e.range[0] + }, + end: { + line: e.loc.end.line, + column: e.loc.end.column, + offset: e.range[1] + } + }; + this.delegate(node, metadata); + } + } + } + }; + // From internal representation to an external structure + Parser.prototype.getTokenRaw = function (token) { + return this.scanner.source.slice(token.start, token.end); + }; + Parser.prototype.convertToken = function (token) { + var t = { + type: token_1.TokenName[token.type], + value: this.getTokenRaw(token) + }; + if (this.config.range) { + t.range = [token.start, token.end]; + } + if (this.config.loc) { + t.loc = { + start: { + line: this.startMarker.line, + column: this.startMarker.column + }, + end: { + line: this.scanner.lineNumber, + column: this.scanner.index - this.scanner.lineStart + } + }; + } + if (token.type === 9 /* RegularExpression */) { + var pattern = token.pattern; + var flags = token.flags; + t.regex = { pattern: pattern, flags: flags }; + } + return t; + }; + Parser.prototype.nextToken = function () { + var token = this.lookahead; + this.lastMarker.index = this.scanner.index; + this.lastMarker.line = this.scanner.lineNumber; + this.lastMarker.column = this.scanner.index - this.scanner.lineStart; + this.collectComments(); + if (this.scanner.index !== this.startMarker.index) { + this.startMarker.index = this.scanner.index; + this.startMarker.line = this.scanner.lineNumber; + this.startMarker.column = this.scanner.index - this.scanner.lineStart; + } + var next = this.scanner.lex(); + this.hasLineTerminator = (token.lineNumber !== next.lineNumber); + if (next && this.context.strict && next.type === 3 /* Identifier */) { + if (this.scanner.isStrictModeReservedWord(next.value)) { + next.type = 4 /* Keyword */; + } + } + this.lookahead = next; + if (this.config.tokens && next.type !== 2 /* EOF */) { + this.tokens.push(this.convertToken(next)); + } + return token; + }; + Parser.prototype.nextRegexToken = function () { + this.collectComments(); + var token = this.scanner.scanRegExp(); + if (this.config.tokens) { + // Pop the previous token, '/' or '/=' + // This is added from the lookahead token. + this.tokens.pop(); + this.tokens.push(this.convertToken(token)); + } + // Prime the next lookahead. + this.lookahead = token; + this.nextToken(); + return token; + }; + Parser.prototype.createNode = function () { + return { + index: this.startMarker.index, + line: this.startMarker.line, + column: this.startMarker.column + }; + }; + Parser.prototype.startNode = function (token, lastLineStart) { + if (lastLineStart === void 0) { lastLineStart = 0; } + var column = token.start - token.lineStart; + var line = token.lineNumber; + if (column < 0) { + column += lastLineStart; + line--; + } + return { + index: token.start, + line: line, + column: column + }; + }; + Parser.prototype.finalize = function (marker, node) { + if (this.config.range) { + node.range = [marker.index, this.lastMarker.index]; + } + if (this.config.loc) { + node.loc = { + start: { + line: marker.line, + column: marker.column, + }, + end: { + line: this.lastMarker.line, + column: this.lastMarker.column + } + }; + if (this.config.source) { + node.loc.source = this.config.source; + } + } + if (this.delegate) { + var metadata = { + start: { + line: marker.line, + column: marker.column, + offset: marker.index + }, + end: { + line: this.lastMarker.line, + column: this.lastMarker.column, + offset: this.lastMarker.index + } + }; + this.delegate(node, metadata); + } + return node; + }; + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + Parser.prototype.expect = function (value) { + var token = this.nextToken(); + if (token.type !== 7 /* Punctuator */ || token.value !== value) { + this.throwUnexpectedToken(token); + } + }; + // Quietly expect a comma when in tolerant mode, otherwise delegates to expect(). + Parser.prototype.expectCommaSeparator = function () { + if (this.config.tolerant) { + var token = this.lookahead; + if (token.type === 7 /* Punctuator */ && token.value === ',') { + this.nextToken(); + } + else if (token.type === 7 /* Punctuator */ && token.value === ';') { + this.nextToken(); + this.tolerateUnexpectedToken(token); + } + else { + this.tolerateUnexpectedToken(token, messages_1.Messages.UnexpectedToken); + } + } + else { + this.expect(','); + } + }; + // Expect the next token to match the specified keyword. + // If not, an exception will be thrown. + Parser.prototype.expectKeyword = function (keyword) { + var token = this.nextToken(); + if (token.type !== 4 /* Keyword */ || token.value !== keyword) { + this.throwUnexpectedToken(token); + } + }; + // Return true if the next token matches the specified punctuator. + Parser.prototype.match = function (value) { + return this.lookahead.type === 7 /* Punctuator */ && this.lookahead.value === value; + }; + // Return true if the next token matches the specified keyword + Parser.prototype.matchKeyword = function (keyword) { + return this.lookahead.type === 4 /* Keyword */ && this.lookahead.value === keyword; + }; + // Return true if the next token matches the specified contextual keyword + // (where an identifier is sometimes a keyword depending on the context) + Parser.prototype.matchContextualKeyword = function (keyword) { + return this.lookahead.type === 3 /* Identifier */ && this.lookahead.value === keyword; + }; + // Return true if the next token is an assignment operator + Parser.prototype.matchAssign = function () { + if (this.lookahead.type !== 7 /* Punctuator */) { + return false; + } + var op = this.lookahead.value; + return op === '=' || + op === '*=' || + op === '**=' || + op === '/=' || + op === '%=' || + op === '+=' || + op === '-=' || + op === '<<=' || + op === '>>=' || + op === '>>>=' || + op === '&=' || + op === '^=' || + op === '|='; + }; + // Cover grammar support. + // + // When an assignment expression position starts with an left parenthesis, the determination of the type + // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead) + // or the first comma. This situation also defers the determination of all the expressions nested in the pair. + // + // There are three productions that can be parsed in a parentheses pair that needs to be determined + // after the outermost pair is closed. They are: + // + // 1. AssignmentExpression + // 2. BindingElements + // 3. AssignmentTargets + // + // In order to avoid exponential backtracking, we use two flags to denote if the production can be + // binding element or assignment target. + // + // The three productions have the relationship: + // + // BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression + // + // with a single exception that CoverInitializedName when used directly in an Expression, generates + // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the + // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair. + // + // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not + // effect the current flags. This means the production the parser parses is only used as an expression. Therefore + // the CoverInitializedName check is conducted. + // + // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates + // the flags outside of the parser. This means the production the parser parses is used as a part of a potential + // pattern. The CoverInitializedName check is deferred. + Parser.prototype.isolateCoverGrammar = function (parseFunction) { + var previousIsBindingElement = this.context.isBindingElement; + var previousIsAssignmentTarget = this.context.isAssignmentTarget; + var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; + this.context.isBindingElement = true; + this.context.isAssignmentTarget = true; + this.context.firstCoverInitializedNameError = null; + var result = parseFunction.call(this); + if (this.context.firstCoverInitializedNameError !== null) { + this.throwUnexpectedToken(this.context.firstCoverInitializedNameError); + } + this.context.isBindingElement = previousIsBindingElement; + this.context.isAssignmentTarget = previousIsAssignmentTarget; + this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError; + return result; + }; + Parser.prototype.inheritCoverGrammar = function (parseFunction) { + var previousIsBindingElement = this.context.isBindingElement; + var previousIsAssignmentTarget = this.context.isAssignmentTarget; + var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; + this.context.isBindingElement = true; + this.context.isAssignmentTarget = true; + this.context.firstCoverInitializedNameError = null; + var result = parseFunction.call(this); + this.context.isBindingElement = this.context.isBindingElement && previousIsBindingElement; + this.context.isAssignmentTarget = this.context.isAssignmentTarget && previousIsAssignmentTarget; + this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError || this.context.firstCoverInitializedNameError; + return result; + }; + Parser.prototype.consumeSemicolon = function () { + if (this.match(';')) { + this.nextToken(); + } + else if (!this.hasLineTerminator) { + if (this.lookahead.type !== 2 /* EOF */ && !this.match('}')) { + this.throwUnexpectedToken(this.lookahead); + } + this.lastMarker.index = this.startMarker.index; + this.lastMarker.line = this.startMarker.line; + this.lastMarker.column = this.startMarker.column; + } + }; + // https://tc39.github.io/ecma262/#sec-primary-expression + Parser.prototype.parsePrimaryExpression = function () { + var node = this.createNode(); + var expr; + var token, raw; + switch (this.lookahead.type) { + case 3 /* Identifier */: + if ((this.context.isModule || this.context.await) && this.lookahead.value === 'await') { + this.tolerateUnexpectedToken(this.lookahead); + } + expr = this.matchAsyncFunction() ? this.parseFunctionExpression() : this.finalize(node, new Node.Identifier(this.nextToken().value)); + break; + case 6 /* NumericLiteral */: + case 8 /* StringLiteral */: + if (this.context.strict && this.lookahead.octal) { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.StrictOctalLiteral); + } + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + token = this.nextToken(); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.Literal(token.value, raw)); + break; + case 1 /* BooleanLiteral */: + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + token = this.nextToken(); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.Literal(token.value === 'true', raw)); + break; + case 5 /* NullLiteral */: + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + token = this.nextToken(); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.Literal(null, raw)); + break; + case 10 /* Template */: + expr = this.parseTemplateLiteral(); + break; + case 7 /* Punctuator */: + switch (this.lookahead.value) { + case '(': + this.context.isBindingElement = false; + expr = this.inheritCoverGrammar(this.parseGroupExpression); + break; + case '[': + expr = this.inheritCoverGrammar(this.parseArrayInitializer); + break; + case '{': + expr = this.inheritCoverGrammar(this.parseObjectInitializer); + break; + case '/': + case '/=': + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + this.scanner.index = this.startMarker.index; + token = this.nextRegexToken(); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.RegexLiteral(token.regex, raw, token.pattern, token.flags)); + break; + default: + expr = this.throwUnexpectedToken(this.nextToken()); + } + break; + case 4 /* Keyword */: + if (!this.context.strict && this.context.allowYield && this.matchKeyword('yield')) { + expr = this.parseIdentifierName(); + } + else if (!this.context.strict && this.matchKeyword('let')) { + expr = this.finalize(node, new Node.Identifier(this.nextToken().value)); + } + else { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + if (this.matchKeyword('function')) { + expr = this.parseFunctionExpression(); + } + else if (this.matchKeyword('this')) { + this.nextToken(); + expr = this.finalize(node, new Node.ThisExpression()); + } + else if (this.matchKeyword('class')) { + expr = this.parseClassExpression(); + } + else { + expr = this.throwUnexpectedToken(this.nextToken()); + } + } + break; + default: + expr = this.throwUnexpectedToken(this.nextToken()); + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-array-initializer + Parser.prototype.parseSpreadElement = function () { + var node = this.createNode(); + this.expect('...'); + var arg = this.inheritCoverGrammar(this.parseAssignmentExpression); + return this.finalize(node, new Node.SpreadElement(arg)); + }; + Parser.prototype.parseArrayInitializer = function () { + var node = this.createNode(); + var elements = []; + this.expect('['); + while (!this.match(']')) { + if (this.match(',')) { + this.nextToken(); + elements.push(null); + } + else if (this.match('...')) { + var element = this.parseSpreadElement(); + if (!this.match(']')) { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + this.expect(','); + } + elements.push(element); + } + else { + elements.push(this.inheritCoverGrammar(this.parseAssignmentExpression)); + if (!this.match(']')) { + this.expect(','); + } + } + } + this.expect(']'); + return this.finalize(node, new Node.ArrayExpression(elements)); + }; + // https://tc39.github.io/ecma262/#sec-object-initializer + Parser.prototype.parsePropertyMethod = function (params) { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var previousStrict = this.context.strict; + var previousAllowStrictDirective = this.context.allowStrictDirective; + this.context.allowStrictDirective = params.simple; + var body = this.isolateCoverGrammar(this.parseFunctionSourceElements); + if (this.context.strict && params.firstRestricted) { + this.tolerateUnexpectedToken(params.firstRestricted, params.message); + } + if (this.context.strict && params.stricted) { + this.tolerateUnexpectedToken(params.stricted, params.message); + } + this.context.strict = previousStrict; + this.context.allowStrictDirective = previousAllowStrictDirective; + return body; + }; + Parser.prototype.parsePropertyMethodFunction = function () { + var isGenerator = false; + var node = this.createNode(); + var previousAllowYield = this.context.allowYield; + this.context.allowYield = true; + var params = this.parseFormalParameters(); + var method = this.parsePropertyMethod(params); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); + }; + Parser.prototype.parsePropertyMethodAsyncFunction = function () { + var node = this.createNode(); + var previousAllowYield = this.context.allowYield; + var previousAwait = this.context.await; + this.context.allowYield = false; + this.context.await = true; + var params = this.parseFormalParameters(); + var method = this.parsePropertyMethod(params); + this.context.allowYield = previousAllowYield; + this.context.await = previousAwait; + return this.finalize(node, new Node.AsyncFunctionExpression(null, params.params, method)); + }; + Parser.prototype.parseObjectPropertyKey = function () { + var node = this.createNode(); + var token = this.nextToken(); + var key; + switch (token.type) { + case 8 /* StringLiteral */: + case 6 /* NumericLiteral */: + if (this.context.strict && token.octal) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictOctalLiteral); + } + var raw = this.getTokenRaw(token); + key = this.finalize(node, new Node.Literal(token.value, raw)); + break; + case 3 /* Identifier */: + case 1 /* BooleanLiteral */: + case 5 /* NullLiteral */: + case 4 /* Keyword */: + key = this.finalize(node, new Node.Identifier(token.value)); + break; + case 7 /* Punctuator */: + if (token.value === '[') { + key = this.isolateCoverGrammar(this.parseAssignmentExpression); + this.expect(']'); + } + else { + key = this.throwUnexpectedToken(token); + } + break; + default: + key = this.throwUnexpectedToken(token); + } + return key; + }; + Parser.prototype.isPropertyKey = function (key, value) { + return (key.type === syntax_1.Syntax.Identifier && key.name === value) || + (key.type === syntax_1.Syntax.Literal && key.value === value); + }; + Parser.prototype.parseObjectProperty = function (hasProto) { + var node = this.createNode(); + var token = this.lookahead; + var kind; + var key = null; + var value = null; + var computed = false; + var method = false; + var shorthand = false; + var isAsync = false; + if (token.type === 3 /* Identifier */) { + var id = token.value; + this.nextToken(); + computed = this.match('['); + isAsync = !this.hasLineTerminator && (id === 'async') && + !this.match(':') && !this.match('(') && !this.match('*') && !this.match(','); + key = isAsync ? this.parseObjectPropertyKey() : this.finalize(node, new Node.Identifier(id)); + } + else if (this.match('*')) { + this.nextToken(); + } + else { + computed = this.match('['); + key = this.parseObjectPropertyKey(); + } + var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); + if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'get' && lookaheadPropertyKey) { + kind = 'get'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + this.context.allowYield = false; + value = this.parseGetterMethod(); + } + else if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'set' && lookaheadPropertyKey) { + kind = 'set'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseSetterMethod(); + } + else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) { + kind = 'init'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseGeneratorMethod(); + method = true; + } + else { + if (!key) { + this.throwUnexpectedToken(this.lookahead); + } + kind = 'init'; + if (this.match(':') && !isAsync) { + if (!computed && this.isPropertyKey(key, '__proto__')) { + if (hasProto.value) { + this.tolerateError(messages_1.Messages.DuplicateProtoProperty); + } + hasProto.value = true; + } + this.nextToken(); + value = this.inheritCoverGrammar(this.parseAssignmentExpression); + } + else if (this.match('(')) { + value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction(); + method = true; + } + else if (token.type === 3 /* Identifier */) { + var id = this.finalize(node, new Node.Identifier(token.value)); + if (this.match('=')) { + this.context.firstCoverInitializedNameError = this.lookahead; + this.nextToken(); + shorthand = true; + var init = this.isolateCoverGrammar(this.parseAssignmentExpression); + value = this.finalize(node, new Node.AssignmentPattern(id, init)); + } + else { + shorthand = true; + value = id; + } + } + else { + this.throwUnexpectedToken(this.nextToken()); + } + } + return this.finalize(node, new Node.Property(kind, key, computed, value, method, shorthand)); + }; + Parser.prototype.parseObjectInitializer = function () { + var node = this.createNode(); + this.expect('{'); + var properties = []; + var hasProto = { value: false }; + while (!this.match('}')) { + properties.push(this.parseObjectProperty(hasProto)); + if (!this.match('}')) { + this.expectCommaSeparator(); + } + } + this.expect('}'); + return this.finalize(node, new Node.ObjectExpression(properties)); + }; + // https://tc39.github.io/ecma262/#sec-template-literals + Parser.prototype.parseTemplateHead = function () { + assert_1.assert(this.lookahead.head, 'Template literal must start with a template head'); + var node = this.createNode(); + var token = this.nextToken(); + var raw = token.value; + var cooked = token.cooked; + return this.finalize(node, new Node.TemplateElement({ raw: raw, cooked: cooked }, token.tail)); + }; + Parser.prototype.parseTemplateElement = function () { + if (this.lookahead.type !== 10 /* Template */) { + this.throwUnexpectedToken(); + } + var node = this.createNode(); + var token = this.nextToken(); + var raw = token.value; + var cooked = token.cooked; + return this.finalize(node, new Node.TemplateElement({ raw: raw, cooked: cooked }, token.tail)); + }; + Parser.prototype.parseTemplateLiteral = function () { + var node = this.createNode(); + var expressions = []; + var quasis = []; + var quasi = this.parseTemplateHead(); + quasis.push(quasi); + while (!quasi.tail) { + expressions.push(this.parseExpression()); + quasi = this.parseTemplateElement(); + quasis.push(quasi); + } + return this.finalize(node, new Node.TemplateLiteral(quasis, expressions)); + }; + // https://tc39.github.io/ecma262/#sec-grouping-operator + Parser.prototype.reinterpretExpressionAsPattern = function (expr) { + switch (expr.type) { + case syntax_1.Syntax.Identifier: + case syntax_1.Syntax.MemberExpression: + case syntax_1.Syntax.RestElement: + case syntax_1.Syntax.AssignmentPattern: + break; + case syntax_1.Syntax.SpreadElement: + expr.type = syntax_1.Syntax.RestElement; + this.reinterpretExpressionAsPattern(expr.argument); + break; + case syntax_1.Syntax.ArrayExpression: + expr.type = syntax_1.Syntax.ArrayPattern; + for (var i = 0; i < expr.elements.length; i++) { + if (expr.elements[i] !== null) { + this.reinterpretExpressionAsPattern(expr.elements[i]); + } + } + break; + case syntax_1.Syntax.ObjectExpression: + expr.type = syntax_1.Syntax.ObjectPattern; + for (var i = 0; i < expr.properties.length; i++) { + this.reinterpretExpressionAsPattern(expr.properties[i].value); + } + break; + case syntax_1.Syntax.AssignmentExpression: + expr.type = syntax_1.Syntax.AssignmentPattern; + delete expr.operator; + this.reinterpretExpressionAsPattern(expr.left); + break; + default: + // Allow other node type for tolerant parsing. + break; + } + }; + Parser.prototype.parseGroupExpression = function () { + var expr; + this.expect('('); + if (this.match(')')) { + this.nextToken(); + if (!this.match('=>')) { + this.expect('=>'); + } + expr = { + type: ArrowParameterPlaceHolder, + params: [], + async: false + }; + } + else { + var startToken = this.lookahead; + var params = []; + if (this.match('...')) { + expr = this.parseRestElement(params); + this.expect(')'); + if (!this.match('=>')) { + this.expect('=>'); + } + expr = { + type: ArrowParameterPlaceHolder, + params: [expr], + async: false + }; + } + else { + var arrow = false; + this.context.isBindingElement = true; + expr = this.inheritCoverGrammar(this.parseAssignmentExpression); + if (this.match(',')) { + var expressions = []; + this.context.isAssignmentTarget = false; + expressions.push(expr); + while (this.lookahead.type !== 2 /* EOF */) { + if (!this.match(',')) { + break; + } + this.nextToken(); + if (this.match(')')) { + this.nextToken(); + for (var i = 0; i < expressions.length; i++) { + this.reinterpretExpressionAsPattern(expressions[i]); + } + arrow = true; + expr = { + type: ArrowParameterPlaceHolder, + params: expressions, + async: false + }; + } + else if (this.match('...')) { + if (!this.context.isBindingElement) { + this.throwUnexpectedToken(this.lookahead); + } + expressions.push(this.parseRestElement(params)); + this.expect(')'); + if (!this.match('=>')) { + this.expect('=>'); + } + this.context.isBindingElement = false; + for (var i = 0; i < expressions.length; i++) { + this.reinterpretExpressionAsPattern(expressions[i]); + } + arrow = true; + expr = { + type: ArrowParameterPlaceHolder, + params: expressions, + async: false + }; + } + else { + expressions.push(this.inheritCoverGrammar(this.parseAssignmentExpression)); + } + if (arrow) { + break; + } + } + if (!arrow) { + expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions)); + } + } + if (!arrow) { + this.expect(')'); + if (this.match('=>')) { + if (expr.type === syntax_1.Syntax.Identifier && expr.name === 'yield') { + arrow = true; + expr = { + type: ArrowParameterPlaceHolder, + params: [expr], + async: false + }; + } + if (!arrow) { + if (!this.context.isBindingElement) { + this.throwUnexpectedToken(this.lookahead); + } + if (expr.type === syntax_1.Syntax.SequenceExpression) { + for (var i = 0; i < expr.expressions.length; i++) { + this.reinterpretExpressionAsPattern(expr.expressions[i]); + } + } + else { + this.reinterpretExpressionAsPattern(expr); + } + var parameters = (expr.type === syntax_1.Syntax.SequenceExpression ? expr.expressions : [expr]); + expr = { + type: ArrowParameterPlaceHolder, + params: parameters, + async: false + }; + } + } + this.context.isBindingElement = false; + } + } + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-left-hand-side-expressions + Parser.prototype.parseArguments = function () { + this.expect('('); + var args = []; + if (!this.match(')')) { + while (true) { + var expr = this.match('...') ? this.parseSpreadElement() : + this.isolateCoverGrammar(this.parseAssignmentExpression); + args.push(expr); + if (this.match(')')) { + break; + } + this.expectCommaSeparator(); + if (this.match(')')) { + break; + } + } + } + this.expect(')'); + return args; + }; + Parser.prototype.isIdentifierName = function (token) { + return token.type === 3 /* Identifier */ || + token.type === 4 /* Keyword */ || + token.type === 1 /* BooleanLiteral */ || + token.type === 5 /* NullLiteral */; + }; + Parser.prototype.parseIdentifierName = function () { + var node = this.createNode(); + var token = this.nextToken(); + if (!this.isIdentifierName(token)) { + this.throwUnexpectedToken(token); + } + return this.finalize(node, new Node.Identifier(token.value)); + }; + Parser.prototype.parseNewExpression = function () { + var node = this.createNode(); + var id = this.parseIdentifierName(); + assert_1.assert(id.name === 'new', 'New expression must start with `new`'); + var expr; + if (this.match('.')) { + this.nextToken(); + if (this.lookahead.type === 3 /* Identifier */ && this.context.inFunctionBody && this.lookahead.value === 'target') { + var property = this.parseIdentifierName(); + expr = new Node.MetaProperty(id, property); + } + else { + this.throwUnexpectedToken(this.lookahead); + } + } + else { + var callee = this.isolateCoverGrammar(this.parseLeftHandSideExpression); + var args = this.match('(') ? this.parseArguments() : []; + expr = new Node.NewExpression(callee, args); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + return this.finalize(node, expr); + }; + Parser.prototype.parseAsyncArgument = function () { + var arg = this.parseAssignmentExpression(); + this.context.firstCoverInitializedNameError = null; + return arg; + }; + Parser.prototype.parseAsyncArguments = function () { + this.expect('('); + var args = []; + if (!this.match(')')) { + while (true) { + var expr = this.match('...') ? this.parseSpreadElement() : + this.isolateCoverGrammar(this.parseAsyncArgument); + args.push(expr); + if (this.match(')')) { + break; + } + this.expectCommaSeparator(); + if (this.match(')')) { + break; + } + } + } + this.expect(')'); + return args; + }; + Parser.prototype.parseLeftHandSideExpressionAllowCall = function () { + var startToken = this.lookahead; + var maybeAsync = this.matchContextualKeyword('async'); + var previousAllowIn = this.context.allowIn; + this.context.allowIn = true; + var expr; + if (this.matchKeyword('super') && this.context.inFunctionBody) { + expr = this.createNode(); + this.nextToken(); + expr = this.finalize(expr, new Node.Super()); + if (!this.match('(') && !this.match('.') && !this.match('[')) { + this.throwUnexpectedToken(this.lookahead); + } + } + else { + expr = this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); + } + while (true) { + if (this.match('.')) { + this.context.isBindingElement = false; + this.context.isAssignmentTarget = true; + this.expect('.'); + var property = this.parseIdentifierName(); + expr = this.finalize(this.startNode(startToken), new Node.StaticMemberExpression(expr, property)); + } + else if (this.match('(')) { + var asyncArrow = maybeAsync && (startToken.lineNumber === this.lookahead.lineNumber); + this.context.isBindingElement = false; + this.context.isAssignmentTarget = false; + var args = asyncArrow ? this.parseAsyncArguments() : this.parseArguments(); + expr = this.finalize(this.startNode(startToken), new Node.CallExpression(expr, args)); + if (asyncArrow && this.match('=>')) { + for (var i = 0; i < args.length; ++i) { + this.reinterpretExpressionAsPattern(args[i]); + } + expr = { + type: ArrowParameterPlaceHolder, + params: args, + async: true + }; + } + } + else if (this.match('[')) { + this.context.isBindingElement = false; + this.context.isAssignmentTarget = true; + this.expect('['); + var property = this.isolateCoverGrammar(this.parseExpression); + this.expect(']'); + expr = this.finalize(this.startNode(startToken), new Node.ComputedMemberExpression(expr, property)); + } + else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) { + var quasi = this.parseTemplateLiteral(); + expr = this.finalize(this.startNode(startToken), new Node.TaggedTemplateExpression(expr, quasi)); + } + else { + break; + } + } + this.context.allowIn = previousAllowIn; + return expr; + }; + Parser.prototype.parseSuper = function () { + var node = this.createNode(); + this.expectKeyword('super'); + if (!this.match('[') && !this.match('.')) { + this.throwUnexpectedToken(this.lookahead); + } + return this.finalize(node, new Node.Super()); + }; + Parser.prototype.parseLeftHandSideExpression = function () { + assert_1.assert(this.context.allowIn, 'callee of new expression always allow in keyword.'); + var node = this.startNode(this.lookahead); + var expr = (this.matchKeyword('super') && this.context.inFunctionBody) ? this.parseSuper() : + this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); + while (true) { + if (this.match('[')) { + this.context.isBindingElement = false; + this.context.isAssignmentTarget = true; + this.expect('['); + var property = this.isolateCoverGrammar(this.parseExpression); + this.expect(']'); + expr = this.finalize(node, new Node.ComputedMemberExpression(expr, property)); + } + else if (this.match('.')) { + this.context.isBindingElement = false; + this.context.isAssignmentTarget = true; + this.expect('.'); + var property = this.parseIdentifierName(); + expr = this.finalize(node, new Node.StaticMemberExpression(expr, property)); + } + else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) { + var quasi = this.parseTemplateLiteral(); + expr = this.finalize(node, new Node.TaggedTemplateExpression(expr, quasi)); + } + else { + break; + } + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-update-expressions + Parser.prototype.parseUpdateExpression = function () { + var expr; + var startToken = this.lookahead; + if (this.match('++') || this.match('--')) { + var node = this.startNode(startToken); + var token = this.nextToken(); + expr = this.inheritCoverGrammar(this.parseUnaryExpression); + if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) { + this.tolerateError(messages_1.Messages.StrictLHSPrefix); + } + if (!this.context.isAssignmentTarget) { + this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); + } + var prefix = true; + expr = this.finalize(node, new Node.UpdateExpression(token.value, expr, prefix)); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + else { + expr = this.inheritCoverGrammar(this.parseLeftHandSideExpressionAllowCall); + if (!this.hasLineTerminator && this.lookahead.type === 7 /* Punctuator */) { + if (this.match('++') || this.match('--')) { + if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) { + this.tolerateError(messages_1.Messages.StrictLHSPostfix); + } + if (!this.context.isAssignmentTarget) { + this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); + } + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var operator = this.nextToken().value; + var prefix = false; + expr = this.finalize(this.startNode(startToken), new Node.UpdateExpression(operator, expr, prefix)); + } + } + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-unary-operators + Parser.prototype.parseAwaitExpression = function () { + var node = this.createNode(); + this.nextToken(); + var argument = this.parseUnaryExpression(); + return this.finalize(node, new Node.AwaitExpression(argument)); + }; + Parser.prototype.parseUnaryExpression = function () { + var expr; + if (this.match('+') || this.match('-') || this.match('~') || this.match('!') || + this.matchKeyword('delete') || this.matchKeyword('void') || this.matchKeyword('typeof')) { + var node = this.startNode(this.lookahead); + var token = this.nextToken(); + expr = this.inheritCoverGrammar(this.parseUnaryExpression); + expr = this.finalize(node, new Node.UnaryExpression(token.value, expr)); + if (this.context.strict && expr.operator === 'delete' && expr.argument.type === syntax_1.Syntax.Identifier) { + this.tolerateError(messages_1.Messages.StrictDelete); + } + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + else if (this.context.await && this.matchContextualKeyword('await')) { + expr = this.parseAwaitExpression(); + } + else { + expr = this.parseUpdateExpression(); + } + return expr; + }; + Parser.prototype.parseExponentiationExpression = function () { + var startToken = this.lookahead; + var expr = this.inheritCoverGrammar(this.parseUnaryExpression); + if (expr.type !== syntax_1.Syntax.UnaryExpression && this.match('**')) { + this.nextToken(); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var left = expr; + var right = this.isolateCoverGrammar(this.parseExponentiationExpression); + expr = this.finalize(this.startNode(startToken), new Node.BinaryExpression('**', left, right)); + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-exp-operator + // https://tc39.github.io/ecma262/#sec-multiplicative-operators + // https://tc39.github.io/ecma262/#sec-additive-operators + // https://tc39.github.io/ecma262/#sec-bitwise-shift-operators + // https://tc39.github.io/ecma262/#sec-relational-operators + // https://tc39.github.io/ecma262/#sec-equality-operators + // https://tc39.github.io/ecma262/#sec-binary-bitwise-operators + // https://tc39.github.io/ecma262/#sec-binary-logical-operators + Parser.prototype.binaryPrecedence = function (token) { + var op = token.value; + var precedence; + if (token.type === 7 /* Punctuator */) { + precedence = this.operatorPrecedence[op] || 0; + } + else if (token.type === 4 /* Keyword */) { + precedence = (op === 'instanceof' || (this.context.allowIn && op === 'in')) ? 7 : 0; + } + else { + precedence = 0; + } + return precedence; + }; + Parser.prototype.parseBinaryExpression = function () { + var startToken = this.lookahead; + var expr = this.inheritCoverGrammar(this.parseExponentiationExpression); + var token = this.lookahead; + var prec = this.binaryPrecedence(token); + if (prec > 0) { + this.nextToken(); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var markers = [startToken, this.lookahead]; + var left = expr; + var right = this.isolateCoverGrammar(this.parseExponentiationExpression); + var stack = [left, token.value, right]; + var precedences = [prec]; + while (true) { + prec = this.binaryPrecedence(this.lookahead); + if (prec <= 0) { + break; + } + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= precedences[precedences.length - 1])) { + right = stack.pop(); + var operator = stack.pop(); + precedences.pop(); + left = stack.pop(); + markers.pop(); + var node = this.startNode(markers[markers.length - 1]); + stack.push(this.finalize(node, new Node.BinaryExpression(operator, left, right))); + } + // Shift. + stack.push(this.nextToken().value); + precedences.push(prec); + markers.push(this.lookahead); + stack.push(this.isolateCoverGrammar(this.parseExponentiationExpression)); + } + // Final reduce to clean-up the stack. + var i = stack.length - 1; + expr = stack[i]; + var lastMarker = markers.pop(); + while (i > 1) { + var marker = markers.pop(); + var lastLineStart = lastMarker && lastMarker.lineStart; + var node = this.startNode(marker, lastLineStart); + var operator = stack[i - 1]; + expr = this.finalize(node, new Node.BinaryExpression(operator, stack[i - 2], expr)); + i -= 2; + lastMarker = marker; + } + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-conditional-operator + Parser.prototype.parseConditionalExpression = function () { + var startToken = this.lookahead; + var expr = this.inheritCoverGrammar(this.parseBinaryExpression); + if (this.match('?')) { + this.nextToken(); + var previousAllowIn = this.context.allowIn; + this.context.allowIn = true; + var consequent = this.isolateCoverGrammar(this.parseAssignmentExpression); + this.context.allowIn = previousAllowIn; + this.expect(':'); + var alternate = this.isolateCoverGrammar(this.parseAssignmentExpression); + expr = this.finalize(this.startNode(startToken), new Node.ConditionalExpression(expr, consequent, alternate)); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-assignment-operators + Parser.prototype.checkPatternParam = function (options, param) { + switch (param.type) { + case syntax_1.Syntax.Identifier: + this.validateParam(options, param, param.name); + break; + case syntax_1.Syntax.RestElement: + this.checkPatternParam(options, param.argument); + break; + case syntax_1.Syntax.AssignmentPattern: + this.checkPatternParam(options, param.left); + break; + case syntax_1.Syntax.ArrayPattern: + for (var i = 0; i < param.elements.length; i++) { + if (param.elements[i] !== null) { + this.checkPatternParam(options, param.elements[i]); + } + } + break; + case syntax_1.Syntax.ObjectPattern: + for (var i = 0; i < param.properties.length; i++) { + this.checkPatternParam(options, param.properties[i].value); + } + break; + default: + break; + } + options.simple = options.simple && (param instanceof Node.Identifier); + }; + Parser.prototype.reinterpretAsCoverFormalsList = function (expr) { + var params = [expr]; + var options; + var asyncArrow = false; + switch (expr.type) { + case syntax_1.Syntax.Identifier: + break; + case ArrowParameterPlaceHolder: + params = expr.params; + asyncArrow = expr.async; + break; + default: + return null; + } + options = { + simple: true, + paramSet: {} + }; + for (var i = 0; i < params.length; ++i) { + var param = params[i]; + if (param.type === syntax_1.Syntax.AssignmentPattern) { + if (param.right.type === syntax_1.Syntax.YieldExpression) { + if (param.right.argument) { + this.throwUnexpectedToken(this.lookahead); + } + param.right.type = syntax_1.Syntax.Identifier; + param.right.name = 'yield'; + delete param.right.argument; + delete param.right.delegate; + } + } + else if (asyncArrow && param.type === syntax_1.Syntax.Identifier && param.name === 'await') { + this.throwUnexpectedToken(this.lookahead); + } + this.checkPatternParam(options, param); + params[i] = param; + } + if (this.context.strict || !this.context.allowYield) { + for (var i = 0; i < params.length; ++i) { + var param = params[i]; + if (param.type === syntax_1.Syntax.YieldExpression) { + this.throwUnexpectedToken(this.lookahead); + } + } + } + if (options.message === messages_1.Messages.StrictParamDupe) { + var token = this.context.strict ? options.stricted : options.firstRestricted; + this.throwUnexpectedToken(token, options.message); + } + return { + simple: options.simple, + params: params, + stricted: options.stricted, + firstRestricted: options.firstRestricted, + message: options.message + }; + }; + Parser.prototype.parseAssignmentExpression = function () { + var expr; + if (!this.context.allowYield && this.matchKeyword('yield')) { + expr = this.parseYieldExpression(); + } + else { + var startToken = this.lookahead; + var token = startToken; + expr = this.parseConditionalExpression(); + if (token.type === 3 /* Identifier */ && (token.lineNumber === this.lookahead.lineNumber) && token.value === 'async') { + if (this.lookahead.type === 3 /* Identifier */ || this.matchKeyword('yield')) { + var arg = this.parsePrimaryExpression(); + this.reinterpretExpressionAsPattern(arg); + expr = { + type: ArrowParameterPlaceHolder, + params: [arg], + async: true + }; + } + } + if (expr.type === ArrowParameterPlaceHolder || this.match('=>')) { + // https://tc39.github.io/ecma262/#sec-arrow-function-definitions + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var isAsync = expr.async; + var list = this.reinterpretAsCoverFormalsList(expr); + if (list) { + if (this.hasLineTerminator) { + this.tolerateUnexpectedToken(this.lookahead); + } + this.context.firstCoverInitializedNameError = null; + var previousStrict = this.context.strict; + var previousAllowStrictDirective = this.context.allowStrictDirective; + this.context.allowStrictDirective = list.simple; + var previousAllowYield = this.context.allowYield; + var previousAwait = this.context.await; + this.context.allowYield = true; + this.context.await = isAsync; + var node = this.startNode(startToken); + this.expect('=>'); + var body = void 0; + if (this.match('{')) { + var previousAllowIn = this.context.allowIn; + this.context.allowIn = true; + body = this.parseFunctionSourceElements(); + this.context.allowIn = previousAllowIn; + } + else { + body = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + var expression = body.type !== syntax_1.Syntax.BlockStatement; + if (this.context.strict && list.firstRestricted) { + this.throwUnexpectedToken(list.firstRestricted, list.message); + } + if (this.context.strict && list.stricted) { + this.tolerateUnexpectedToken(list.stricted, list.message); + } + expr = isAsync ? this.finalize(node, new Node.AsyncArrowFunctionExpression(list.params, body, expression)) : + this.finalize(node, new Node.ArrowFunctionExpression(list.params, body, expression)); + this.context.strict = previousStrict; + this.context.allowStrictDirective = previousAllowStrictDirective; + this.context.allowYield = previousAllowYield; + this.context.await = previousAwait; + } + } + else { + if (this.matchAssign()) { + if (!this.context.isAssignmentTarget) { + this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); + } + if (this.context.strict && expr.type === syntax_1.Syntax.Identifier) { + var id = expr; + if (this.scanner.isRestrictedWord(id.name)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictLHSAssignment); + } + if (this.scanner.isStrictModeReservedWord(id.name)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); + } + } + if (!this.match('=')) { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + else { + this.reinterpretExpressionAsPattern(expr); + } + token = this.nextToken(); + var operator = token.value; + var right = this.isolateCoverGrammar(this.parseAssignmentExpression); + expr = this.finalize(this.startNode(startToken), new Node.AssignmentExpression(operator, expr, right)); + this.context.firstCoverInitializedNameError = null; + } + } + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-comma-operator + Parser.prototype.parseExpression = function () { + var startToken = this.lookahead; + var expr = this.isolateCoverGrammar(this.parseAssignmentExpression); + if (this.match(',')) { + var expressions = []; + expressions.push(expr); + while (this.lookahead.type !== 2 /* EOF */) { + if (!this.match(',')) { + break; + } + this.nextToken(); + expressions.push(this.isolateCoverGrammar(this.parseAssignmentExpression)); + } + expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions)); + } + return expr; + }; + // https://tc39.github.io/ecma262/#sec-block + Parser.prototype.parseStatementListItem = function () { + var statement; + this.context.isAssignmentTarget = true; + this.context.isBindingElement = true; + if (this.lookahead.type === 4 /* Keyword */) { + switch (this.lookahead.value) { + case 'export': + if (!this.context.isModule) { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalExportDeclaration); + } + statement = this.parseExportDeclaration(); + break; + case 'import': + if (!this.context.isModule) { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalImportDeclaration); + } + statement = this.parseImportDeclaration(); + break; + case 'const': + statement = this.parseLexicalDeclaration({ inFor: false }); + break; + case 'function': + statement = this.parseFunctionDeclaration(); + break; + case 'class': + statement = this.parseClassDeclaration(); + break; + case 'let': + statement = this.isLexicalDeclaration() ? this.parseLexicalDeclaration({ inFor: false }) : this.parseStatement(); + break; + default: + statement = this.parseStatement(); + break; + } + } + else { + statement = this.parseStatement(); + } + return statement; + }; + Parser.prototype.parseBlock = function () { + var node = this.createNode(); + this.expect('{'); + var block = []; + while (true) { + if (this.match('}')) { + break; + } + block.push(this.parseStatementListItem()); + } + this.expect('}'); + return this.finalize(node, new Node.BlockStatement(block)); + }; + // https://tc39.github.io/ecma262/#sec-let-and-const-declarations + Parser.prototype.parseLexicalBinding = function (kind, options) { + var node = this.createNode(); + var params = []; + var id = this.parsePattern(params, kind); + if (this.context.strict && id.type === syntax_1.Syntax.Identifier) { + if (this.scanner.isRestrictedWord(id.name)) { + this.tolerateError(messages_1.Messages.StrictVarName); + } + } + var init = null; + if (kind === 'const') { + if (!this.matchKeyword('in') && !this.matchContextualKeyword('of')) { + if (this.match('=')) { + this.nextToken(); + init = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + else { + this.throwError(messages_1.Messages.DeclarationMissingInitializer, 'const'); + } + } + } + else if ((!options.inFor && id.type !== syntax_1.Syntax.Identifier) || this.match('=')) { + this.expect('='); + init = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + return this.finalize(node, new Node.VariableDeclarator(id, init)); + }; + Parser.prototype.parseBindingList = function (kind, options) { + var list = [this.parseLexicalBinding(kind, options)]; + while (this.match(',')) { + this.nextToken(); + list.push(this.parseLexicalBinding(kind, options)); + } + return list; + }; + Parser.prototype.isLexicalDeclaration = function () { + var state = this.scanner.saveState(); + this.scanner.scanComments(); + var next = this.scanner.lex(); + this.scanner.restoreState(state); + return (next.type === 3 /* Identifier */) || + (next.type === 7 /* Punctuator */ && next.value === '[') || + (next.type === 7 /* Punctuator */ && next.value === '{') || + (next.type === 4 /* Keyword */ && next.value === 'let') || + (next.type === 4 /* Keyword */ && next.value === 'yield'); + }; + Parser.prototype.parseLexicalDeclaration = function (options) { + var node = this.createNode(); + var kind = this.nextToken().value; + assert_1.assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const'); + var declarations = this.parseBindingList(kind, options); + this.consumeSemicolon(); + return this.finalize(node, new Node.VariableDeclaration(declarations, kind)); + }; + // https://tc39.github.io/ecma262/#sec-destructuring-binding-patterns + Parser.prototype.parseBindingRestElement = function (params, kind) { + var node = this.createNode(); + this.expect('...'); + var arg = this.parsePattern(params, kind); + return this.finalize(node, new Node.RestElement(arg)); + }; + Parser.prototype.parseArrayPattern = function (params, kind) { + var node = this.createNode(); + this.expect('['); + var elements = []; + while (!this.match(']')) { + if (this.match(',')) { + this.nextToken(); + elements.push(null); + } + else { + if (this.match('...')) { + elements.push(this.parseBindingRestElement(params, kind)); + break; + } + else { + elements.push(this.parsePatternWithDefault(params, kind)); + } + if (!this.match(']')) { + this.expect(','); + } + } + } + this.expect(']'); + return this.finalize(node, new Node.ArrayPattern(elements)); + }; + Parser.prototype.parsePropertyPattern = function (params, kind) { + var node = this.createNode(); + var computed = false; + var shorthand = false; + var method = false; + var key; + var value; + if (this.lookahead.type === 3 /* Identifier */) { + var keyToken = this.lookahead; + key = this.parseVariableIdentifier(); + var init = this.finalize(node, new Node.Identifier(keyToken.value)); + if (this.match('=')) { + params.push(keyToken); + shorthand = true; + this.nextToken(); + var expr = this.parseAssignmentExpression(); + value = this.finalize(this.startNode(keyToken), new Node.AssignmentPattern(init, expr)); + } + else if (!this.match(':')) { + params.push(keyToken); + shorthand = true; + value = init; + } + else { + this.expect(':'); + value = this.parsePatternWithDefault(params, kind); + } + } + else { + computed = this.match('['); + key = this.parseObjectPropertyKey(); + this.expect(':'); + value = this.parsePatternWithDefault(params, kind); + } + return this.finalize(node, new Node.Property('init', key, computed, value, method, shorthand)); + }; + Parser.prototype.parseObjectPattern = function (params, kind) { + var node = this.createNode(); + var properties = []; + this.expect('{'); + while (!this.match('}')) { + properties.push(this.parsePropertyPattern(params, kind)); + if (!this.match('}')) { + this.expect(','); + } + } + this.expect('}'); + return this.finalize(node, new Node.ObjectPattern(properties)); + }; + Parser.prototype.parsePattern = function (params, kind) { + var pattern; + if (this.match('[')) { + pattern = this.parseArrayPattern(params, kind); + } + else if (this.match('{')) { + pattern = this.parseObjectPattern(params, kind); + } + else { + if (this.matchKeyword('let') && (kind === 'const' || kind === 'let')) { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.LetInLexicalBinding); + } + params.push(this.lookahead); + pattern = this.parseVariableIdentifier(kind); + } + return pattern; + }; + Parser.prototype.parsePatternWithDefault = function (params, kind) { + var startToken = this.lookahead; + var pattern = this.parsePattern(params, kind); + if (this.match('=')) { + this.nextToken(); + var previousAllowYield = this.context.allowYield; + this.context.allowYield = true; + var right = this.isolateCoverGrammar(this.parseAssignmentExpression); + this.context.allowYield = previousAllowYield; + pattern = this.finalize(this.startNode(startToken), new Node.AssignmentPattern(pattern, right)); + } + return pattern; + }; + // https://tc39.github.io/ecma262/#sec-variable-statement + Parser.prototype.parseVariableIdentifier = function (kind) { + var node = this.createNode(); + var token = this.nextToken(); + if (token.type === 4 /* Keyword */ && token.value === 'yield') { + if (this.context.strict) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); + } + else if (!this.context.allowYield) { + this.throwUnexpectedToken(token); + } + } + else if (token.type !== 3 /* Identifier */) { + if (this.context.strict && token.type === 4 /* Keyword */ && this.scanner.isStrictModeReservedWord(token.value)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); + } + else { + if (this.context.strict || token.value !== 'let' || kind !== 'var') { + this.throwUnexpectedToken(token); + } + } + } + else if ((this.context.isModule || this.context.await) && token.type === 3 /* Identifier */ && token.value === 'await') { + this.tolerateUnexpectedToken(token); + } + return this.finalize(node, new Node.Identifier(token.value)); + }; + Parser.prototype.parseVariableDeclaration = function (options) { + var node = this.createNode(); + var params = []; + var id = this.parsePattern(params, 'var'); + if (this.context.strict && id.type === syntax_1.Syntax.Identifier) { + if (this.scanner.isRestrictedWord(id.name)) { + this.tolerateError(messages_1.Messages.StrictVarName); + } + } + var init = null; + if (this.match('=')) { + this.nextToken(); + init = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + else if (id.type !== syntax_1.Syntax.Identifier && !options.inFor) { + this.expect('='); + } + return this.finalize(node, new Node.VariableDeclarator(id, init)); + }; + Parser.prototype.parseVariableDeclarationList = function (options) { + var opt = { inFor: options.inFor }; + var list = []; + list.push(this.parseVariableDeclaration(opt)); + while (this.match(',')) { + this.nextToken(); + list.push(this.parseVariableDeclaration(opt)); + } + return list; + }; + Parser.prototype.parseVariableStatement = function () { + var node = this.createNode(); + this.expectKeyword('var'); + var declarations = this.parseVariableDeclarationList({ inFor: false }); + this.consumeSemicolon(); + return this.finalize(node, new Node.VariableDeclaration(declarations, 'var')); + }; + // https://tc39.github.io/ecma262/#sec-empty-statement + Parser.prototype.parseEmptyStatement = function () { + var node = this.createNode(); + this.expect(';'); + return this.finalize(node, new Node.EmptyStatement()); + }; + // https://tc39.github.io/ecma262/#sec-expression-statement + Parser.prototype.parseExpressionStatement = function () { + var node = this.createNode(); + var expr = this.parseExpression(); + this.consumeSemicolon(); + return this.finalize(node, new Node.ExpressionStatement(expr)); + }; + // https://tc39.github.io/ecma262/#sec-if-statement + Parser.prototype.parseIfClause = function () { + if (this.context.strict && this.matchKeyword('function')) { + this.tolerateError(messages_1.Messages.StrictFunction); + } + return this.parseStatement(); + }; + Parser.prototype.parseIfStatement = function () { + var node = this.createNode(); + var consequent; + var alternate = null; + this.expectKeyword('if'); + this.expect('('); + var test = this.parseExpression(); + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + consequent = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + consequent = this.parseIfClause(); + if (this.matchKeyword('else')) { + this.nextToken(); + alternate = this.parseIfClause(); + } + } + return this.finalize(node, new Node.IfStatement(test, consequent, alternate)); + }; + // https://tc39.github.io/ecma262/#sec-do-while-statement + Parser.prototype.parseDoWhileStatement = function () { + var node = this.createNode(); + this.expectKeyword('do'); + var previousInIteration = this.context.inIteration; + this.context.inIteration = true; + var body = this.parseStatement(); + this.context.inIteration = previousInIteration; + this.expectKeyword('while'); + this.expect('('); + var test = this.parseExpression(); + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + } + else { + this.expect(')'); + if (this.match(';')) { + this.nextToken(); + } + } + return this.finalize(node, new Node.DoWhileStatement(body, test)); + }; + // https://tc39.github.io/ecma262/#sec-while-statement + Parser.prototype.parseWhileStatement = function () { + var node = this.createNode(); + var body; + this.expectKeyword('while'); + this.expect('('); + var test = this.parseExpression(); + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + body = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + var previousInIteration = this.context.inIteration; + this.context.inIteration = true; + body = this.parseStatement(); + this.context.inIteration = previousInIteration; + } + return this.finalize(node, new Node.WhileStatement(test, body)); + }; + // https://tc39.github.io/ecma262/#sec-for-statement + // https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements + Parser.prototype.parseForStatement = function () { + var init = null; + var test = null; + var update = null; + var forIn = true; + var left, right; + var node = this.createNode(); + this.expectKeyword('for'); + this.expect('('); + if (this.match(';')) { + this.nextToken(); + } + else { + if (this.matchKeyword('var')) { + init = this.createNode(); + this.nextToken(); + var previousAllowIn = this.context.allowIn; + this.context.allowIn = false; + var declarations = this.parseVariableDeclarationList({ inFor: true }); + this.context.allowIn = previousAllowIn; + if (declarations.length === 1 && this.matchKeyword('in')) { + var decl = declarations[0]; + if (decl.init && (decl.id.type === syntax_1.Syntax.ArrayPattern || decl.id.type === syntax_1.Syntax.ObjectPattern || this.context.strict)) { + this.tolerateError(messages_1.Messages.ForInOfLoopInitializer, 'for-in'); + } + init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); + this.nextToken(); + left = init; + right = this.parseExpression(); + init = null; + } + else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) { + init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); + this.nextToken(); + left = init; + right = this.parseAssignmentExpression(); + init = null; + forIn = false; + } + else { + init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); + this.expect(';'); + } + } + else if (this.matchKeyword('const') || this.matchKeyword('let')) { + init = this.createNode(); + var kind = this.nextToken().value; + if (!this.context.strict && this.lookahead.value === 'in') { + init = this.finalize(init, new Node.Identifier(kind)); + this.nextToken(); + left = init; + right = this.parseExpression(); + init = null; + } + else { + var previousAllowIn = this.context.allowIn; + this.context.allowIn = false; + var declarations = this.parseBindingList(kind, { inFor: true }); + this.context.allowIn = previousAllowIn; + if (declarations.length === 1 && declarations[0].init === null && this.matchKeyword('in')) { + init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); + this.nextToken(); + left = init; + right = this.parseExpression(); + init = null; + } + else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) { + init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); + this.nextToken(); + left = init; + right = this.parseAssignmentExpression(); + init = null; + forIn = false; + } + else { + this.consumeSemicolon(); + init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); + } + } + } + else { + var initStartToken = this.lookahead; + var previousAllowIn = this.context.allowIn; + this.context.allowIn = false; + init = this.inheritCoverGrammar(this.parseAssignmentExpression); + this.context.allowIn = previousAllowIn; + if (this.matchKeyword('in')) { + if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) { + this.tolerateError(messages_1.Messages.InvalidLHSInForIn); + } + this.nextToken(); + this.reinterpretExpressionAsPattern(init); + left = init; + right = this.parseExpression(); + init = null; + } + else if (this.matchContextualKeyword('of')) { + if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) { + this.tolerateError(messages_1.Messages.InvalidLHSInForLoop); + } + this.nextToken(); + this.reinterpretExpressionAsPattern(init); + left = init; + right = this.parseAssignmentExpression(); + init = null; + forIn = false; + } + else { + if (this.match(',')) { + var initSeq = [init]; + while (this.match(',')) { + this.nextToken(); + initSeq.push(this.isolateCoverGrammar(this.parseAssignmentExpression)); + } + init = this.finalize(this.startNode(initStartToken), new Node.SequenceExpression(initSeq)); + } + this.expect(';'); + } + } + } + if (typeof left === 'undefined') { + if (!this.match(';')) { + test = this.parseExpression(); + } + this.expect(';'); + if (!this.match(')')) { + update = this.parseExpression(); + } + } + var body; + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + body = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + var previousInIteration = this.context.inIteration; + this.context.inIteration = true; + body = this.isolateCoverGrammar(this.parseStatement); + this.context.inIteration = previousInIteration; + } + return (typeof left === 'undefined') ? + this.finalize(node, new Node.ForStatement(init, test, update, body)) : + forIn ? this.finalize(node, new Node.ForInStatement(left, right, body)) : + this.finalize(node, new Node.ForOfStatement(left, right, body)); + }; + // https://tc39.github.io/ecma262/#sec-continue-statement + Parser.prototype.parseContinueStatement = function () { + var node = this.createNode(); + this.expectKeyword('continue'); + var label = null; + if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) { + var id = this.parseVariableIdentifier(); + label = id; + var key = '$' + id.name; + if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { + this.throwError(messages_1.Messages.UnknownLabel, id.name); + } + } + this.consumeSemicolon(); + if (label === null && !this.context.inIteration) { + this.throwError(messages_1.Messages.IllegalContinue); + } + return this.finalize(node, new Node.ContinueStatement(label)); + }; + // https://tc39.github.io/ecma262/#sec-break-statement + Parser.prototype.parseBreakStatement = function () { + var node = this.createNode(); + this.expectKeyword('break'); + var label = null; + if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) { + var id = this.parseVariableIdentifier(); + var key = '$' + id.name; + if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { + this.throwError(messages_1.Messages.UnknownLabel, id.name); + } + label = id; + } + this.consumeSemicolon(); + if (label === null && !this.context.inIteration && !this.context.inSwitch) { + this.throwError(messages_1.Messages.IllegalBreak); + } + return this.finalize(node, new Node.BreakStatement(label)); + }; + // https://tc39.github.io/ecma262/#sec-return-statement + Parser.prototype.parseReturnStatement = function () { + if (!this.context.inFunctionBody) { + this.tolerateError(messages_1.Messages.IllegalReturn); + } + var node = this.createNode(); + this.expectKeyword('return'); + var hasArgument = (!this.match(';') && !this.match('}') && + !this.hasLineTerminator && this.lookahead.type !== 2 /* EOF */) || + this.lookahead.type === 8 /* StringLiteral */ || + this.lookahead.type === 10 /* Template */; + var argument = hasArgument ? this.parseExpression() : null; + this.consumeSemicolon(); + return this.finalize(node, new Node.ReturnStatement(argument)); + }; + // https://tc39.github.io/ecma262/#sec-with-statement + Parser.prototype.parseWithStatement = function () { + if (this.context.strict) { + this.tolerateError(messages_1.Messages.StrictModeWith); + } + var node = this.createNode(); + var body; + this.expectKeyword('with'); + this.expect('('); + var object = this.parseExpression(); + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + body = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + body = this.parseStatement(); + } + return this.finalize(node, new Node.WithStatement(object, body)); + }; + // https://tc39.github.io/ecma262/#sec-switch-statement + Parser.prototype.parseSwitchCase = function () { + var node = this.createNode(); + var test; + if (this.matchKeyword('default')) { + this.nextToken(); + test = null; + } + else { + this.expectKeyword('case'); + test = this.parseExpression(); + } + this.expect(':'); + var consequent = []; + while (true) { + if (this.match('}') || this.matchKeyword('default') || this.matchKeyword('case')) { + break; + } + consequent.push(this.parseStatementListItem()); + } + return this.finalize(node, new Node.SwitchCase(test, consequent)); + }; + Parser.prototype.parseSwitchStatement = function () { + var node = this.createNode(); + this.expectKeyword('switch'); + this.expect('('); + var discriminant = this.parseExpression(); + this.expect(')'); + var previousInSwitch = this.context.inSwitch; + this.context.inSwitch = true; + var cases = []; + var defaultFound = false; + this.expect('{'); + while (true) { + if (this.match('}')) { + break; + } + var clause = this.parseSwitchCase(); + if (clause.test === null) { + if (defaultFound) { + this.throwError(messages_1.Messages.MultipleDefaultsInSwitch); + } + defaultFound = true; + } + cases.push(clause); + } + this.expect('}'); + this.context.inSwitch = previousInSwitch; + return this.finalize(node, new Node.SwitchStatement(discriminant, cases)); + }; + // https://tc39.github.io/ecma262/#sec-labelled-statements + Parser.prototype.parseLabelledStatement = function () { + var node = this.createNode(); + var expr = this.parseExpression(); + var statement; + if ((expr.type === syntax_1.Syntax.Identifier) && this.match(':')) { + this.nextToken(); + var id = expr; + var key = '$' + id.name; + if (Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { + this.throwError(messages_1.Messages.Redeclaration, 'Label', id.name); + } + this.context.labelSet[key] = true; + var body = void 0; + if (this.matchKeyword('class')) { + this.tolerateUnexpectedToken(this.lookahead); + body = this.parseClassDeclaration(); + } + else if (this.matchKeyword('function')) { + var token = this.lookahead; + var declaration = this.parseFunctionDeclaration(); + if (this.context.strict) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunction); + } + else if (declaration.generator) { + this.tolerateUnexpectedToken(token, messages_1.Messages.GeneratorInLegacyContext); + } + body = declaration; + } + else { + body = this.parseStatement(); + } + delete this.context.labelSet[key]; + statement = new Node.LabeledStatement(id, body); + } + else { + this.consumeSemicolon(); + statement = new Node.ExpressionStatement(expr); + } + return this.finalize(node, statement); + }; + // https://tc39.github.io/ecma262/#sec-throw-statement + Parser.prototype.parseThrowStatement = function () { + var node = this.createNode(); + this.expectKeyword('throw'); + if (this.hasLineTerminator) { + this.throwError(messages_1.Messages.NewlineAfterThrow); + } + var argument = this.parseExpression(); + this.consumeSemicolon(); + return this.finalize(node, new Node.ThrowStatement(argument)); + }; + // https://tc39.github.io/ecma262/#sec-try-statement + Parser.prototype.parseCatchClause = function () { + var node = this.createNode(); + this.expectKeyword('catch'); + this.expect('('); + if (this.match(')')) { + this.throwUnexpectedToken(this.lookahead); + } + var params = []; + var param = this.parsePattern(params); + var paramMap = {}; + for (var i = 0; i < params.length; i++) { + var key = '$' + params[i].value; + if (Object.prototype.hasOwnProperty.call(paramMap, key)) { + this.tolerateError(messages_1.Messages.DuplicateBinding, params[i].value); + } + paramMap[key] = true; + } + if (this.context.strict && param.type === syntax_1.Syntax.Identifier) { + if (this.scanner.isRestrictedWord(param.name)) { + this.tolerateError(messages_1.Messages.StrictCatchVariable); + } + } + this.expect(')'); + var body = this.parseBlock(); + return this.finalize(node, new Node.CatchClause(param, body)); + }; + Parser.prototype.parseFinallyClause = function () { + this.expectKeyword('finally'); + return this.parseBlock(); + }; + Parser.prototype.parseTryStatement = function () { + var node = this.createNode(); + this.expectKeyword('try'); + var block = this.parseBlock(); + var handler = this.matchKeyword('catch') ? this.parseCatchClause() : null; + var finalizer = this.matchKeyword('finally') ? this.parseFinallyClause() : null; + if (!handler && !finalizer) { + this.throwError(messages_1.Messages.NoCatchOrFinally); + } + return this.finalize(node, new Node.TryStatement(block, handler, finalizer)); + }; + // https://tc39.github.io/ecma262/#sec-debugger-statement + Parser.prototype.parseDebuggerStatement = function () { + var node = this.createNode(); + this.expectKeyword('debugger'); + this.consumeSemicolon(); + return this.finalize(node, new Node.DebuggerStatement()); + }; + // https://tc39.github.io/ecma262/#sec-ecmascript-language-statements-and-declarations + Parser.prototype.parseStatement = function () { + var statement; + switch (this.lookahead.type) { + case 1 /* BooleanLiteral */: + case 5 /* NullLiteral */: + case 6 /* NumericLiteral */: + case 8 /* StringLiteral */: + case 10 /* Template */: + case 9 /* RegularExpression */: + statement = this.parseExpressionStatement(); + break; + case 7 /* Punctuator */: + var value = this.lookahead.value; + if (value === '{') { + statement = this.parseBlock(); + } + else if (value === '(') { + statement = this.parseExpressionStatement(); + } + else if (value === ';') { + statement = this.parseEmptyStatement(); + } + else { + statement = this.parseExpressionStatement(); + } + break; + case 3 /* Identifier */: + statement = this.matchAsyncFunction() ? this.parseFunctionDeclaration() : this.parseLabelledStatement(); + break; + case 4 /* Keyword */: + switch (this.lookahead.value) { + case 'break': + statement = this.parseBreakStatement(); + break; + case 'continue': + statement = this.parseContinueStatement(); + break; + case 'debugger': + statement = this.parseDebuggerStatement(); + break; + case 'do': + statement = this.parseDoWhileStatement(); + break; + case 'for': + statement = this.parseForStatement(); + break; + case 'function': + statement = this.parseFunctionDeclaration(); + break; + case 'if': + statement = this.parseIfStatement(); + break; + case 'return': + statement = this.parseReturnStatement(); + break; + case 'switch': + statement = this.parseSwitchStatement(); + break; + case 'throw': + statement = this.parseThrowStatement(); + break; + case 'try': + statement = this.parseTryStatement(); + break; + case 'var': + statement = this.parseVariableStatement(); + break; + case 'while': + statement = this.parseWhileStatement(); + break; + case 'with': + statement = this.parseWithStatement(); + break; + default: + statement = this.parseExpressionStatement(); + break; + } + break; + default: + statement = this.throwUnexpectedToken(this.lookahead); + } + return statement; + }; + // https://tc39.github.io/ecma262/#sec-function-definitions + Parser.prototype.parseFunctionSourceElements = function () { + var node = this.createNode(); + this.expect('{'); + var body = this.parseDirectivePrologues(); + var previousLabelSet = this.context.labelSet; + var previousInIteration = this.context.inIteration; + var previousInSwitch = this.context.inSwitch; + var previousInFunctionBody = this.context.inFunctionBody; + this.context.labelSet = {}; + this.context.inIteration = false; + this.context.inSwitch = false; + this.context.inFunctionBody = true; + while (this.lookahead.type !== 2 /* EOF */) { + if (this.match('}')) { + break; + } + body.push(this.parseStatementListItem()); + } + this.expect('}'); + this.context.labelSet = previousLabelSet; + this.context.inIteration = previousInIteration; + this.context.inSwitch = previousInSwitch; + this.context.inFunctionBody = previousInFunctionBody; + return this.finalize(node, new Node.BlockStatement(body)); + }; + Parser.prototype.validateParam = function (options, param, name) { + var key = '$' + name; + if (this.context.strict) { + if (this.scanner.isRestrictedWord(name)) { + options.stricted = param; + options.message = messages_1.Messages.StrictParamName; + } + if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { + options.stricted = param; + options.message = messages_1.Messages.StrictParamDupe; + } + } + else if (!options.firstRestricted) { + if (this.scanner.isRestrictedWord(name)) { + options.firstRestricted = param; + options.message = messages_1.Messages.StrictParamName; + } + else if (this.scanner.isStrictModeReservedWord(name)) { + options.firstRestricted = param; + options.message = messages_1.Messages.StrictReservedWord; + } + else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { + options.stricted = param; + options.message = messages_1.Messages.StrictParamDupe; + } + } + /* istanbul ignore next */ + if (typeof Object.defineProperty === 'function') { + Object.defineProperty(options.paramSet, key, { value: true, enumerable: true, writable: true, configurable: true }); + } + else { + options.paramSet[key] = true; + } + }; + Parser.prototype.parseRestElement = function (params) { + var node = this.createNode(); + this.expect('...'); + var arg = this.parsePattern(params); + if (this.match('=')) { + this.throwError(messages_1.Messages.DefaultRestParameter); + } + if (!this.match(')')) { + this.throwError(messages_1.Messages.ParameterAfterRestParameter); + } + return this.finalize(node, new Node.RestElement(arg)); + }; + Parser.prototype.parseFormalParameter = function (options) { + var params = []; + var param = this.match('...') ? this.parseRestElement(params) : this.parsePatternWithDefault(params); + for (var i = 0; i < params.length; i++) { + this.validateParam(options, params[i], params[i].value); + } + options.simple = options.simple && (param instanceof Node.Identifier); + options.params.push(param); + }; + Parser.prototype.parseFormalParameters = function (firstRestricted) { + var options; + options = { + simple: true, + params: [], + firstRestricted: firstRestricted + }; + this.expect('('); + if (!this.match(')')) { + options.paramSet = {}; + while (this.lookahead.type !== 2 /* EOF */) { + this.parseFormalParameter(options); + if (this.match(')')) { + break; + } + this.expect(','); + if (this.match(')')) { + break; + } + } + } + this.expect(')'); + return { + simple: options.simple, + params: options.params, + stricted: options.stricted, + firstRestricted: options.firstRestricted, + message: options.message + }; + }; + Parser.prototype.matchAsyncFunction = function () { + var match = this.matchContextualKeyword('async'); + if (match) { + var state = this.scanner.saveState(); + this.scanner.scanComments(); + var next = this.scanner.lex(); + this.scanner.restoreState(state); + match = (state.lineNumber === next.lineNumber) && (next.type === 4 /* Keyword */) && (next.value === 'function'); + } + return match; + }; + Parser.prototype.parseFunctionDeclaration = function (identifierIsOptional) { + var node = this.createNode(); + var isAsync = this.matchContextualKeyword('async'); + if (isAsync) { + this.nextToken(); + } + this.expectKeyword('function'); + var isGenerator = isAsync ? false : this.match('*'); + if (isGenerator) { + this.nextToken(); + } + var message; + var id = null; + var firstRestricted = null; + if (!identifierIsOptional || !this.match('(')) { + var token = this.lookahead; + id = this.parseVariableIdentifier(); + if (this.context.strict) { + if (this.scanner.isRestrictedWord(token.value)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName); + } + } + else { + if (this.scanner.isRestrictedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictFunctionName; + } + else if (this.scanner.isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictReservedWord; + } + } + } + var previousAllowAwait = this.context.await; + var previousAllowYield = this.context.allowYield; + this.context.await = isAsync; + this.context.allowYield = !isGenerator; + var formalParameters = this.parseFormalParameters(firstRestricted); + var params = formalParameters.params; + var stricted = formalParameters.stricted; + firstRestricted = formalParameters.firstRestricted; + if (formalParameters.message) { + message = formalParameters.message; + } + var previousStrict = this.context.strict; + var previousAllowStrictDirective = this.context.allowStrictDirective; + this.context.allowStrictDirective = formalParameters.simple; + var body = this.parseFunctionSourceElements(); + if (this.context.strict && firstRestricted) { + this.throwUnexpectedToken(firstRestricted, message); + } + if (this.context.strict && stricted) { + this.tolerateUnexpectedToken(stricted, message); + } + this.context.strict = previousStrict; + this.context.allowStrictDirective = previousAllowStrictDirective; + this.context.await = previousAllowAwait; + this.context.allowYield = previousAllowYield; + return isAsync ? this.finalize(node, new Node.AsyncFunctionDeclaration(id, params, body)) : + this.finalize(node, new Node.FunctionDeclaration(id, params, body, isGenerator)); + }; + Parser.prototype.parseFunctionExpression = function () { + var node = this.createNode(); + var isAsync = this.matchContextualKeyword('async'); + if (isAsync) { + this.nextToken(); + } + this.expectKeyword('function'); + var isGenerator = isAsync ? false : this.match('*'); + if (isGenerator) { + this.nextToken(); + } + var message; + var id = null; + var firstRestricted; + var previousAllowAwait = this.context.await; + var previousAllowYield = this.context.allowYield; + this.context.await = isAsync; + this.context.allowYield = !isGenerator; + if (!this.match('(')) { + var token = this.lookahead; + id = (!this.context.strict && !isGenerator && this.matchKeyword('yield')) ? this.parseIdentifierName() : this.parseVariableIdentifier(); + if (this.context.strict) { + if (this.scanner.isRestrictedWord(token.value)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName); + } + } + else { + if (this.scanner.isRestrictedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictFunctionName; + } + else if (this.scanner.isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictReservedWord; + } + } + } + var formalParameters = this.parseFormalParameters(firstRestricted); + var params = formalParameters.params; + var stricted = formalParameters.stricted; + firstRestricted = formalParameters.firstRestricted; + if (formalParameters.message) { + message = formalParameters.message; + } + var previousStrict = this.context.strict; + var previousAllowStrictDirective = this.context.allowStrictDirective; + this.context.allowStrictDirective = formalParameters.simple; + var body = this.parseFunctionSourceElements(); + if (this.context.strict && firstRestricted) { + this.throwUnexpectedToken(firstRestricted, message); + } + if (this.context.strict && stricted) { + this.tolerateUnexpectedToken(stricted, message); + } + this.context.strict = previousStrict; + this.context.allowStrictDirective = previousAllowStrictDirective; + this.context.await = previousAllowAwait; + this.context.allowYield = previousAllowYield; + return isAsync ? this.finalize(node, new Node.AsyncFunctionExpression(id, params, body)) : + this.finalize(node, new Node.FunctionExpression(id, params, body, isGenerator)); + }; + // https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive + Parser.prototype.parseDirective = function () { + var token = this.lookahead; + var node = this.createNode(); + var expr = this.parseExpression(); + var directive = (expr.type === syntax_1.Syntax.Literal) ? this.getTokenRaw(token).slice(1, -1) : null; + this.consumeSemicolon(); + return this.finalize(node, directive ? new Node.Directive(expr, directive) : new Node.ExpressionStatement(expr)); + }; + Parser.prototype.parseDirectivePrologues = function () { + var firstRestricted = null; + var body = []; + while (true) { + var token = this.lookahead; + if (token.type !== 8 /* StringLiteral */) { + break; + } + var statement = this.parseDirective(); + body.push(statement); + var directive = statement.directive; + if (typeof directive !== 'string') { + break; + } + if (directive === 'use strict') { + this.context.strict = true; + if (firstRestricted) { + this.tolerateUnexpectedToken(firstRestricted, messages_1.Messages.StrictOctalLiteral); + } + if (!this.context.allowStrictDirective) { + this.tolerateUnexpectedToken(token, messages_1.Messages.IllegalLanguageModeDirective); + } + } + else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + return body; + }; + // https://tc39.github.io/ecma262/#sec-method-definitions + Parser.prototype.qualifiedPropertyName = function (token) { + switch (token.type) { + case 3 /* Identifier */: + case 8 /* StringLiteral */: + case 1 /* BooleanLiteral */: + case 5 /* NullLiteral */: + case 6 /* NumericLiteral */: + case 4 /* Keyword */: + return true; + case 7 /* Punctuator */: + return token.value === '['; + default: + break; + } + return false; + }; + Parser.prototype.parseGetterMethod = function () { + var node = this.createNode(); + var isGenerator = false; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = !isGenerator; + var formalParameters = this.parseFormalParameters(); + if (formalParameters.params.length > 0) { + this.tolerateError(messages_1.Messages.BadGetterArity); + } + var method = this.parsePropertyMethod(formalParameters); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator)); + }; + Parser.prototype.parseSetterMethod = function () { + var node = this.createNode(); + var isGenerator = false; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = !isGenerator; + var formalParameters = this.parseFormalParameters(); + if (formalParameters.params.length !== 1) { + this.tolerateError(messages_1.Messages.BadSetterArity); + } + else if (formalParameters.params[0] instanceof Node.RestElement) { + this.tolerateError(messages_1.Messages.BadSetterRestParameter); + } + var method = this.parsePropertyMethod(formalParameters); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator)); + }; + Parser.prototype.parseGeneratorMethod = function () { + var node = this.createNode(); + var isGenerator = true; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = true; + var params = this.parseFormalParameters(); + this.context.allowYield = false; + var method = this.parsePropertyMethod(params); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); + }; + // https://tc39.github.io/ecma262/#sec-generator-function-definitions + Parser.prototype.isStartOfExpression = function () { + var start = true; + var value = this.lookahead.value; + switch (this.lookahead.type) { + case 7 /* Punctuator */: + start = (value === '[') || (value === '(') || (value === '{') || + (value === '+') || (value === '-') || + (value === '!') || (value === '~') || + (value === '++') || (value === '--') || + (value === '/') || (value === '/='); // regular expression literal + break; + case 4 /* Keyword */: + start = (value === 'class') || (value === 'delete') || + (value === 'function') || (value === 'let') || (value === 'new') || + (value === 'super') || (value === 'this') || (value === 'typeof') || + (value === 'void') || (value === 'yield'); + break; + default: + break; + } + return start; + }; + Parser.prototype.parseYieldExpression = function () { + var node = this.createNode(); + this.expectKeyword('yield'); + var argument = null; + var delegate = false; + if (!this.hasLineTerminator) { + var previousAllowYield = this.context.allowYield; + this.context.allowYield = false; + delegate = this.match('*'); + if (delegate) { + this.nextToken(); + argument = this.parseAssignmentExpression(); + } + else if (this.isStartOfExpression()) { + argument = this.parseAssignmentExpression(); + } + this.context.allowYield = previousAllowYield; + } + return this.finalize(node, new Node.YieldExpression(argument, delegate)); + }; + // https://tc39.github.io/ecma262/#sec-class-definitions + Parser.prototype.parseClassElement = function (hasConstructor) { + var token = this.lookahead; + var node = this.createNode(); + var kind = ''; + var key = null; + var value = null; + var computed = false; + var method = false; + var isStatic = false; + var isAsync = false; + if (this.match('*')) { + this.nextToken(); + } + else { + computed = this.match('['); + key = this.parseObjectPropertyKey(); + var id = key; + if (id.name === 'static' && (this.qualifiedPropertyName(this.lookahead) || this.match('*'))) { + token = this.lookahead; + isStatic = true; + computed = this.match('['); + if (this.match('*')) { + this.nextToken(); + } + else { + key = this.parseObjectPropertyKey(); + } + } + if ((token.type === 3 /* Identifier */) && !this.hasLineTerminator && (token.value === 'async')) { + var punctuator = this.lookahead.value; + if (punctuator !== ':' && punctuator !== '(' && punctuator !== '*') { + isAsync = true; + token = this.lookahead; + key = this.parseObjectPropertyKey(); + if (token.type === 3 /* Identifier */ && token.value === 'constructor') { + this.tolerateUnexpectedToken(token, messages_1.Messages.ConstructorIsAsync); + } + } + } + } + var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); + if (token.type === 3 /* Identifier */) { + if (token.value === 'get' && lookaheadPropertyKey) { + kind = 'get'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + this.context.allowYield = false; + value = this.parseGetterMethod(); + } + else if (token.value === 'set' && lookaheadPropertyKey) { + kind = 'set'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseSetterMethod(); + } + } + else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) { + kind = 'init'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseGeneratorMethod(); + method = true; + } + if (!kind && key && this.match('(')) { + kind = 'init'; + value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction(); + method = true; + } + if (!kind) { + this.throwUnexpectedToken(this.lookahead); + } + if (kind === 'init') { + kind = 'method'; + } + if (!computed) { + if (isStatic && this.isPropertyKey(key, 'prototype')) { + this.throwUnexpectedToken(token, messages_1.Messages.StaticPrototype); + } + if (!isStatic && this.isPropertyKey(key, 'constructor')) { + if (kind !== 'method' || !method || (value && value.generator)) { + this.throwUnexpectedToken(token, messages_1.Messages.ConstructorSpecialMethod); + } + if (hasConstructor.value) { + this.throwUnexpectedToken(token, messages_1.Messages.DuplicateConstructor); + } + else { + hasConstructor.value = true; + } + kind = 'constructor'; + } + } + return this.finalize(node, new Node.MethodDefinition(key, computed, value, kind, isStatic)); + }; + Parser.prototype.parseClassElementList = function () { + var body = []; + var hasConstructor = { value: false }; + this.expect('{'); + while (!this.match('}')) { + if (this.match(';')) { + this.nextToken(); + } + else { + body.push(this.parseClassElement(hasConstructor)); + } + } + this.expect('}'); + return body; + }; + Parser.prototype.parseClassBody = function () { + var node = this.createNode(); + var elementList = this.parseClassElementList(); + return this.finalize(node, new Node.ClassBody(elementList)); + }; + Parser.prototype.parseClassDeclaration = function (identifierIsOptional) { + var node = this.createNode(); + var previousStrict = this.context.strict; + this.context.strict = true; + this.expectKeyword('class'); + var id = (identifierIsOptional && (this.lookahead.type !== 3 /* Identifier */)) ? null : this.parseVariableIdentifier(); + var superClass = null; + if (this.matchKeyword('extends')) { + this.nextToken(); + superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); + } + var classBody = this.parseClassBody(); + this.context.strict = previousStrict; + return this.finalize(node, new Node.ClassDeclaration(id, superClass, classBody)); + }; + Parser.prototype.parseClassExpression = function () { + var node = this.createNode(); + var previousStrict = this.context.strict; + this.context.strict = true; + this.expectKeyword('class'); + var id = (this.lookahead.type === 3 /* Identifier */) ? this.parseVariableIdentifier() : null; + var superClass = null; + if (this.matchKeyword('extends')) { + this.nextToken(); + superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); + } + var classBody = this.parseClassBody(); + this.context.strict = previousStrict; + return this.finalize(node, new Node.ClassExpression(id, superClass, classBody)); + }; + // https://tc39.github.io/ecma262/#sec-scripts + // https://tc39.github.io/ecma262/#sec-modules + Parser.prototype.parseModule = function () { + this.context.strict = true; + this.context.isModule = true; + this.scanner.isModule = true; + var node = this.createNode(); + var body = this.parseDirectivePrologues(); + while (this.lookahead.type !== 2 /* EOF */) { + body.push(this.parseStatementListItem()); + } + return this.finalize(node, new Node.Module(body)); + }; + Parser.prototype.parseScript = function () { + var node = this.createNode(); + var body = this.parseDirectivePrologues(); + while (this.lookahead.type !== 2 /* EOF */) { + body.push(this.parseStatementListItem()); + } + return this.finalize(node, new Node.Script(body)); + }; + // https://tc39.github.io/ecma262/#sec-imports + Parser.prototype.parseModuleSpecifier = function () { + var node = this.createNode(); + if (this.lookahead.type !== 8 /* StringLiteral */) { + this.throwError(messages_1.Messages.InvalidModuleSpecifier); + } + var token = this.nextToken(); + var raw = this.getTokenRaw(token); + return this.finalize(node, new Node.Literal(token.value, raw)); + }; + // import {} ...; + Parser.prototype.parseImportSpecifier = function () { + var node = this.createNode(); + var imported; + var local; + if (this.lookahead.type === 3 /* Identifier */) { + imported = this.parseVariableIdentifier(); + local = imported; + if (this.matchContextualKeyword('as')) { + this.nextToken(); + local = this.parseVariableIdentifier(); + } + } + else { + imported = this.parseIdentifierName(); + local = imported; + if (this.matchContextualKeyword('as')) { + this.nextToken(); + local = this.parseVariableIdentifier(); + } + else { + this.throwUnexpectedToken(this.nextToken()); + } + } + return this.finalize(node, new Node.ImportSpecifier(local, imported)); + }; + // {foo, bar as bas} + Parser.prototype.parseNamedImports = function () { + this.expect('{'); + var specifiers = []; + while (!this.match('}')) { + specifiers.push(this.parseImportSpecifier()); + if (!this.match('}')) { + this.expect(','); + } + } + this.expect('}'); + return specifiers; + }; + // import ...; + Parser.prototype.parseImportDefaultSpecifier = function () { + var node = this.createNode(); + var local = this.parseIdentifierName(); + return this.finalize(node, new Node.ImportDefaultSpecifier(local)); + }; + // import <* as foo> ...; + Parser.prototype.parseImportNamespaceSpecifier = function () { + var node = this.createNode(); + this.expect('*'); + if (!this.matchContextualKeyword('as')) { + this.throwError(messages_1.Messages.NoAsAfterImportNamespace); + } + this.nextToken(); + var local = this.parseIdentifierName(); + return this.finalize(node, new Node.ImportNamespaceSpecifier(local)); + }; + Parser.prototype.parseImportDeclaration = function () { + if (this.context.inFunctionBody) { + this.throwError(messages_1.Messages.IllegalImportDeclaration); + } + var node = this.createNode(); + this.expectKeyword('import'); + var src; + var specifiers = []; + if (this.lookahead.type === 8 /* StringLiteral */) { + // import 'foo'; + src = this.parseModuleSpecifier(); + } + else { + if (this.match('{')) { + // import {bar} + specifiers = specifiers.concat(this.parseNamedImports()); + } + else if (this.match('*')) { + // import * as foo + specifiers.push(this.parseImportNamespaceSpecifier()); + } + else if (this.isIdentifierName(this.lookahead) && !this.matchKeyword('default')) { + // import foo + specifiers.push(this.parseImportDefaultSpecifier()); + if (this.match(',')) { + this.nextToken(); + if (this.match('*')) { + // import foo, * as foo + specifiers.push(this.parseImportNamespaceSpecifier()); + } + else if (this.match('{')) { + // import foo, {bar} + specifiers = specifiers.concat(this.parseNamedImports()); + } + else { + this.throwUnexpectedToken(this.lookahead); + } + } + } + else { + this.throwUnexpectedToken(this.nextToken()); + } + if (!this.matchContextualKeyword('from')) { + var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; + this.throwError(message, this.lookahead.value); + } + this.nextToken(); + src = this.parseModuleSpecifier(); + } + this.consumeSemicolon(); + return this.finalize(node, new Node.ImportDeclaration(specifiers, src)); + }; + // https://tc39.github.io/ecma262/#sec-exports + Parser.prototype.parseExportSpecifier = function () { + var node = this.createNode(); + var local = this.parseIdentifierName(); + var exported = local; + if (this.matchContextualKeyword('as')) { + this.nextToken(); + exported = this.parseIdentifierName(); + } + return this.finalize(node, new Node.ExportSpecifier(local, exported)); + }; + Parser.prototype.parseExportDeclaration = function () { + if (this.context.inFunctionBody) { + this.throwError(messages_1.Messages.IllegalExportDeclaration); + } + var node = this.createNode(); + this.expectKeyword('export'); + var exportDeclaration; + if (this.matchKeyword('default')) { + // export default ... + this.nextToken(); + if (this.matchKeyword('function')) { + // export default function foo () {} + // export default function () {} + var declaration = this.parseFunctionDeclaration(true); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + else if (this.matchKeyword('class')) { + // export default class foo {} + var declaration = this.parseClassDeclaration(true); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + else if (this.matchContextualKeyword('async')) { + // export default async function f () {} + // export default async function () {} + // export default async x => x + var declaration = this.matchAsyncFunction() ? this.parseFunctionDeclaration(true) : this.parseAssignmentExpression(); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + else { + if (this.matchContextualKeyword('from')) { + this.throwError(messages_1.Messages.UnexpectedToken, this.lookahead.value); + } + // export default {}; + // export default []; + // export default (1 + 2); + var declaration = this.match('{') ? this.parseObjectInitializer() : + this.match('[') ? this.parseArrayInitializer() : this.parseAssignmentExpression(); + this.consumeSemicolon(); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + } + else if (this.match('*')) { + // export * from 'foo'; + this.nextToken(); + if (!this.matchContextualKeyword('from')) { + var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; + this.throwError(message, this.lookahead.value); + } + this.nextToken(); + var src = this.parseModuleSpecifier(); + this.consumeSemicolon(); + exportDeclaration = this.finalize(node, new Node.ExportAllDeclaration(src)); + } + else if (this.lookahead.type === 4 /* Keyword */) { + // export var f = 1; + var declaration = void 0; + switch (this.lookahead.value) { + case 'let': + case 'const': + declaration = this.parseLexicalDeclaration({ inFor: false }); + break; + case 'var': + case 'class': + case 'function': + declaration = this.parseStatementListItem(); + break; + default: + this.throwUnexpectedToken(this.lookahead); + } + exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null)); + } + else if (this.matchAsyncFunction()) { + var declaration = this.parseFunctionDeclaration(); + exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null)); + } + else { + var specifiers = []; + var source = null; + var isExportFromIdentifier = false; + this.expect('{'); + while (!this.match('}')) { + isExportFromIdentifier = isExportFromIdentifier || this.matchKeyword('default'); + specifiers.push(this.parseExportSpecifier()); + if (!this.match('}')) { + this.expect(','); + } + } + this.expect('}'); + if (this.matchContextualKeyword('from')) { + // export {default} from 'foo'; + // export {foo} from 'foo'; + this.nextToken(); + source = this.parseModuleSpecifier(); + this.consumeSemicolon(); + } + else if (isExportFromIdentifier) { + // export {default}; // missing fromClause + var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; + this.throwError(message, this.lookahead.value); + } + else { + // export {foo}; + this.consumeSemicolon(); + } + exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(null, specifiers, source)); + } + return exportDeclaration; + }; + return Parser; + }()); + exports.Parser = Parser; + + +/***/ }, +/* 9 */ +/***/ function(module, exports) { + + "use strict"; + // Ensure the condition is true, otherwise throw an error. + // This is only to have a better contract semantic, i.e. another safety net + // to catch a logic error. The condition shall be fulfilled in normal case. + // Do NOT use this to enforce a certain condition on any user input. + Object.defineProperty(exports, "__esModule", { value: true }); + function assert(condition, message) { + /* istanbul ignore if */ + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + exports.assert = assert; + + +/***/ }, +/* 10 */ +/***/ function(module, exports) { + + "use strict"; + /* tslint:disable:max-classes-per-file */ + Object.defineProperty(exports, "__esModule", { value: true }); + var ErrorHandler = (function () { + function ErrorHandler() { + this.errors = []; + this.tolerant = false; + } + ErrorHandler.prototype.recordError = function (error) { + this.errors.push(error); + }; + ErrorHandler.prototype.tolerate = function (error) { + if (this.tolerant) { + this.recordError(error); + } + else { + throw error; + } + }; + ErrorHandler.prototype.constructError = function (msg, column) { + var error = new Error(msg); + try { + throw error; + } + catch (base) { + /* istanbul ignore else */ + if (Object.create && Object.defineProperty) { + error = Object.create(base); + Object.defineProperty(error, 'column', { value: column }); + } + } + /* istanbul ignore next */ + return error; + }; + ErrorHandler.prototype.createError = function (index, line, col, description) { + var msg = 'Line ' + line + ': ' + description; + var error = this.constructError(msg, col); + error.index = index; + error.lineNumber = line; + error.description = description; + return error; + }; + ErrorHandler.prototype.throwError = function (index, line, col, description) { + throw this.createError(index, line, col, description); + }; + ErrorHandler.prototype.tolerateError = function (index, line, col, description) { + var error = this.createError(index, line, col, description); + if (this.tolerant) { + this.recordError(error); + } + else { + throw error; + } + }; + return ErrorHandler; + }()); + exports.ErrorHandler = ErrorHandler; + + +/***/ }, +/* 11 */ +/***/ function(module, exports) { + + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + // Error messages should be identical to V8. + exports.Messages = { + BadGetterArity: 'Getter must not have any formal parameters', + BadSetterArity: 'Setter must have exactly one formal parameter', + BadSetterRestParameter: 'Setter function argument must not be a rest parameter', + ConstructorIsAsync: 'Class constructor may not be an async method', + ConstructorSpecialMethod: 'Class constructor may not be an accessor', + DeclarationMissingInitializer: 'Missing initializer in %0 declaration', + DefaultRestParameter: 'Unexpected token =', + DuplicateBinding: 'Duplicate binding %0', + DuplicateConstructor: 'A class may only have one constructor', + DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals', + ForInOfLoopInitializer: '%0 loop variable declaration may not have an initializer', + GeneratorInLegacyContext: 'Generator declarations are not allowed in legacy contexts', + IllegalBreak: 'Illegal break statement', + IllegalContinue: 'Illegal continue statement', + IllegalExportDeclaration: 'Unexpected token', + IllegalImportDeclaration: 'Unexpected token', + IllegalLanguageModeDirective: 'Illegal \'use strict\' directive in function with non-simple parameter list', + IllegalReturn: 'Illegal return statement', + InvalidEscapedReservedWord: 'Keyword must not contain escaped characters', + InvalidHexEscapeSequence: 'Invalid hexadecimal escape sequence', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + InvalidLHSInForLoop: 'Invalid left-hand side in for-loop', + InvalidModuleSpecifier: 'Unexpected token', + InvalidRegExp: 'Invalid regular expression', + LetInLexicalBinding: 'let is disallowed as a lexically bound name', + MissingFromClause: 'Unexpected token', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NewlineAfterThrow: 'Illegal newline after throw', + NoAsAfterImportNamespace: 'Unexpected token', + NoCatchOrFinally: 'Missing catch or finally after try', + ParameterAfterRestParameter: 'Rest parameter must be last formal parameter', + Redeclaration: '%0 \'%1\' has already been declared', + StaticPrototype: 'Classes may not have static property named prototype', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictFunction: 'In strict mode code, functions can only be declared at top level or inside a block', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + TemplateOctalLiteral: 'Octal literals are not allowed in template strings.', + UnexpectedEOS: 'Unexpected end of input', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedNumber: 'Unexpected number', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedString: 'Unexpected string', + UnexpectedTemplate: 'Unexpected quasi %0', + UnexpectedToken: 'Unexpected token %0', + UnexpectedTokenIllegal: 'Unexpected token ILLEGAL', + UnknownLabel: 'Undefined label \'%0\'', + UnterminatedRegExp: 'Invalid regular expression: missing /' + }; + + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + var assert_1 = __webpack_require__(9); + var character_1 = __webpack_require__(4); + var messages_1 = __webpack_require__(11); + function hexValue(ch) { + return '0123456789abcdef'.indexOf(ch.toLowerCase()); + } + function octalValue(ch) { + return '01234567'.indexOf(ch); + } + var Scanner = (function () { + function Scanner(code, handler) { + this.source = code; + this.errorHandler = handler; + this.trackComment = false; + this.isModule = false; + this.length = code.length; + this.index = 0; + this.lineNumber = (code.length > 0) ? 1 : 0; + this.lineStart = 0; + this.curlyStack = []; + } + Scanner.prototype.saveState = function () { + return { + index: this.index, + lineNumber: this.lineNumber, + lineStart: this.lineStart + }; + }; + Scanner.prototype.restoreState = function (state) { + this.index = state.index; + this.lineNumber = state.lineNumber; + this.lineStart = state.lineStart; + }; + Scanner.prototype.eof = function () { + return this.index >= this.length; + }; + Scanner.prototype.throwUnexpectedToken = function (message) { + if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; } + return this.errorHandler.throwError(this.index, this.lineNumber, this.index - this.lineStart + 1, message); + }; + Scanner.prototype.tolerateUnexpectedToken = function (message) { + if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; } + this.errorHandler.tolerateError(this.index, this.lineNumber, this.index - this.lineStart + 1, message); + }; + // https://tc39.github.io/ecma262/#sec-comments + Scanner.prototype.skipSingleLineComment = function (offset) { + var comments = []; + var start, loc; + if (this.trackComment) { + comments = []; + start = this.index - offset; + loc = { + start: { + line: this.lineNumber, + column: this.index - this.lineStart - offset + }, + end: {} + }; + } + while (!this.eof()) { + var ch = this.source.charCodeAt(this.index); + ++this.index; + if (character_1.Character.isLineTerminator(ch)) { + if (this.trackComment) { + loc.end = { + line: this.lineNumber, + column: this.index - this.lineStart - 1 + }; + var entry = { + multiLine: false, + slice: [start + offset, this.index - 1], + range: [start, this.index - 1], + loc: loc + }; + comments.push(entry); + } + if (ch === 13 && this.source.charCodeAt(this.index) === 10) { + ++this.index; + } + ++this.lineNumber; + this.lineStart = this.index; + return comments; + } + } + if (this.trackComment) { + loc.end = { + line: this.lineNumber, + column: this.index - this.lineStart + }; + var entry = { + multiLine: false, + slice: [start + offset, this.index], + range: [start, this.index], + loc: loc + }; + comments.push(entry); + } + return comments; + }; + Scanner.prototype.skipMultiLineComment = function () { + var comments = []; + var start, loc; + if (this.trackComment) { + comments = []; + start = this.index - 2; + loc = { + start: { + line: this.lineNumber, + column: this.index - this.lineStart - 2 + }, + end: {} + }; + } + while (!this.eof()) { + var ch = this.source.charCodeAt(this.index); + if (character_1.Character.isLineTerminator(ch)) { + if (ch === 0x0D && this.source.charCodeAt(this.index + 1) === 0x0A) { + ++this.index; + } + ++this.lineNumber; + ++this.index; + this.lineStart = this.index; + } + else if (ch === 0x2A) { + // Block comment ends with '*/'. + if (this.source.charCodeAt(this.index + 1) === 0x2F) { + this.index += 2; + if (this.trackComment) { + loc.end = { + line: this.lineNumber, + column: this.index - this.lineStart + }; + var entry = { + multiLine: true, + slice: [start + 2, this.index - 2], + range: [start, this.index], + loc: loc + }; + comments.push(entry); + } + return comments; + } + ++this.index; + } + else { + ++this.index; + } + } + // Ran off the end of the file - the whole thing is a comment + if (this.trackComment) { + loc.end = { + line: this.lineNumber, + column: this.index - this.lineStart + }; + var entry = { + multiLine: true, + slice: [start + 2, this.index], + range: [start, this.index], + loc: loc + }; + comments.push(entry); + } + this.tolerateUnexpectedToken(); + return comments; + }; + Scanner.prototype.scanComments = function () { + var comments; + if (this.trackComment) { + comments = []; + } + var start = (this.index === 0); + while (!this.eof()) { + var ch = this.source.charCodeAt(this.index); + if (character_1.Character.isWhiteSpace(ch)) { + ++this.index; + } + else if (character_1.Character.isLineTerminator(ch)) { + ++this.index; + if (ch === 0x0D && this.source.charCodeAt(this.index) === 0x0A) { + ++this.index; + } + ++this.lineNumber; + this.lineStart = this.index; + start = true; + } + else if (ch === 0x2F) { + ch = this.source.charCodeAt(this.index + 1); + if (ch === 0x2F) { + this.index += 2; + var comment = this.skipSingleLineComment(2); + if (this.trackComment) { + comments = comments.concat(comment); + } + start = true; + } + else if (ch === 0x2A) { + this.index += 2; + var comment = this.skipMultiLineComment(); + if (this.trackComment) { + comments = comments.concat(comment); + } + } + else { + break; + } + } + else if (start && ch === 0x2D) { + // U+003E is '>' + if ((this.source.charCodeAt(this.index + 1) === 0x2D) && (this.source.charCodeAt(this.index + 2) === 0x3E)) { + // '-->' is a single-line comment + this.index += 3; + var comment = this.skipSingleLineComment(3); + if (this.trackComment) { + comments = comments.concat(comment); + } + } + else { + break; + } + } + else if (ch === 0x3C && !this.isModule) { + if (this.source.slice(this.index + 1, this.index + 4) === '!--') { + this.index += 4; // `' is a single-line comment - this.index += 3; - var comment = this.skipSingleLineComment(3); - if (this.trackComment) { - comments = comments.concat(comment); - } - } - else { - break; - } - } - else if (ch === 0x3C && !this.isModule) { - if (this.source.slice(this.index + 1, this.index + 4) === '!--') { - this.index += 4; // ` - - + + + diff --git a/js/appinfo.js b/js/appinfo.js index 776142bcd..6a91dce2d 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -1,7 +1,23 @@ +// Converts a string into most efficient way to send to Espruino (either json, base64, or compressed base64) function toJS(txt) { var json = JSON.stringify(txt); var b64 = "atob("+JSON.stringify(btoa(json))+")"; - return b64.length < json.length ? b64 : json; + var js = b64.length < json.length ? b64 : json; + + if (heatshrink) { + var ua = new Uint8Array(txt.length); + for (var i=0;i { // Load all files Promise.all(app.storage.map(storageFile => { - if (storageFile.content) + if (storageFile.content!==undefined) return Promise.resolve(storageFile); else if (storageFile.url) return options.fileGetter(`apps/${app.id}/${storageFile.url}`).then(content => { @@ -52,14 +68,14 @@ var AppInfo = { let js = storageFile.content.trim(); if (js.endsWith(";")) js = js.slice(0,-1); - storageFile.cmd = `\x10require('Storage').write(${toJS(storageFile.name)},${js});`; + storageFile.cmd = `\x10require('Storage').write(${JSON.stringify(storageFile.name)},${js});`; } else { let code = storageFile.content; // write code in chunks, in case it is too big to fit in RAM (fix #157) - var CHUNKSIZE = 4096; - storageFile.cmd = `\x10require('Storage').write(${toJS(storageFile.name)},${toJS(code.substr(0,CHUNKSIZE))},0,${code.length});`; + var CHUNKSIZE = 8192; + storageFile.cmd = `\x10require('Storage').write(${JSON.stringify(storageFile.name)},${toJS(code.substr(0,CHUNKSIZE))},0,${code.length});`; for (var i=CHUNKSIZE;i { // expects an apps.json structure (i.e. with `s }).then(fileContents => { return new Promise((resolve,reject) => { console.log("uploadApp",fileContents.map(f=>f.name).join(", ")); - var maxBytes = fileContents.reduce((b,f)=>b+f.content.length, 0)||1; + var maxBytes = fileContents.reduce((b,f)=>b+f.cmd.length, 0)||1; var currentBytes = 0; var appInfoFileName = app.id+".info"; @@ -37,19 +37,25 @@ uploadApp : (app,skipReset) => { // expects an apps.json structure (i.e. with `s } var f = fileContents.shift(); console.log(`Upload ${f.name} => ${JSON.stringify(f.content)}`); - Progress.show({ - min:currentBytes / maxBytes, - max:(currentBytes+f.content.length) / maxBytes}); - currentBytes += f.content.length; // Chould check CRC here if needed instead of returning 'OK'... // E.CRC32(require("Storage").read(${JSON.stringify(app.name)})) - Puck.write(`${f.cmd};Bluetooth.println("OK")\n`,(result) => { - if (!result || result.trim()!="OK") { - Progress.hide({sticky:true}); - return reject("Unexpected response "+(result||"")); - } - doUploadFiles(); - }, true); // wait for a newline + var cmds = f.cmd.split("\n"); + function uploadCmd() { + if (!cmds.length) return doUploadFiles(); + var cmd = cmds.shift(); + Progress.show({ + min:currentBytes / maxBytes, + max:(currentBytes+cmd.length) / maxBytes}); + currentBytes += cmd.length; + Puck.write(`${cmd};Bluetooth.println("OK")\n`,(result) => { + if (!result || result.trim()!="OK") { + Progress.hide({sticky:true}); + return reject("Unexpected response "+(result||"")); + } + uploadCmd(); + }, true); // wait for a newline + } + uploadCmd(); } // Start the upload function doUpload() { diff --git a/lib/heatshrink.js b/lib/heatshrink.js new file mode 100644 index 000000000..8e4e9a8df --- /dev/null +++ b/lib/heatshrink.js @@ -0,0 +1,100 @@ +/* + Compiled to JS with Emscripten by Gordon Williams + heatshrink_config.h matches that of Espruino. + Source for conversion at http://github.com/gfwilliams/heatshrink-js +*/ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof module === 'object' && module.exports) { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.heatshrink = factory(); + } +}(typeof self !== 'undefined' ? self : this, function () { +/* +Copyright (c) 2013-2015, Scott Vokes +All rights reserved. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +var Module=typeof Module!=="undefined"?Module:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_HAS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_HAS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_NODE=ENVIRONMENT_HAS_NODE&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_NODE){scriptDirectory=__dirname+"/";var nodeFS;var nodePath;read_=function shell_read(filename,binary){var ret;ret=tryParseAsDataURI(filename);if(!ret){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);ret=nodeFS["readFileSync"](filename)}return binary?ret:ret.toString()};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){var data=tryParseAsDataURI(f);if(data){return intArrayToString(data)}return read(f)}}readBinary=function readBinary(f){var data;data=tryParseAsDataURI(f);if(data){return data}if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}read_=function shell_read(url){try{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText}catch(err){var data=tryParseAsDataURI(url);if(data){return intArrayToString(data)}throw err}};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){try{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}catch(err){var data=tryParseAsDataURI(url);if(data){return data}throw err}}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}var data=tryParseAsDataURI(url);if(data){onload(data.buffer);return}onerror()};xhr.onerror=onerror;xhr.send(null)};setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function dynamicAlloc(size){var ret=HEAP32[DYNAMICTOP_PTR>>2];var end=ret+size+15&-16;if(end>_emscripten_get_heap_size()){abort()}HEAP32[DYNAMICTOP_PTR>>2]=end;return ret}function getNativeTypeSize(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return 4}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0,"getNativeTypeSize invalid bits "+bits+", type "+type);return bits/8}else{return 0}}}}function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}var jsCallStartIndex=1;var functionPointers=new Array(0);var funcWrappers={};function dynCall(sig,ptr,args){if(args&&args.length){return Module["dynCall_"+sig].apply(null,[ptr].concat(args))}else{return Module["dynCall_"+sig].call(null,ptr)}}var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var getTempRet0=function(){return tempRet0};var GLOBAL_BASE=8;var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];function setValue(ptr,value,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i=endIdx))++endPtr;if(endPtr-idx>16&&u8Array.subarray&&UTF8Decoder){return UTF8Decoder.decode(u8Array.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var STACK_BASE=2928,DYNAMIC_BASE=5245808,DYNAMICTOP_PTR=2896;var INITIAL_TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;if(Module["buffer"]){buffer=Module["buffer"]}else{buffer=new ArrayBuffer(INITIAL_TOTAL_MEMORY)}INITIAL_TOTAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var Math_abs=Math.abs;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_min=Math.min;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};var memoryInitializer=null;var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}var tempDouble;var tempI64;memoryInitializer="data:application/octet-stream;base64,AAAAAAAAAAARAAoAERERAAAAAAUAAAAAAAAJAAAAAAsAAAAAAAAAABEADwoREREDCgcAARMJCwsAAAkGCwAACwAGEQAAABEREQAAAAAAAAAAAAAAAAAAAAALAAAAAAAAAAARAAoKERERAAoAAAIACQsAAAAJAAsAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAADAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAA0AAAAEDQAAAAAJDgAAAAAADgAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAPAAAAAA8AAAAACRAAAAAAABAAABAAABIAAAASEhIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAABISEgAAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAAoAAAAACgAAAAAJCwAAAAAACwAACwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAAAAwAAAAACQwAAAAAAAwAAAwAADAxMjM0NTY3ODlBQkNERUYFAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAEgEAAAABAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAK/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApeXiBDT01QUkVTU0lORyAlZCBieXRlcwoAQXNzZXJ0IGF0IGhlYXRzaHJpbmtfd3JhcHBlci5jOiVkCgBeXiBzdW5rICV6ZAoAXl4gcG9sbGVkICV6ZAoAaW46ICV1IGNvbXByZXNzZWQ6ICV1CgAKXl4gREVDT01QUkVTU0lORyAlZCBieXRlcwoALSsgICAwWDB4AChudWxsKQAtMFgrMFggMFgtMHgrMHggMHgAaW5mAElORgBuYW4ATkFOAC4=";var tempDoublePtr=2912;function demangle(func){return func}function demangleAll(text){var regex=/\b__Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}function flush_NO_FILESYSTEM(){var fflush=Module["_fflush"];if(fflush)fflush(0);var buffers=SYSCALLS.buffers;if(buffers[1].length)SYSCALLS.printChar(1,10);if(buffers[2].length)SYSCALLS.printChar(2,10)}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};var SYSCALLS={buffers:[null,[],[]],printChar:function(stream,curr){var buffer=SYSCALLS.buffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}},varargs:0,get:function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(){var ret=UTF8ToString(SYSCALLS.get());return ret},get64:function(){var low=SYSCALLS.get(),high=SYSCALLS.get();return low},getZero:function(){SYSCALLS.get()}};function _fd_write(stream,iov,iovcnt,pnum){try{var num=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___wasi_fd_write(){return _fd_write.apply(null,arguments)}function _emscripten_get_heap_size(){return HEAP8.length}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest)}function ___setErrNo(value){if(Module["___errno_location"])HEAP32[Module["___errno_location"]()>>2]=value;return value}function abortOnCannotGrowMemory(requestedSize){abort("OOM")}function _emscripten_resize_heap(requestedSize){abortOnCannotGrowMemory(requestedSize)}var ASSERTIONS=false;function intArrayToString(array){var ret=[];for(var i=0;i255){if(ASSERTIONS){assert(false,"Character code "+chr+" ("+String.fromCharCode(chr)+") at offset "+i+" not in 0x00-0xFF.")}chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}var decodeBase64=typeof atob==="function"?atob:function(input){var keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");do{enc1=keyStr.indexOf(input.charAt(i++));enc2=keyStr.indexOf(input.charAt(i++));enc3=keyStr.indexOf(input.charAt(i++));enc4=keyStr.indexOf(input.charAt(i++));chr1=enc1<<2|enc2>>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!==64){output=output+String.fromCharCode(chr2)}if(enc4!==64){output=output+String.fromCharCode(chr3)}}while(i>2]=0;n=(f|0)>1;if(n){c[g>>2]=b;ab(888,g)|0}l=(d|0)==0;g=0;h=0;a:while(1){if(h>>>0>=b>>>0){h=26;break}if((X(p,a+h|0,b-h|0,o)|0)<=-1){h=6;break}i=c[o>>2]|0;h=i+h|0;if(n){c[r>>2]=i;ab(949,r)|0}k=(h|0)==(b|0);if(k?(ma(p)|0)!=1:0){h=12;break}b:while(1){if(l)j=Z(p,m,64,o)|0;else j=Z(p,d+g|0,e-g|0,o)|0;if((j|0)<=-1){h=17;break a}i=c[o>>2]|0;g=i+g|0;if(n){c[q>>2]=i;ab(962,q)|0}switch(j|0){case 1:break;case 0:break b;default:{h=21;break a}}}if(k?ma(p)|0:0){h=25;break}}if((h|0)==6){c[s>>2]=21;ab(914,s)|0;g=0}else if((h|0)==12){c[x>>2]=25;ab(914,x)|0;g=0}else if((h|0)==17){c[t>>2]=36;ab(914,t)|0;g=0}else if((h|0)==21){c[u>>2]=40;ab(914,u)|0;g=0}else if((h|0)==25){c[v>>2]=42;ab(914,v)|0;g=0}else if((h|0)==26)if((f|0)>0){c[w>>2]=b;c[w+4>>2]=g;ab(977,w)|0}I=y;return g|0}function V(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;y=I;I=I+448|0;w=y+128|0;v=y+120|0;u=y+112|0;q=y+104|0;t=y+96|0;x=y+88|0;r=y+80|0;s=y+72|0;g=y+64|0;p=y+140|0;o=y+136|0;m=y;na(p);c[o>>2]=0;n=(f|0)>1;if(n){c[g>>2]=b;ab(1e3,g)|0}l=(d|0)==0;g=0;h=0;a:while(1){if(h>>>0>=b>>>0){h=27;break}if((oa(p,a+h|0,b-h|0,o)|0)<=-1){h=6;break}i=c[o>>2]|0;h=i+h|0;if(n){c[r>>2]=i;ab(949,r)|0}k=(h|0)==(b|0);if(k?(za(p)|0)!=1:0){h=12;break}do{if(l)j=pa(p,m,64,o)|0;else j=pa(p,d+g|0,e-g|0,o)|0;if((j|0)<=-1){h=17;break a}i=c[o>>2]|0;g=i+g|0;if(n){c[q>>2]=i;ab(962,q)|0;i=c[o>>2]|0}}while((j|0)==1&(i|0)!=0);if(j|0){h=22;break}if(k?za(p)|0:0){h=26;break}}if((h|0)==6){c[s>>2]=63;ab(914,s)|0;g=0}else if((h|0)==12){c[x>>2]=67;ab(914,x)|0;g=0}else if((h|0)==17){c[t>>2]=78;ab(914,t)|0;g=0}else if((h|0)==22){c[u>>2]=82;ab(914,u)|0;g=0}else if((h|0)==26){c[v>>2]=84;ab(914,v)|0;g=0}else if((h|0)==27)if((f|0)>0){c[w>>2]=b;c[w+4>>2]=g;ab(977,w)|0}I=y;return g|0}function W(c){c=c|0;ob(c+15|0,0,512)|0;b[c>>1]=0;a[c+12>>0]=0;b[c+2>>1]=0;a[c+11>>0]=0;a[c+14>>0]=-128;a[c+13>>0]=0;b[c+4>>1]=0;b[c+8>>1]=0;a[c+10>>0]=0;return}function X(d,e,f,g){d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0;if(!((d|0)==0|(e|0)==0|(g|0)==0))if((Y(d)|0)==0?(h=d+12|0,(a[h>>0]|0)==0):0){j=b[d>>1]|0;i=256-j&65535;k=i>>>0>>0?i:f;mb((j+256&65535)+(d+15)|0,e|0,k|0)|0;c[g>>2]=k;b[d>>1]=k+(j&65535);if(i>>>0>f>>>0)d=0;else{a[h>>0]=1;d=0}}else d=-2;else d=-1;return d|0}function Y(b){b=b|0;return a[b+11>>0]&1|0}function Z(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0;k=I;I=I+16|0;i=k;if(!((b|0)==0|(d|0)==0|(f|0)==0))if(!e)d=-2;else{c[f>>2]=0;c[i>>2]=d;c[i+4>>2]=e;c[i+8>>2]=f;h=b+12|0;g=a[h>>0]|0;a:while(1){switch(g<<24>>24){case 9:case 0:{d=0;j=15;break a}case 8:{j=11;break a}case 1:{d=2;break}case 2:{d=(_(b)|0)&255;break}case 3:{d=($(b,i)|0)&255;break}case 4:{d=(aa(b,i)|0)&255;break}case 5:{d=(ba(b,i)|0)&255;break}case 6:{d=(ca(b,i)|0)&255;break}case 7:{da(b);d=0;break}default:{d=-2;break a}}a[h>>0]=d;if(d<<24>>24==g<<24>>24?(c[f>>2]|0)==(e|0):0){d=1;j=15;break}g=d}if((j|0)==11){a[h>>0]=ea(b,i)|0;d=0}}else d=-1;I=k;return d|0}function _(a){a=a|0;var c=0,d=0,f=0,g=0,h=0,i=0,j=0;j=I;I=I+16|0;h=j;i=a+2|0;c=b[i>>1]|0;g=(Y(a)|0)!=0;d=c&65535;f=e[a>>1]|0;if((f-(g?1:64)|0)<(d|0))c=g?8:7;else{g=f-d|0;b[h>>1]=0;c=la(a,(c+256&65535)+65280&65535,d+256&65535,((g|0)<64?g:64)&65535,h)|0;if(c<<16>>16==-1){b[i>>1]=(b[i>>1]|0)+1<<16>>16;c=0}else{b[a+6>>1]=c;c=b[h>>1]|0}b[a+4>>1]=c;c=3}I=j;return c|0}function $(c,d){c=c|0;d=d|0;do if(fa(d)|0)if(!(b[c+4>>1]|0)){ka(c,d,1);c=4;break}else{ka(c,d,0);b[c+8>>1]=(e[c+6>>1]|0)+65535;a[c+10>>0]=8;c=5;break}else c=3;while(0);return c|0}function aa(a,b){a=a|0;b=b|0;if(!(fa(b)|0))a=4;else{ja(a,b);a=2}return a|0}function ba(c,d){c=c|0;d=d|0;if((fa(d)|0)!=0?(ha(c,d)|0)<<24>>24==0:0){b[c+8>>1]=(e[c+4>>1]|0)+65535;a[c+10>>0]=6;c=6}else c=5;return c|0}function ca(a,c){a=a|0;c=c|0;if((fa(c)|0)!=0?(ha(a,c)|0)<<24>>24==0:0){c=a+4|0;a=a+2|0;b[a>>1]=(e[a>>1]|0)+(e[c>>1]|0);b[c>>1]=0;a=2}else a=6;return a|0}function da(a){a=a|0;ga(a);return}function ea(b,d){b=b|0;d=d|0;var e=0,f=0;if((a[b+14>>0]|0)!=-128)if(!(fa(d)|0))b=8;else{f=a[b+13>>0]|0;e=c[d>>2]|0;d=c[d+8>>2]|0;b=c[d>>2]|0;c[d>>2]=b+1;a[e+b>>0]=f;b=9}else b=9;return b|0}function fa(a){a=a|0;return (c[c[a+8>>2]>>2]|0)>>>0<(c[a+4>>2]|0)>>>0|0}function ga(a){a=a|0;var c=0,d=0,f=0;d=a+2|0;f=256-(b[d>>1]|0)<<16>>16;c=256-(f&65535)|0;nb(a+15|0,a+15+c|0,f+256&65535|0)|0;b[d>>1]=0;b[a>>1]=(e[a>>1]|0)-c;return}function ha(c,f){c=c|0;f=f|0;var g=0,h=0,i=0,j=0;i=c+10|0;g=a[i>>0]|0;if((g&255)<=8)if(!(g<<24>>24))g=0;else{h=b[c+8>>1]&255;j=4}else{h=(e[c+8>>1]|0)>>>((g&255)+-8|0)&255;g=8;j=4}if((j|0)==4){ia(c,g,h,f);a[i>>0]=(d[i>>0]|0)-(g&255)}return g|0}function ia(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0;h=d&255;j=b+14|0;if(d<<24>>24==8?(a[j>>0]|0)==-128:0){j=c[f>>2]|0;i=c[f+8>>2]|0;f=c[i>>2]|0;c[i>>2]=f+1;a[j+f>>0]=e}else g=4;a:do if((g|0)==4){i=e&255;g=b+13|0;b=f+8|0;e=h;while(1){d=e+-1|0;if((e|0)<=0)break a;e=a[j>>0]|0;if(1<>0]=a[g>>0]|e;h=(e&255)>>>1;a[j>>0]=h;if(!(h<<24>>24)){a[j>>0]=-128;k=a[g>>0]|0;e=c[f>>2]|0;l=c[b>>2]|0;h=c[l>>2]|0;c[l>>2]=h+1;a[e+h>>0]=k;a[g>>0]=0}e=d}}while(0);return}function ja(c,d){c=c|0;d=d|0;ia(c,8,a[((b[c+2>>1]|0)+255&65535)+(c+15)>>0]|0,d);return}function ka(a,b,c){a=a|0;b=b|0;c=c|0;ia(a,1,c,b);return}function la(c,d,e,f,g){c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0;n=e&65535;l=c+15+n|0;h=-1;e=0;m=n+65535&65535;while(1){if(m<<16>>16>16)break;i=(m<<16>>16)+(c+15)|0;k=e&65535;if((a[i+k>>0]|0)==(a[l+k>>0]|0)?(a[i>>0]|0)==(a[l>>0]|0):0){k=1;while(1){j=k&65535;if((k&65535)>=(f&65535))break;if((a[i+j>>0]|0)!=(a[l+j>>0]|0))break;k=k+1<<16>>16}if((k&65535)>(e&65535))if(k<<16>>16==f<<16>>16){h=m;e=f;break}else{h=m;e=k}}m=m+-1<<16>>16}if((e&65535)>1){b[g>>1]=e;e=n-(h&65535)&65535}else e=-1;return e|0}function ma(b){b=b|0;var c=0;if(!b)b=-1;else{c=b+11|0;a[c>>0]=a[c>>0]|1;c=b+12|0;b=a[c>>0]|0;if(!(b<<24>>24)){a[c>>0]=1;b=1}b=b<<24>>24!=9&1}return b|0}function na(a){a=a|0;ob(a|0,0,301)|0;return}function oa(a,d,f,g){a=a|0;d=d|0;f=f|0;g=g|0;var h=0,i=0,j=0;if((a|0)==0|(d|0)==0|(g|0)==0)f=-1;else{i=e[a>>1]|0;j=32-i|0;h=j>>>0>>0?j:f;if(!j){f=1;h=0}else{mb(a+13+i|0,d|0,h|0)|0;b[a>>1]=h+i;f=0}c[g>>2]=h}return f|0}function pa(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0;k=I;I=I+16|0;i=k;if((b|0)==0|(d|0)==0|(f|0)==0)d=-1;else{c[f>>2]=0;c[i>>2]=d;c[i+4>>2]=e;c[i+8>>2]=f;h=b+10|0;d=a[h>>0]|0;a:while(1){switch(d<<24>>24){case 0:{g=qa(b)|0;break}case 1:{g=ra(b,i)|0;break}case 2:{g=sa(b)|0;break}case 3:{g=ta(b)|0;break}case 4:{g=ua(b)|0;break}case 5:{g=va(b)|0;break}case 6:{g=wa(b,i)|0;break}default:{d=-2;break a}}l=d;d=g&255;a[h>>0]=d;if(l<<24>>24==d<<24>>24){j=12;break}}if((j|0)==12)d=(c[f>>2]|0)==(e|0)&1}I=k;return d|0}function qa(a){a=a|0;switch((ya(a,1)|0)<<16>>16){case -1:{a=0;break}case 0:{b[a+6>>1]=0;a=3;break}default:a=1}return a|0}function ra(d,e){d=d|0;e=e|0;var f=0,g=0,h=0;if((c[c[e+8>>2]>>2]|0)>>>0<(c[e+4>>2]|0)>>>0?(f=ya(d,8)|0,f<<16>>16!=-1):0){f=f&255;h=d+8|0;g=b[h>>1]|0;b[h>>1]=g+1<<16>>16;a[d+45+(g&255)>>0]=f;xa(e,f);f=0}else f=1;return f|0}function sa(a){a=a|0;var c=0;c=ya(a,0)|0;if(c<<16>>16==-1)c=2;else{b[a+6>>1]=(c&65535)<<8;c=3}return c|0}function ta(a){a=a|0;var c=0,d=0;c=ya(a,8)|0;if(c<<16>>16==-1)c=3;else{d=a+6|0;b[d>>1]=(b[d>>1]|c)+1<<16>>16;b[a+4>>1]=0;c=5}return c|0}function ua(a){a=a|0;var c=0;c=ya(a,-2)|0;if(c<<16>>16==-1)c=4;else{b[a+4>>1]=(c&65535)<<8;c=5}return c|0}function va(a){a=a|0;var c=0;c=ya(a,6)|0;if(c<<16>>16==-1)c=5;else{a=a+4|0;b[a>>1]=(b[a>>1]|c)+1<<16>>16;c=6}return c|0}function wa(d,f){d=d|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;g=(c[f+4>>2]|0)-(c[c[f+8>>2]>>2]|0)|0;if(g){k=d+4|0;j=e[k>>1]|0;j=g>>>0>j>>>0?j:g;h=d+45|0;i=d+8|0;g=e[d+6>>1]|0;d=0;while(1){if(d>>>0>=j>>>0)break;n=a[h+((e[i>>1]|0)-g&255)>>0]|0;xa(f,n);m=b[i>>1]|0;a[h+(m&255)>>0]=n;b[i>>1]=m+1<<16>>16;d=d+1|0}n=(e[k>>1]|0)-j|0;b[k>>1]=n;if(!(n&65535))g=0;else l=6}else l=6;if((l|0)==6)g=6;return g|0}function xa(b,d){b=b|0;d=d|0;var e=0,f=0;e=c[b>>2]|0;f=c[b+8>>2]|0;b=c[f>>2]|0;c[f>>2]=b+1;a[e+b>>0]=d;return}function ya(c,e){c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;m=e&255;a:do if((e&255)>15)e=-1;else{e=b[c>>1]|0;j=c+12|0;if(e<<16>>16==0?(1<(d[j>>0]|0|0):0){e=-1;break}k=c+11|0;l=c+2|0;g=e;e=0;i=0;while(1){if(i>>>0>=m>>>0)break a;f=a[j>>0]|0;if(!(f<<24>>24)){if(!(g<<16>>16)){e=-1;break a}h=b[l>>1]|0;f=h+1<<16>>16;b[l>>1]=f;h=a[(h&65535)+(c+13)>>0]|0;a[k>>0]=h;if(f<<16>>16==g<<16>>16){b[l>>1]=0;b[c>>1]=0;g=0}a[j>>0]=-128;f=-128}else h=a[k>>0]|0;a[j>>0]=(f&255)>>>1;e=((e&65535)<<1|(f&h)<<24>>24!=0)&65535;i=i+1|0}}while(0);return e|0}function za(c){c=c|0;a:do if(!c)c=-1;else switch(a[c+10>>0]|0){case 0:{c=(b[c>>1]|0)!=0&1;break a}case 4:case 5:case 2:case 3:{c=(b[c>>1]|0)!=0&1;break a}case 1:{c=(b[c>>1]|0)!=0&1;break a}default:{c=1;break a}}while(0);return c|0}function Aa(a){a=a|0;return 0}function Ba(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;l=I;I=I+32|0;g=l;i=l+16|0;j=a+28|0;f=c[j>>2]|0;c[g>>2]=f;k=a+20|0;f=(c[k>>2]|0)-f|0;c[g+4>>2]=f;c[g+8>>2]=b;c[g+12>>2]=d;e=a+60|0;h=2;f=f+d|0;while(1){if(!((x(c[e>>2]|0,g|0,h|0,i|0)|0)<<16>>16))b=c[i>>2]|0;else{c[i>>2]=-1;b=-1}if((f|0)==(b|0)){b=6;break}if((b|0)<0){b=8;break}p=c[g+4>>2]|0;m=b>>>0>p>>>0;n=m?g+8|0:g;p=b-(m?p:0)|0;c[n>>2]=(c[n>>2]|0)+p;o=n+4|0;c[o>>2]=(c[o>>2]|0)-p;g=n;h=h+(m<<31>>31)|0;f=f-b|0}if((b|0)==6){p=c[a+44>>2]|0;c[a+16>>2]=p+(c[a+48>>2]|0);c[j>>2]=p;c[k>>2]=p}else if((b|0)==8){c[a+16>>2]=0;c[j>>2]=0;c[k>>2]=0;c[a>>2]=c[a>>2]|32;if((h|0)==2)d=0;else d=d-(c[g+4>>2]|0)|0}I=l;return d|0}function Ca(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;u(0);return 0}function Da(){return 2128}function Ea(a,b,c){a=a|0;b=b|0;c=c|0;return Ha(a,b,c,1,1)|0}function Fa(b,e,f,g,h,i){b=b|0;e=+e;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,s=0.0,t=0,u=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;H=I;I=I+560|0;m=H+32|0;u=H+536|0;G=H;F=G;l=H+540|0;c[u>>2]=0;E=l+12|0;_a(e)|0;j=v()|0;if((j|0)<0){e=-e;_a(e)|0;j=v()|0;D=1;B=1045}else{D=(h&2049|0)!=0&1;B=(h&2048|0)==0?((h&1|0)==0?1046:1051):1048}do if(0==0&(j&2146435072|0)==2146435072){G=(i&32|0)!=0;j=D+3|0;Ta(b,32,f,j,h&-65537);La(b,B,D);La(b,e!=e|0.0!=0.0?(G?1072:1076):G?1064:1068,3);Ta(b,32,f,j,h^8192)}else{s=+$a(e,u)*2.0;j=s!=0.0;if(j)c[u>>2]=(c[u>>2]|0)+-1;x=i|32;if((x|0)==97){o=i&32;q=(o|0)==0?B:B+9|0;p=D|2;j=12-g|0;do if(!(g>>>0>11|(j|0)==0)){e=8.0;do{j=j+-1|0;e=e*16.0}while((j|0)!=0);if((a[q>>0]|0)==45){e=-(e+(-s-e));break}else{e=s+e-e;break}}else e=s;while(0);k=c[u>>2]|0;j=(k|0)<0?0-k|0:k;j=Ra(j,((j|0)<0)<<31>>31,E)|0;if((j|0)==(E|0)){j=l+11|0;a[j>>0]=48}a[j+-1>>0]=(k>>31&2)+43;n=j+-2|0;a[n>>0]=i+15;k=(g|0)<1;l=(h&8|0)==0;j=G;while(1){D=~~e;m=j+1|0;a[j>>0]=o|d[480+D>>0];e=(e-+(D|0))*16.0;if((m-F|0)==1?!(l&(k&e==0.0)):0){a[m>>0]=46;m=j+2|0}if(!(e!=0.0))break;else j=m}if((g|0)!=0?(-2-F+m|0)<(g|0):0){k=E;l=n;j=g+2+k-l|0}else{k=E;l=n;j=k-F-l+m|0}E=j+p|0;Ta(b,32,f,E,h);La(b,q,p);Ta(b,48,f,E,h^65536);F=m-F|0;La(b,G,F);G=k-l|0;Ta(b,48,j-(F+G)|0,0,0);La(b,n,G);Ta(b,32,f,E,h^8192);j=E;break}k=(g|0)<0?6:g;if(j){l=(c[u>>2]|0)+-28|0;c[u>>2]=l;e=s*268435456.0}else{l=c[u>>2]|0;e=s}C=(l|0)<0?m:m+288|0;m=C;do{z=~~e>>>0;c[m>>2]=z;m=m+4|0;e=(e-+(z>>>0))*1.0e9}while(e!=0.0);z=C;if((l|0)>0){j=C;do{o=(l|0)<29?l:29;l=m+-4|0;if(l>>>0>=j>>>0){n=0;do{t=lb(c[l>>2]|0,0,o|0)|0;t=fb(t|0,v()|0,n|0,0)|0;w=v()|0;n=jb(t|0,w|0,1e9,0)|0;y=eb(n|0,v()|0,1e9,0)|0;y=gb(t|0,w|0,y|0,v()|0)|0;v()|0;c[l>>2]=y;l=l+-4|0}while(l>>>0>=j>>>0);if(n){j=j+-4|0;c[j>>2]=n}}a:do if(m>>>0>j>>>0)while(1){l=m+-4|0;if(c[l>>2]|0)break a;if(l>>>0>j>>>0)m=l;else{m=l;break}}while(0);l=(c[u>>2]|0)-o|0;c[u>>2]=l}while((l|0)>0)}else j=C;if((l|0)<0){g=((k+25|0)/9|0)+1|0;t=(x|0)==102;do{q=0-l|0;q=(q|0)<9?q:9;if(j>>>0>>0){o=(1<>>q;p=0;l=j;do{y=c[l>>2]|0;c[l>>2]=(y>>>q)+p;p=r(y&o,n)|0;l=l+4|0}while(l>>>0>>0);j=(c[j>>2]|0)==0?j+4|0:j;if(p){c[m>>2]=p;m=m+4|0}}else j=(c[j>>2]|0)==0?j+4|0:j;l=t?C:j;m=(m-l>>2|0)>(g|0)?l+(g<<2)|0:m;l=(c[u>>2]|0)+q|0;c[u>>2]=l}while((l|0)<0);t=m}else t=m;if(j>>>0>>0){l=(z-j>>2)*9|0;n=c[j>>2]|0;if(n>>>0>=10){m=10;do{m=m*10|0;l=l+1|0}while(n>>>0>=m>>>0)}}else l=0;u=(x|0)==103;w=(k|0)!=0;m=k-((x|0)==102?0:l)+((w&u)<<31>>31)|0;if((m|0)<(((t-z>>2)*9|0)+-9|0)){y=m+9216|0;m=(y|0)/9|0;g=C+4+(m+-1024<<2)|0;m=y-(m*9|0)|0;if((m|0)<8){n=10;while(1){n=n*10|0;if((m|0)<7)m=m+1|0;else break}}else n=10;p=c[g>>2]|0;m=(p>>>0)/(n>>>0)|0;q=p-(r(m,n)|0)|0;o=(g+4|0)==(t|0);if(!(o&(q|0)==0)){s=(m&1|0)==0?9007199254740992.0:9007199254740994.0;y=n>>>1;e=q>>>0>>0?.5:o&(q|0)==(y|0)?1.0:1.5;if(D){y=(a[B>>0]|0)==45;s=y?-s:s;e=y?-e:e}m=p-q|0;c[g>>2]=m;if(s+e!=s){y=m+n|0;c[g>>2]=y;if(y>>>0>999999999){l=g;while(1){m=l+-4|0;c[l>>2]=0;if(m>>>0>>0){j=j+-4|0;c[j>>2]=0}y=(c[m>>2]|0)+1|0;c[m>>2]=y;if(y>>>0>999999999)l=m;else break}}else m=g;l=(z-j>>2)*9|0;o=c[j>>2]|0;if(o>>>0>=10){n=10;do{n=n*10|0;l=l+1|0}while(o>>>0>=n>>>0)}}else m=g}else m=g;x=m+4|0;y=j;j=t>>>0>x>>>0?x:t}else{y=j;j=t}q=0-l|0;b:do if(j>>>0>y>>>0)while(1){m=j+-4|0;if(c[m>>2]|0){t=1;x=j;break b}if(m>>>0>y>>>0)j=m;else{t=0;x=m;break}}else{t=0;x=j}while(0);do if(u){j=k+((w^1)&1)|0;if((j|0)>(l|0)&(l|0)>-5){k=j+-1-l|0;n=i+-1|0}else{k=j+-1|0;n=i+-2|0}if(!(h&8)){if(t?(A=c[x+-4>>2]|0,(A|0)!=0):0)if(!((A>>>0)%10|0)){j=10;m=0;do{j=j*10|0;m=m+1|0}while(!((A>>>0)%(j>>>0)|0|0))}else m=0;else m=9;j=((x-z>>2)*9|0)+-9|0;if((n|32|0)==102){i=j-m|0;i=(i|0)>0?i:0;k=(k|0)<(i|0)?k:i;break}else{i=j+l-m|0;i=(i|0)>0?i:0;k=(k|0)<(i|0)?k:i;break}}}else n=i;while(0);g=(k|0)!=0;o=g?1:h>>>3&1;p=(n|32|0)==102;if(p){w=0;j=(l|0)>0?l:0}else{j=(l|0)<0?q:l;j=Ra(j,((j|0)<0)<<31>>31,E)|0;m=E;if((m-j|0)<2)do{j=j+-1|0;a[j>>0]=48}while((m-j|0)<2);a[j+-1>>0]=(l>>31&2)+43;j=j+-2|0;a[j>>0]=n;w=j;j=m-j|0}j=D+1+k+o+j|0;Ta(b,32,f,j,h);La(b,B,D);Ta(b,48,f,j,h^65536);if(p){o=y>>>0>C>>>0?C:y;q=G+9|0;p=q;n=G+8|0;m=o;do{l=Ra(c[m>>2]|0,0,q)|0;if((m|0)==(o|0)){if((l|0)==(q|0)){a[n>>0]=48;l=n}}else if(l>>>0>G>>>0){ob(G|0,48,l-F|0)|0;do l=l+-1|0;while(l>>>0>G>>>0)}La(b,l,p-l|0);m=m+4|0}while(m>>>0<=C>>>0);if(!((h&8|0)==0&(g^1)))La(b,1080,1);if(m>>>0>>0&(k|0)>0)while(1){l=Ra(c[m>>2]|0,0,q)|0;if(l>>>0>G>>>0){ob(G|0,48,l-F|0)|0;do l=l+-1|0;while(l>>>0>G>>>0)}La(b,l,(k|0)<9?k:9);m=m+4|0;l=k+-9|0;if(!(m>>>0>>0&(k|0)>9)){k=l;break}else k=l}Ta(b,48,k+9|0,9,0)}else{g=t?x:y+4|0;if(y>>>0>>0&(k|0)>-1){q=G+9|0;u=(h&8|0)==0;t=q;n=0-F|0;p=G+8|0;o=y;do{l=Ra(c[o>>2]|0,0,q)|0;if((l|0)==(q|0)){a[p>>0]=48;l=p}do if((o|0)==(y|0)){m=l+1|0;La(b,l,1);if(u&(k|0)<1){l=m;break}La(b,1080,1);l=m}else{if(l>>>0<=G>>>0)break;ob(G|0,48,l+n|0)|0;do l=l+-1|0;while(l>>>0>G>>>0)}while(0);F=t-l|0;La(b,l,(k|0)>(F|0)?F:k);k=k-F|0;o=o+4|0}while(o>>>0>>0&(k|0)>-1)}Ta(b,48,k+18|0,18,0);La(b,w,E-w|0)}Ta(b,32,f,j,h^8192)}while(0);I=H;return ((j|0)<(f|0)?f:j)|0}function Ga(a,b){a=a|0;b=b|0;var d=0.0,e=0;e=(c[b>>2]|0)+(8-1)&~(8-1);d=+g[e>>3];c[b>>2]=e+8;g[a>>3]=d;return}function Ha(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=I;I=I+224|0;o=t+208|0;s=t+160|0;r=t+80|0;q=t;h=s;i=h+40|0;do{c[h>>2]=0;h=h+4|0}while((h|0)<(i|0));c[o>>2]=c[e>>2];if((Ia(0,d,o,r,s,f,g)|0)<0)e=-1;else{if((c[b+76>>2]|0)>-1)p=Ja(b)|0;else p=0;e=c[b>>2]|0;n=e&32;if((a[b+74>>0]|0)<1)c[b>>2]=e&-33;j=b+48|0;if(!(c[j>>2]|0)){i=b+44|0;e=c[i>>2]|0;c[i>>2]=q;k=b+28|0;c[k>>2]=q;m=b+20|0;c[m>>2]=q;c[j>>2]=80;l=b+16|0;c[l>>2]=q+80;h=Ia(b,d,o,r,s,f,g)|0;if(e){N[c[b+36>>2]&1](b,0,0)|0;h=(c[m>>2]|0)==0?-1:h;c[i>>2]=e;c[j>>2]=0;c[l>>2]=0;c[k>>2]=0;c[m>>2]=0}}else h=Ia(b,d,o,r,s,f,g)|0;e=c[b>>2]|0;c[b>>2]=e|n;if(p|0)Ka(b);e=(e&32|0)==0?h:-1}I=t;return e|0}function Ia(d,e,f,h,i,j,k){d=d|0;e=e|0;f=f|0;h=h|0;i=i|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,J=0,K=0,L=0;K=I;I=I+64|0;H=K+56|0;F=K+40|0;z=K;J=K+48|0;G=K+60|0;c[H>>2]=e;C=(d|0)!=0;y=z+40|0;B=y;z=z+39|0;A=J+4|0;e=0;l=0;o=0;a:while(1){do{do if((e|0)>-1)if((l|0)>(2147483647-e|0)){c[(Da()|0)>>2]=75;e=-1;break}else{e=l+e|0;break}while(0);s=c[H>>2]|0;l=a[s>>0]|0;if(!(l<<24>>24)){x=92;break a}m=s;b:while(1){switch(l<<24>>24){case 37:{x=10;break b}case 0:{l=m;break b}default:{}}w=m+1|0;c[H>>2]=w;l=a[w>>0]|0;m=w}c:do if((x|0)==10){x=0;n=m;l=m;do{if((a[n+1>>0]|0)!=37)break c;l=l+1|0;n=n+2|0;c[H>>2]=n}while((a[n>>0]|0)==37)}while(0);l=l-s|0;if(C)La(d,s,l)}while((l|0)!=0);w=(Ma(a[(c[H>>2]|0)+1>>0]|0)|0)==0;l=c[H>>2]|0;if(!w?(a[l+2>>0]|0)==36:0){m=3;q=(a[l+1>>0]|0)+-48|0;p=1}else{m=1;q=-1;p=o}m=l+m|0;c[H>>2]=m;l=a[m>>0]|0;n=(l<<24>>24)+-32|0;if(n>>>0>31|(1<>2]=m;l=a[m>>0]|0;n=(l<<24>>24)+-32|0;if(n>>>0>31|(1<>24==42){if((Ma(a[m+1>>0]|0)|0)!=0?(D=c[H>>2]|0,(a[D+2>>0]|0)==36):0){l=D+1|0;c[i+((a[l>>0]|0)+-48<<2)>>2]=10;n=1;m=D+3|0;l=c[h+((a[l>>0]|0)+-48<<3)>>2]|0}else{if(p|0){e=-1;break}if(C){w=(c[f>>2]|0)+(4-1)&~(4-1);l=c[w>>2]|0;c[f>>2]=w+4}else l=0;n=0;m=(c[H>>2]|0)+1|0}c[H>>2]=m;u=(l|0)<0;o=u?o|8192:o;w=n;u=u?0-l|0:l}else{l=Na(H)|0;if((l|0)<0){e=-1;break}m=c[H>>2]|0;w=p;u=l}do if((a[m>>0]|0)==46){l=m+1|0;if((a[l>>0]|0)!=42){c[H>>2]=l;t=Na(H)|0;l=c[H>>2]|0;break}if(Ma(a[m+2>>0]|0)|0?(E=c[H>>2]|0,(a[E+3>>0]|0)==36):0){t=E+2|0;c[i+((a[t>>0]|0)+-48<<2)>>2]=10;t=c[h+((a[t>>0]|0)+-48<<3)>>2]|0;l=E+4|0;c[H>>2]=l;break}if(w|0){e=-1;break a}if(C){t=(c[f>>2]|0)+(4-1)&~(4-1);m=c[t>>2]|0;c[f>>2]=t+4}else m=0;l=(c[H>>2]|0)+2|0;c[H>>2]=l;t=m}else{l=m;t=-1}while(0);r=0;while(1){if(((a[l>>0]|0)+-65|0)>>>0>57){e=-1;break a}m=l;l=l+1|0;c[H>>2]=l;m=a[(a[m>>0]|0)+-65+(16+(r*58|0))>>0]|0;p=m&255;if((p+-1|0)>>>0>=8)break;else r=p}if(!(m<<24>>24)){e=-1;break}n=(q|0)>-1;do if(m<<24>>24==19)if(n){e=-1;break a}else x=54;else{if(n){c[i+(q<<2)>>2]=p;p=h+(q<<3)|0;q=c[p+4>>2]|0;x=F;c[x>>2]=c[p>>2];c[x+4>>2]=q;x=54;break}if(!C){e=0;break a}Oa(F,p,f,k);l=c[H>>2]|0;x=55}while(0);if((x|0)==54){x=0;if(C)x=55;else l=0}d:do if((x|0)==55){x=0;n=a[l+-1>>0]|0;n=(r|0)!=0&(n&15|0)==3?n&-33:n;l=o&-65537;q=(o&8192|0)==0?o:l;e:do switch(n|0){case 110:switch((r&255)<<24>>24){case 0:{c[c[F>>2]>>2]=e;l=0;break d}case 1:{c[c[F>>2]>>2]=e;l=0;break d}case 2:{l=c[F>>2]|0;c[l>>2]=e;c[l+4>>2]=((e|0)<0)<<31>>31;l=0;break d}case 3:{b[c[F>>2]>>1]=e;l=0;break d}case 4:{a[c[F>>2]>>0]=e;l=0;break d}case 6:{c[c[F>>2]>>2]=e;l=0;break d}case 7:{l=c[F>>2]|0;c[l>>2]=e;c[l+4>>2]=((e|0)<0)<<31>>31;l=0;break d}default:{l=0;break d}}case 112:{l=q|8;m=t>>>0>8?t:8;n=120;x=67;break}case 88:case 120:{l=q;m=t;x=67;break}case 111:{o=F;o=Qa(c[o>>2]|0,c[o+4>>2]|0,y)|0;m=B-o|0;l=q;m=(q&8|0)==0|(t|0)>(m|0)?t:m+1|0;r=0;p=1028;x=73;break}case 105:case 100:{m=F;l=c[m>>2]|0;m=c[m+4>>2]|0;if((m|0)<0){l=gb(0,0,l|0,m|0)|0;m=v()|0;n=F;c[n>>2]=l;c[n+4>>2]=m;n=1;p=1028;x=72;break e}else{n=(q&2049|0)!=0&1;p=(q&2048|0)==0?((q&1|0)==0?1028:1030):1029;x=72;break e}}case 117:{m=F;l=c[m>>2]|0;m=c[m+4>>2]|0;n=0;p=1028;x=72;break}case 99:{a[z>>0]=c[F>>2];s=z;q=l;o=1;n=0;m=1028;l=B;break}case 115:{p=c[F>>2]|0;p=(p|0)==0?1038:p;r=Sa(p,0,t)|0;L=(r|0)==0;s=p;q=l;o=L?t:r-p|0;n=0;m=1028;l=L?p+t|0:r;break}case 67:{c[J>>2]=c[F>>2];c[A>>2]=0;c[F>>2]=J;o=-1;x=79;break}case 83:{if(!t){Ta(d,32,u,0,q);l=0;x=89}else{o=t;x=79}break}case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{l=M[j&1](d,+g[F>>3],u,t,q,n)|0;break d}default:{o=t;n=0;m=1028;l=B}}while(0);f:do if((x|0)==67){o=F;o=Pa(c[o>>2]|0,c[o+4>>2]|0,y,n&32)|0;p=F;p=(l&8|0)==0|(c[p>>2]|0)==0&(c[p+4>>2]|0)==0;r=p?0:2;p=p?1028:1028+(n>>>4)|0;x=73}else if((x|0)==72){o=Ra(l,m,y)|0;l=q;m=t;r=n;x=73}else if((x|0)==79){x=0;l=0;p=c[F>>2]|0;while(1){m=c[p>>2]|0;if(!m)break;m=Ua(G,m)|0;n=(m|0)<0;if(n|m>>>0>(o-l|0)>>>0){x=83;break}l=m+l|0;if(o>>>0>l>>>0)p=p+4|0;else break}if((x|0)==83){x=0;if(n){e=-1;break a}}Ta(d,32,u,l,q);if(!l){l=0;x=89}else{n=0;o=c[F>>2]|0;while(1){m=c[o>>2]|0;if(!m){x=89;break f}m=Ua(G,m)|0;n=m+n|0;if((n|0)>(l|0)){x=89;break f}La(d,G,m);if(n>>>0>=l>>>0){x=89;break}else o=o+4|0}}}while(0);if((x|0)==73){x=0;n=F;n=(c[n>>2]|0)!=0|(c[n+4>>2]|0)!=0;L=(m|0)!=0|n;n=B-o+((n^1)&1)|0;s=L?o:y;q=(m|0)>-1?l&-65537:l;o=L?((m|0)>(n|0)?m:n):0;n=r;m=p;l=B}else if((x|0)==89){x=0;Ta(d,32,u,l,q^8192);l=(u|0)>(l|0)?u:l;break}t=l-s|0;r=(o|0)<(t|0)?t:o;L=r+n|0;l=(u|0)<(L|0)?L:u;Ta(d,32,l,L,q);La(d,m,n);Ta(d,48,l,L,q^65536);Ta(d,48,r,t,0);La(d,s,t);Ta(d,32,l,L,q^8192)}while(0);o=w}g:do if((x|0)==92)if(!d)if(!o)e=0;else{e=1;while(1){l=c[i+(e<<2)>>2]|0;if(!l)break;Oa(h+(e<<3)|0,l,f,k);e=e+1|0;if(e>>>0>=10){e=1;break g}}while(1){if(c[i+(e<<2)>>2]|0){e=-1;break g}e=e+1|0;if(e>>>0>=10){e=1;break}}}while(0);I=K;return e|0}function Ja(a){a=a|0;return 1}function Ka(a){a=a|0;return}function La(a,b,d){a=a|0;b=b|0;d=d|0;if(!(c[a>>2]&32))Ya(b,d,a)|0;return}function Ma(a){a=a|0;return (a+-48|0)>>>0<10|0}function Na(b){b=b|0;var d=0,e=0;if(!(Ma(a[c[b>>2]>>0]|0)|0))d=0;else{d=0;do{e=c[b>>2]|0;d=(d*10|0)+-48+(a[e>>0]|0)|0;e=e+1|0;c[b>>2]=e}while((Ma(a[e>>0]|0)|0)!=0)}return d|0}function Oa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0.0;a:do if(b>>>0<=20)do switch(b|0){case 9:{e=(c[d>>2]|0)+(4-1)&~(4-1);b=c[e>>2]|0;c[d>>2]=e+4;c[a>>2]=b;break a}case 10:{b=(c[d>>2]|0)+(4-1)&~(4-1);e=c[b>>2]|0;c[d>>2]=b+4;b=a;c[b>>2]=e;c[b+4>>2]=((e|0)<0)<<31>>31;break a}case 11:{b=(c[d>>2]|0)+(4-1)&~(4-1);e=c[b>>2]|0;c[d>>2]=b+4;b=a;c[b>>2]=e;c[b+4>>2]=0;break a}case 12:{b=(c[d>>2]|0)+(8-1)&~(8-1);e=b;f=c[e>>2]|0;e=c[e+4>>2]|0;c[d>>2]=b+8;b=a;c[b>>2]=f;c[b+4>>2]=e;break a}case 13:{f=(c[d>>2]|0)+(4-1)&~(4-1);b=c[f>>2]|0;c[d>>2]=f+4;b=(b&65535)<<16>>16;f=a;c[f>>2]=b;c[f+4>>2]=((b|0)<0)<<31>>31;break a}case 14:{f=(c[d>>2]|0)+(4-1)&~(4-1);b=c[f>>2]|0;c[d>>2]=f+4;f=a;c[f>>2]=b&65535;c[f+4>>2]=0;break a}case 15:{f=(c[d>>2]|0)+(4-1)&~(4-1);b=c[f>>2]|0;c[d>>2]=f+4;b=(b&255)<<24>>24;f=a;c[f>>2]=b;c[f+4>>2]=((b|0)<0)<<31>>31;break a}case 16:{f=(c[d>>2]|0)+(4-1)&~(4-1);b=c[f>>2]|0;c[d>>2]=f+4;f=a;c[f>>2]=b&255;c[f+4>>2]=0;break a}case 17:{f=(c[d>>2]|0)+(8-1)&~(8-1);h=+g[f>>3];c[d>>2]=f+8;g[a>>3]=h;break a}case 18:{P[e&1](a,d);break a}default:break a}while(0);while(0);return}function Pa(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;if(!((b|0)==0&(c|0)==0))do{e=e+-1|0;a[e>>0]=d[480+(b&15)>>0]|0|f;b=kb(b|0,c|0,4)|0;c=v()|0}while(!((b|0)==0&(c|0)==0));return e|0}function Qa(b,c,d){b=b|0;c=c|0;d=d|0;if(!((b|0)==0&(c|0)==0))do{d=d+-1|0;a[d>>0]=b&7|48;b=kb(b|0,c|0,3)|0;c=v()|0}while(!((b|0)==0&(c|0)==0));return d|0}function Ra(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0;if(c>>>0>0|(c|0)==0&b>>>0>4294967295)do{e=b;b=jb(b|0,c|0,10,0)|0;f=c;c=v()|0;g=eb(b|0,c|0,10,0)|0;g=gb(e|0,f|0,g|0,v()|0)|0;v()|0;d=d+-1|0;a[d>>0]=g&255|48}while(f>>>0>9|(f|0)==9&e>>>0>4294967295);if(b)do{g=b;b=(b>>>0)/10|0;d=d+-1|0;a[d>>0]=g-(b*10|0)|48}while(g>>>0>=10);return d|0}function Sa(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;h=d&255;f=(e|0)!=0;a:do if(f&(b&3|0)!=0){g=d&255;while(1){if((a[b>>0]|0)==g<<24>>24){i=6;break a}b=b+1|0;e=e+-1|0;f=(e|0)!=0;if(!(f&(b&3|0)!=0)){i=5;break}}}else i=5;while(0);if((i|0)==5)if(f)i=6;else i=16;b:do if((i|0)==6){g=d&255;if((a[b>>0]|0)==g<<24>>24)if(!e){i=16;break}else break;f=r(h,16843009)|0;c:do if(e>>>0>3)while(1){h=c[b>>2]^f;if((h&-2139062144^-2139062144)&h+-16843009|0)break c;b=b+4|0;e=e+-4|0;if(e>>>0<=3){i=11;break}}else i=11;while(0);if((i|0)==11)if(!e){i=16;break}while(1){if((a[b>>0]|0)==g<<24>>24)break b;e=e+-1|0;if(!e){i=16;break}else b=b+1|0}}while(0);if((i|0)==16)b=0;return b|0}function Ta(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0;g=I;I=I+256|0;f=g;if((c|0)>(d|0)&(e&73728|0)==0){e=c-d|0;ob(f|0,b<<24>>24|0,(e>>>0<256?e:256)|0)|0;if(e>>>0>255){b=c-d|0;do{La(a,f,256);e=e+-256|0}while(e>>>0>255);e=b&255}La(a,f,e)}I=g;return}function Ua(a,b){a=a|0;b=b|0;if(!a)a=0;else a=Va(a,b,0)|0;return a|0}function Va(b,d,e){b=b|0;d=d|0;e=e|0;do if(b){if(d>>>0<128){a[b>>0]=d;b=1;break}if(!(c[c[(Wa()|0)+188>>2]>>2]|0))if((d&-128|0)==57216){a[b>>0]=d;b=1;break}else{c[(Da()|0)>>2]=84;b=-1;break}if(d>>>0<2048){a[b>>0]=d>>>6|192;a[b+1>>0]=d&63|128;b=2;break}if(d>>>0<55296|(d&-8192|0)==57344){a[b>>0]=d>>>12|224;a[b+1>>0]=d>>>6&63|128;a[b+2>>0]=d&63|128;b=3;break}if((d+-65536|0)>>>0<1048576){a[b>>0]=d>>>18|240;a[b+1>>0]=d>>>12&63|128;a[b+2>>0]=d>>>6&63|128;a[b+3>>0]=d&63|128;b=4;break}else{c[(Da()|0)>>2]=84;b=-1;break}}else b=1;while(0);return b|0}function Wa(){return Xa()|0}function Xa(){return 644}function Ya(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;g=e+16|0;f=c[g>>2]|0;if(!f)if(!(Za(e)|0)){f=c[g>>2]|0;h=5}else f=0;else h=5;a:do if((h|0)==5){j=e+20|0;i=c[j>>2]|0;g=i;if((f-i|0)>>>0>>0){f=N[c[e+36>>2]&1](e,b,d)|0;break}b:do if((a[e+75>>0]|0)<0|(d|0)==0){h=g;e=0;g=d;f=b}else{i=d;while(1){f=i+-1|0;if((a[b+f>>0]|0)==10)break;if(!f){h=g;e=0;g=d;f=b;break b}else i=f}f=N[c[e+36>>2]&1](e,b,i)|0;if(f>>>0>>0)break a;h=c[j>>2]|0;e=i;g=d-i|0;f=b+i|0}while(0);mb(h|0,f|0,g|0)|0;c[j>>2]=(c[j>>2]|0)+g;f=e+g|0}while(0);return f|0}function Za(b){b=b|0;var d=0,e=0;d=b+74|0;e=a[d>>0]|0;a[d>>0]=e+255|e;d=c[b>>2]|0;if(!(d&8)){c[b+8>>2]=0;c[b+4>>2]=0;d=c[b+44>>2]|0;c[b+28>>2]=d;c[b+20>>2]=d;c[b+16>>2]=d+(c[b+48>>2]|0);d=0}else{c[b>>2]=d|32;d=-1}return d|0}function _a(a){a=+a;var b=0;g[h>>3]=a;b=c[h>>2]|0;u(c[h+4>>2]|0);return b|0}function $a(a,b){a=+a;b=b|0;var d=0,e=0,f=0;g[h>>3]=a;d=c[h>>2]|0;e=c[h+4>>2]|0;f=kb(d|0,e|0,52)|0;v()|0;switch(f&2047){case 0:{if(a!=0.0){a=+$a(a*18446744073709551616.0,b);d=(c[b>>2]|0)+-64|0}else d=0;c[b>>2]=d;break}case 2047:break;default:{c[b>>2]=(f&2047)+-1022;c[h>>2]=d;c[h+4>>2]=e&-2146435073|1071644672;a=+g[h>>3]}}return +a}function ab(a,b){a=a|0;b=b|0;var d=0,e=0;d=I;I=I+16|0;e=d;c[e>>2]=b;b=Ea(c[160]|0,a,e)|0;I=d;return b|0}function bb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=I;I=I+16|0;n=w;do if(a>>>0<245){k=a>>>0<11?16:a+11&-8;a=k>>>3;m=c[549]|0;d=m>>>a;if(d&3|0){e=(d&1^1)+a|0;f=2236+(e<<1<<2)|0;b=f+8|0;a=c[b>>2]|0;g=a+8|0;d=c[g>>2]|0;if((d|0)==(f|0))c[549]=m&~(1<>2]=f;c[b>>2]=d}v=e<<3;c[a+4>>2]=v|3;v=a+v+4|0;c[v>>2]=c[v>>2]|1;v=g;I=w;return v|0}l=c[551]|0;if(k>>>0>l>>>0){if(d|0){i=2<>>12&16;d=d>>>i;a=d>>>5&8;d=d>>>a;g=d>>>2&4;d=d>>>g;b=d>>>1&2;d=d>>>b;e=d>>>1&1;e=(a|i|g|b|e)+(d>>>e)|0;d=2236+(e<<1<<2)|0;b=d+8|0;g=c[b>>2]|0;i=g+8|0;a=c[i>>2]|0;if((a|0)==(d|0)){a=m&~(1<>2]=d;c[b>>2]=a;a=m}v=e<<3;h=v-k|0;c[g+4>>2]=k|3;f=g+k|0;c[f+4>>2]=h|1;c[g+v>>2]=h;if(l|0){e=c[554]|0;b=l>>>3;d=2236+(b<<1<<2)|0;b=1<>2]|0}c[b>>2]=e;c[a+12>>2]=e;c[e+8>>2]=a;c[e+12>>2]=d}c[551]=h;c[554]=f;v=i;I=w;return v|0}g=c[550]|0;if(g){i=(g&0-g)+-1|0;f=i>>>12&16;i=i>>>f;e=i>>>5&8;i=i>>>e;h=i>>>2&4;i=i>>>h;d=i>>>1&2;i=i>>>d;j=i>>>1&1;j=c[2500+((e|f|h|d|j)+(i>>>j)<<2)>>2]|0;i=(c[j+4>>2]&-8)-k|0;d=j;while(1){a=c[d+16>>2]|0;if(!a){a=c[d+20>>2]|0;if(!a)break}d=(c[a+4>>2]&-8)-k|0;h=d>>>0>>0;i=h?d:i;d=a;j=h?a:j}h=j+k|0;if(h>>>0>j>>>0){f=c[j+24>>2]|0;b=c[j+12>>2]|0;do if((b|0)==(j|0)){a=j+20|0;b=c[a>>2]|0;if(!b){a=j+16|0;b=c[a>>2]|0;if(!b){d=0;break}}while(1){e=b+20|0;d=c[e>>2]|0;if(!d){e=b+16|0;d=c[e>>2]|0;if(!d)break;else{b=d;a=e}}else{b=d;a=e}}c[a>>2]=0;d=b}else{d=c[j+8>>2]|0;c[d+12>>2]=b;c[b+8>>2]=d;d=b}while(0);do if(f|0){b=c[j+28>>2]|0;a=2500+(b<<2)|0;if((j|0)==(c[a>>2]|0)){c[a>>2]=d;if(!d){c[550]=g&~(1<>2]|0)==(j|0)?v:f+20|0)>>2]=d;if(!d)break}c[d+24>>2]=f;b=c[j+16>>2]|0;if(b|0){c[d+16>>2]=b;c[b+24>>2]=d}b=c[j+20>>2]|0;if(b|0){c[d+20>>2]=b;c[b+24>>2]=d}}while(0);if(i>>>0<16){v=i+k|0;c[j+4>>2]=v|3;v=j+v+4|0;c[v>>2]=c[v>>2]|1}else{c[j+4>>2]=k|3;c[h+4>>2]=i|1;c[h+i>>2]=i;if(l|0){e=c[554]|0;b=l>>>3;d=2236+(b<<1<<2)|0;b=1<>2]|0}c[b>>2]=e;c[a+12>>2]=e;c[e+8>>2]=a;c[e+12>>2]=d}c[551]=i;c[554]=h}v=j+8|0;I=w;return v|0}else m=k}else m=k}else m=k}else if(a>>>0<=4294967231){a=a+11|0;k=a&-8;e=c[550]|0;if(e){d=0-k|0;a=a>>>8;if(a)if(k>>>0>16777215)j=31;else{m=(a+1048320|0)>>>16&8;q=a<>>16&4;q=q<>>16&2;j=14-(i|m|j)+(q<>>15)|0;j=k>>>(j+7|0)&1|j<<1}else j=0;a=c[2500+(j<<2)>>2]|0;a:do if(!a){f=0;a=0;q=61}else{f=0;h=k<<((j|0)==31?0:25-(j>>>1)|0);i=a;a=0;while(1){g=(c[i+4>>2]&-8)-k|0;if(g>>>0>>0)if(!g){d=0;f=i;a=i;q=65;break a}else{d=g;a=i}q=c[i+20>>2]|0;i=c[i+16+(h>>>31<<2)>>2]|0;f=(q|0)==0|(q|0)==(i|0)?f:q;if(!i){q=61;break}else h=h<<1}}while(0);if((q|0)==61){if((f|0)==0&(a|0)==0){a=2<>>12&16;a=a>>>i;h=a>>>5&8;a=a>>>h;j=a>>>2&4;a=a>>>j;m=a>>>1&2;a=a>>>m;f=a>>>1&1;f=c[2500+((h|i|j|m|f)+(a>>>f)<<2)>>2]|0;a=0}if(!f){i=d;g=a}else q=65}if((q|0)==65)while(1){m=(c[f+4>>2]&-8)-k|0;g=m>>>0>>0;d=g?m:d;g=g?f:a;a=c[f+16>>2]|0;if(!a)a=c[f+20>>2]|0;if(!a){i=d;break}else{f=a;a=g}}if(((g|0)!=0?i>>>0<((c[551]|0)-k|0)>>>0:0)?(l=g+k|0,l>>>0>g>>>0):0){h=c[g+24>>2]|0;b=c[g+12>>2]|0;do if((b|0)==(g|0)){a=g+20|0;b=c[a>>2]|0;if(!b){a=g+16|0;b=c[a>>2]|0;if(!b){b=0;break}}while(1){f=b+20|0;d=c[f>>2]|0;if(!d){f=b+16|0;d=c[f>>2]|0;if(!d)break;else{b=d;a=f}}else{b=d;a=f}}c[a>>2]=0}else{v=c[g+8>>2]|0;c[v+12>>2]=b;c[b+8>>2]=v}while(0);do if(h){a=c[g+28>>2]|0;d=2500+(a<<2)|0;if((g|0)==(c[d>>2]|0)){c[d>>2]=b;if(!b){e=e&~(1<>2]|0)==(g|0)?v:h+20|0)>>2]=b;if(!b)break}c[b+24>>2]=h;a=c[g+16>>2]|0;if(a|0){c[b+16>>2]=a;c[a+24>>2]=b}a=c[g+20>>2]|0;if(a){c[b+20>>2]=a;c[a+24>>2]=b}}while(0);b:do if(i>>>0<16){v=i+k|0;c[g+4>>2]=v|3;v=g+v+4|0;c[v>>2]=c[v>>2]|1}else{c[g+4>>2]=k|3;c[l+4>>2]=i|1;c[l+i>>2]=i;b=i>>>3;if(i>>>0<256){d=2236+(b<<1<<2)|0;a=c[549]|0;b=1<>2]|0}c[b>>2]=l;c[a+12>>2]=l;c[l+8>>2]=a;c[l+12>>2]=d;break}b=i>>>8;if(b)if(i>>>0>16777215)d=31;else{u=(b+1048320|0)>>>16&8;v=b<>>16&4;v=v<>>16&2;d=14-(t|u|d)+(v<>>15)|0;d=i>>>(d+7|0)&1|d<<1}else d=0;b=2500+(d<<2)|0;c[l+28>>2]=d;a=l+16|0;c[a+4>>2]=0;c[a>>2]=0;a=1<>2]=l;c[l+24>>2]=b;c[l+12>>2]=l;c[l+8>>2]=l;break}b=c[b>>2]|0;c:do if((c[b+4>>2]&-8|0)!=(i|0)){e=i<<((d|0)==31?0:25-(d>>>1)|0);while(1){d=b+16+(e>>>31<<2)|0;a=c[d>>2]|0;if(!a)break;if((c[a+4>>2]&-8|0)==(i|0)){b=a;break c}else{e=e<<1;b=a}}c[d>>2]=l;c[l+24>>2]=b;c[l+12>>2]=l;c[l+8>>2]=l;break b}while(0);u=b+8|0;v=c[u>>2]|0;c[v+12>>2]=l;c[u>>2]=l;c[l+8>>2]=v;c[l+12>>2]=b;c[l+24>>2]=0}while(0);v=g+8|0;I=w;return v|0}else m=k}else m=k}else m=-1;while(0);d=c[551]|0;if(d>>>0>=m>>>0){a=d-m|0;b=c[554]|0;if(a>>>0>15){v=b+m|0;c[554]=v;c[551]=a;c[v+4>>2]=a|1;c[b+d>>2]=a;c[b+4>>2]=m|3}else{c[551]=0;c[554]=0;c[b+4>>2]=d|3;v=b+d+4|0;c[v>>2]=c[v>>2]|1}v=b+8|0;I=w;return v|0}h=c[552]|0;if(h>>>0>m>>>0){t=h-m|0;c[552]=t;v=c[555]|0;u=v+m|0;c[555]=u;c[u+4>>2]=t|1;c[v+4>>2]=m|3;v=v+8|0;I=w;return v|0}if(!(c[667]|0)){c[669]=4096;c[668]=4096;c[670]=-1;c[671]=-1;c[672]=0;c[660]=0;c[667]=n&-16^1431655768;a=4096}else a=c[669]|0;i=m+48|0;j=m+47|0;g=a+j|0;e=0-a|0;k=g&e;if(k>>>0<=m>>>0){v=0;I=w;return v|0}a=c[659]|0;if(a|0?(l=c[657]|0,n=l+k|0,n>>>0<=l>>>0|n>>>0>a>>>0):0){v=0;I=w;return v|0}d:do if(!(c[660]&4)){d=c[555]|0;e:do if(d){f=2644;while(1){n=c[f>>2]|0;if(n>>>0<=d>>>0?(n+(c[f+4>>2]|0)|0)>>>0>d>>>0:0)break;a=c[f+8>>2]|0;if(!a){q=128;break e}else f=a}b=g-h&e;if(b>>>0<2147483647){a=pb(b|0)|0;if((a|0)==((c[f>>2]|0)+(c[f+4>>2]|0)|0)){if((a|0)!=(-1|0)){h=a;g=b;q=145;break d}}else{e=a;q=136}}else b=0}else q=128;while(0);do if((q|0)==128){d=pb(0)|0;if((d|0)!=(-1|0)?(b=d,o=c[668]|0,p=o+-1|0,b=((p&b|0)==0?0:(p+b&0-o)-b|0)+k|0,o=c[657]|0,p=b+o|0,b>>>0>m>>>0&b>>>0<2147483647):0){n=c[659]|0;if(n|0?p>>>0<=o>>>0|p>>>0>n>>>0:0){b=0;break}a=pb(b|0)|0;if((a|0)==(d|0)){h=d;g=b;q=145;break d}else{e=a;q=136}}else b=0}while(0);do if((q|0)==136){d=0-b|0;if(!(i>>>0>b>>>0&(b>>>0<2147483647&(e|0)!=(-1|0))))if((e|0)==(-1|0)){b=0;break}else{h=e;g=b;q=145;break d}a=c[669]|0;a=j-b+a&0-a;if(a>>>0>=2147483647){h=e;g=b;q=145;break d}if((pb(a|0)|0)==(-1|0)){pb(d|0)|0;b=0;break}else{h=e;g=a+b|0;q=145;break d}}while(0);c[660]=c[660]|4;q=143}else{b=0;q=143}while(0);if(((q|0)==143?k>>>0<2147483647:0)?(r=pb(k|0)|0,p=pb(0)|0,t=p-r|0,s=t>>>0>(m+40|0)>>>0,!((r|0)==(-1|0)|s^1|r>>>0

>>0&((r|0)!=(-1|0)&(p|0)!=(-1|0))^1)):0){h=r;g=s?t:b;q=145}if((q|0)==145){b=(c[657]|0)+g|0;c[657]=b;if(b>>>0>(c[658]|0)>>>0)c[658]=b;j=c[555]|0;f:do if(j){e=2644;while(1){b=c[e>>2]|0;a=c[e+4>>2]|0;if((h|0)==(b+a|0)){q=154;break}d=c[e+8>>2]|0;if(!d)break;else e=d}if(((q|0)==154?(u=e+4|0,(c[e+12>>2]&8|0)==0):0)?h>>>0>j>>>0&b>>>0<=j>>>0:0){c[u>>2]=a+g;v=(c[552]|0)+g|0;t=j+8|0;t=(t&7|0)==0?0:0-t&7;u=j+t|0;t=v-t|0;c[555]=u;c[552]=t;c[u+4>>2]=t|1;c[j+v+4>>2]=40;c[556]=c[671];break}if(h>>>0<(c[553]|0)>>>0)c[553]=h;d=h+g|0;a=2644;while(1){if((c[a>>2]|0)==(d|0)){q=162;break}b=c[a+8>>2]|0;if(!b)break;else a=b}if((q|0)==162?(c[a+12>>2]&8|0)==0:0){c[a>>2]=h;l=a+4|0;c[l>>2]=(c[l>>2]|0)+g;l=h+8|0;l=h+((l&7|0)==0?0:0-l&7)|0;b=d+8|0;b=d+((b&7|0)==0?0:0-b&7)|0;k=l+m|0;i=b-l-m|0;c[l+4>>2]=m|3;g:do if((j|0)==(b|0)){v=(c[552]|0)+i|0;c[552]=v;c[555]=k;c[k+4>>2]=v|1}else{if((c[554]|0)==(b|0)){v=(c[551]|0)+i|0;c[551]=v;c[554]=k;c[k+4>>2]=v|1;c[k+v>>2]=v;break}a=c[b+4>>2]|0;if((a&3|0)==1){h=a&-8;e=a>>>3;h:do if(a>>>0<256){a=c[b+8>>2]|0;d=c[b+12>>2]|0;if((d|0)==(a|0)){c[549]=c[549]&~(1<>2]=d;c[d+8>>2]=a;break}}else{g=c[b+24>>2]|0;a=c[b+12>>2]|0;do if((a|0)==(b|0)){e=b+16|0;d=e+4|0;a=c[d>>2]|0;if(!a){a=c[e>>2]|0;if(!a){a=0;break}else d=e}while(1){f=a+20|0;e=c[f>>2]|0;if(!e){f=a+16|0;e=c[f>>2]|0;if(!e)break;else{a=e;d=f}}else{a=e;d=f}}c[d>>2]=0}else{v=c[b+8>>2]|0;c[v+12>>2]=a;c[a+8>>2]=v}while(0);if(!g)break;d=c[b+28>>2]|0;e=2500+(d<<2)|0;do if((c[e>>2]|0)!=(b|0)){v=g+16|0;c[((c[v>>2]|0)==(b|0)?v:g+20|0)>>2]=a;if(!a)break h}else{c[e>>2]=a;if(a|0)break;c[550]=c[550]&~(1<>2]=g;e=b+16|0;d=c[e>>2]|0;if(d|0){c[a+16>>2]=d;c[d+24>>2]=a}d=c[e+4>>2]|0;if(!d)break;c[a+20>>2]=d;c[d+24>>2]=a}while(0);b=b+h|0;f=h+i|0}else f=i;b=b+4|0;c[b>>2]=c[b>>2]&-2;c[k+4>>2]=f|1;c[k+f>>2]=f;b=f>>>3;if(f>>>0<256){d=2236+(b<<1<<2)|0;a=c[549]|0;b=1<>2]|0}c[b>>2]=k;c[a+12>>2]=k;c[k+8>>2]=a;c[k+12>>2]=d;break}b=f>>>8;do if(!b)e=0;else{if(f>>>0>16777215){e=31;break}u=(b+1048320|0)>>>16&8;v=b<>>16&4;v=v<>>16&2;e=14-(t|u|e)+(v<>>15)|0;e=f>>>(e+7|0)&1|e<<1}while(0);a=2500+(e<<2)|0;c[k+28>>2]=e;b=k+16|0;c[b+4>>2]=0;c[b>>2]=0;b=c[550]|0;d=1<>2]=k;c[k+24>>2]=a;c[k+12>>2]=k;c[k+8>>2]=k;break}b=c[a>>2]|0;i:do if((c[b+4>>2]&-8|0)!=(f|0)){e=f<<((e|0)==31?0:25-(e>>>1)|0);while(1){d=b+16+(e>>>31<<2)|0;a=c[d>>2]|0;if(!a)break;if((c[a+4>>2]&-8|0)==(f|0)){b=a;break i}else{e=e<<1;b=a}}c[d>>2]=k;c[k+24>>2]=b;c[k+12>>2]=k;c[k+8>>2]=k;break g}while(0);u=b+8|0;v=c[u>>2]|0;c[v+12>>2]=k;c[u>>2]=k;c[k+8>>2]=v;c[k+12>>2]=b;c[k+24>>2]=0}while(0);v=l+8|0;I=w;return v|0}a=2644;while(1){b=c[a>>2]|0;if(b>>>0<=j>>>0?(v=b+(c[a+4>>2]|0)|0,v>>>0>j>>>0):0)break;a=c[a+8>>2]|0}f=v+-47|0;a=f+8|0;a=f+((a&7|0)==0?0:0-a&7)|0;f=j+16|0;a=a>>>0>>0?j:a;b=a+8|0;d=g+-40|0;t=h+8|0;t=(t&7|0)==0?0:0-t&7;u=h+t|0;t=d-t|0;c[555]=u;c[552]=t;c[u+4>>2]=t|1;c[h+d+4>>2]=40;c[556]=c[671];d=a+4|0;c[d>>2]=27;c[b>>2]=c[661];c[b+4>>2]=c[662];c[b+8>>2]=c[663];c[b+12>>2]=c[664];c[661]=h;c[662]=g;c[664]=0;c[663]=b;b=a+24|0;do{u=b;b=b+4|0;c[b>>2]=7}while((u+8|0)>>>0>>0);if((a|0)!=(j|0)){g=a-j|0;c[d>>2]=c[d>>2]&-2;c[j+4>>2]=g|1;c[a>>2]=g;b=g>>>3;if(g>>>0<256){d=2236+(b<<1<<2)|0;a=c[549]|0;b=1<>2]|0}c[b>>2]=j;c[a+12>>2]=j;c[j+8>>2]=a;c[j+12>>2]=d;break}b=g>>>8;if(b)if(g>>>0>16777215)e=31;else{u=(b+1048320|0)>>>16&8;v=b<>>16&4;v=v<>>16&2;e=14-(t|u|e)+(v<>>15)|0;e=g>>>(e+7|0)&1|e<<1}else e=0;d=2500+(e<<2)|0;c[j+28>>2]=e;c[j+20>>2]=0;c[f>>2]=0;b=c[550]|0;a=1<>2]=j;c[j+24>>2]=d;c[j+12>>2]=j;c[j+8>>2]=j;break}b=c[d>>2]|0;j:do if((c[b+4>>2]&-8|0)!=(g|0)){e=g<<((e|0)==31?0:25-(e>>>1)|0);while(1){d=b+16+(e>>>31<<2)|0;a=c[d>>2]|0;if(!a)break;if((c[a+4>>2]&-8|0)==(g|0)){b=a;break j}else{e=e<<1;b=a}}c[d>>2]=j;c[j+24>>2]=b;c[j+12>>2]=j;c[j+8>>2]=j;break f}while(0);u=b+8|0;v=c[u>>2]|0;c[v+12>>2]=j;c[u>>2]=j;c[j+8>>2]=v;c[j+12>>2]=b;c[j+24>>2]=0}}else{v=c[553]|0;if((v|0)==0|h>>>0>>0)c[553]=h;c[661]=h;c[662]=g;c[664]=0;c[558]=c[667];c[557]=-1;c[562]=2236;c[561]=2236;c[564]=2244;c[563]=2244;c[566]=2252;c[565]=2252;c[568]=2260;c[567]=2260;c[570]=2268;c[569]=2268;c[572]=2276;c[571]=2276;c[574]=2284;c[573]=2284;c[576]=2292;c[575]=2292;c[578]=2300;c[577]=2300;c[580]=2308;c[579]=2308;c[582]=2316;c[581]=2316;c[584]=2324;c[583]=2324;c[586]=2332;c[585]=2332;c[588]=2340;c[587]=2340;c[590]=2348;c[589]=2348;c[592]=2356;c[591]=2356;c[594]=2364;c[593]=2364;c[596]=2372;c[595]=2372;c[598]=2380;c[597]=2380;c[600]=2388;c[599]=2388;c[602]=2396;c[601]=2396;c[604]=2404;c[603]=2404;c[606]=2412;c[605]=2412;c[608]=2420;c[607]=2420;c[610]=2428;c[609]=2428;c[612]=2436;c[611]=2436;c[614]=2444;c[613]=2444;c[616]=2452;c[615]=2452;c[618]=2460;c[617]=2460;c[620]=2468;c[619]=2468;c[622]=2476;c[621]=2476;c[624]=2484;c[623]=2484;v=g+-40|0;t=h+8|0;t=(t&7|0)==0?0:0-t&7;u=h+t|0;t=v-t|0;c[555]=u;c[552]=t;c[u+4>>2]=t|1;c[h+v+4>>2]=40;c[556]=c[671]}while(0);b=c[552]|0;if(b>>>0>m>>>0){t=b-m|0;c[552]=t;v=c[555]|0;u=v+m|0;c[555]=u;c[u+4>>2]=t|1;c[v+4>>2]=m|3;v=v+8|0;I=w;return v|0}}c[(Da()|0)>>2]=12;v=0;I=w;return v|0}function cb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;if(!a)return;d=a+-8|0;e=c[553]|0;a=c[a+-4>>2]|0;b=a&-8;k=d+b|0;do if(!(a&1)){f=c[d>>2]|0;if(!(a&3))return;g=d+(0-f)|0;h=f+b|0;if(g>>>0>>0)return;if((c[554]|0)==(g|0)){b=k+4|0;a=c[b>>2]|0;if((a&3|0)!=3){i=g;j=g;b=h;break}c[551]=h;c[b>>2]=a&-2;c[g+4>>2]=h|1;c[g+h>>2]=h;return}d=f>>>3;if(f>>>0<256){a=c[g+8>>2]|0;b=c[g+12>>2]|0;if((b|0)==(a|0)){c[549]=c[549]&~(1<>2]=b;c[b+8>>2]=a;i=g;j=g;b=h;break}}f=c[g+24>>2]|0;a=c[g+12>>2]|0;do if((a|0)==(g|0)){d=g+16|0;b=d+4|0;a=c[b>>2]|0;if(!a){a=c[d>>2]|0;if(!a){d=0;break}else b=d}while(1){e=a+20|0;d=c[e>>2]|0;if(!d){e=a+16|0;d=c[e>>2]|0;if(!d)break;else{a=d;b=e}}else{a=d;b=e}}c[b>>2]=0;d=a}else{d=c[g+8>>2]|0;c[d+12>>2]=a;c[a+8>>2]=d;d=a}while(0);if(f){a=c[g+28>>2]|0;b=2500+(a<<2)|0;if((c[b>>2]|0)==(g|0)){c[b>>2]=d;if(!d){c[550]=c[550]&~(1<>2]|0)==(g|0)?j:f+20|0)>>2]=d;if(!d){i=g;j=g;b=h;break}}c[d+24>>2]=f;b=g+16|0;a=c[b>>2]|0;if(a|0){c[d+16>>2]=a;c[a+24>>2]=d}a=c[b+4>>2]|0;if(a){c[d+20>>2]=a;c[a+24>>2]=d;i=g;j=g;b=h}else{i=g;j=g;b=h}}else{i=g;j=g;b=h}}else{i=d;j=d}while(0);if(i>>>0>=k>>>0)return;a=k+4|0;d=c[a>>2]|0;if(!(d&1))return;if(!(d&2)){if((c[555]|0)==(k|0)){k=(c[552]|0)+b|0;c[552]=k;c[555]=j;c[j+4>>2]=k|1;if((j|0)!=(c[554]|0))return;c[554]=0;c[551]=0;return}if((c[554]|0)==(k|0)){k=(c[551]|0)+b|0;c[551]=k;c[554]=i;c[j+4>>2]=k|1;c[i+k>>2]=k;return}f=(d&-8)+b|0;e=d>>>3;do if(d>>>0<256){b=c[k+8>>2]|0;a=c[k+12>>2]|0;if((a|0)==(b|0)){c[549]=c[549]&~(1<>2]=a;c[a+8>>2]=b;break}}else{g=c[k+24>>2]|0;a=c[k+12>>2]|0;do if((a|0)==(k|0)){d=k+16|0;b=d+4|0;a=c[b>>2]|0;if(!a){a=c[d>>2]|0;if(!a){d=0;break}else b=d}while(1){e=a+20|0;d=c[e>>2]|0;if(!d){e=a+16|0;d=c[e>>2]|0;if(!d)break;else{a=d;b=e}}else{a=d;b=e}}c[b>>2]=0;d=a}else{d=c[k+8>>2]|0;c[d+12>>2]=a;c[a+8>>2]=d;d=a}while(0);if(g|0){a=c[k+28>>2]|0;b=2500+(a<<2)|0;if((c[b>>2]|0)==(k|0)){c[b>>2]=d;if(!d){c[550]=c[550]&~(1<>2]|0)==(k|0)?h:g+20|0)>>2]=d;if(!d)break}c[d+24>>2]=g;b=k+16|0;a=c[b>>2]|0;if(a|0){c[d+16>>2]=a;c[a+24>>2]=d}a=c[b+4>>2]|0;if(a|0){c[d+20>>2]=a;c[a+24>>2]=d}}}while(0);c[j+4>>2]=f|1;c[i+f>>2]=f;if((j|0)==(c[554]|0)){c[551]=f;return}}else{c[a>>2]=d&-2;c[j+4>>2]=b|1;c[i+b>>2]=b;f=b}a=f>>>3;if(f>>>0<256){d=2236+(a<<1<<2)|0;b=c[549]|0;a=1<>2]|0}c[a>>2]=j;c[b+12>>2]=j;c[j+8>>2]=b;c[j+12>>2]=d;return}a=f>>>8;if(a)if(f>>>0>16777215)e=31;else{i=(a+1048320|0)>>>16&8;k=a<>>16&4;k=k<>>16&2;e=14-(h|i|e)+(k<>>15)|0;e=f>>>(e+7|0)&1|e<<1}else e=0;b=2500+(e<<2)|0;c[j+28>>2]=e;c[j+20>>2]=0;c[j+16>>2]=0;a=c[550]|0;d=1<>2]=j;c[j+24>>2]=b;c[j+12>>2]=j;c[j+8>>2]=j}else{a=c[b>>2]|0;b:do if((c[a+4>>2]&-8|0)!=(f|0)){e=f<<((e|0)==31?0:25-(e>>>1)|0);while(1){d=a+16+(e>>>31<<2)|0;b=c[d>>2]|0;if(!b)break;if((c[b+4>>2]&-8|0)==(f|0)){a=b;break b}else{e=e<<1;a=b}}c[d>>2]=j;c[j+24>>2]=a;c[j+12>>2]=j;c[j+8>>2]=j;break a}while(0);i=a+8|0;k=c[i>>2]|0;c[k+12>>2]=j;c[i>>2]=j;c[j+8>>2]=k;c[j+12>>2]=a;c[j+24>>2]=0}while(0);k=(c[557]|0)+-1|0;c[557]=k;if(k|0)return;a=2652;while(1){a=c[a>>2]|0;if(!a)break;else a=a+8|0}c[557]=-1;return}function db(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;f=a&65535;e=b&65535;c=r(e,f)|0;d=a>>>16;a=(c>>>16)+(r(e,d)|0)|0;e=b>>>16;b=r(e,f)|0;return (u((a>>>16)+(r(e,d)|0)+(((a&65535)+b|0)>>>16)|0),a+b<<16|c&65535|0)|0}function eb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=a;f=c;c=db(e,f)|0;a=v()|0;return (u((r(b,f)|0)+(r(d,e)|0)+a|a&0|0),c|0|0)|0}function fb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;c=a+c>>>0;return (u(b+d+(c>>>0>>0|0)>>>0|0),c|0)|0}function gb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;d=b-d-(c>>>0>a>>>0|0)>>>0;return (u(d|0),a-c>>>0|0)|0}function hb(a){a=a|0;return (a?31-(s(a^a-1)|0)|0:32)|0}function ib(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;l=a;j=b;k=j;h=d;n=e;i=n;if(!k){g=(f|0)!=0;if(!i){if(g){c[f>>2]=(l>>>0)%(h>>>0);c[f+4>>2]=0}n=0;f=(l>>>0)/(h>>>0)>>>0;return (u(n|0),f)|0}else{if(!g){n=0;f=0;return (u(n|0),f)|0}c[f>>2]=a|0;c[f+4>>2]=b&0;n=0;f=0;return (u(n|0),f)|0}}g=(i|0)==0;do if(h){if(!g){g=(s(i|0)|0)-(s(k|0)|0)|0;if(g>>>0<=31){m=g+1|0;i=31-g|0;b=g-31>>31;h=m;a=l>>>(m>>>0)&b|k<>>(m>>>0)&b;g=0;i=l<>2]=a|0;c[f+4>>2]=j|b&0;n=0;f=0;return (u(n|0),f)|0}g=h-1|0;if(g&h|0){i=(s(h|0)|0)+33-(s(k|0)|0)|0;p=64-i|0;m=32-i|0;j=m>>31;o=i-32|0;b=o>>31;h=i;a=m-1>>31&k>>>(o>>>0)|(k<>>(i>>>0))&b;b=b&k>>>(i>>>0);g=l<>>(o>>>0))&j|l<>31;break}if(f|0){c[f>>2]=g&l;c[f+4>>2]=0}if((h|0)==1){o=j|b&0;p=a|0|0;return (u(o|0),p)|0}else{p=hb(h|0)|0;o=k>>>(p>>>0)|0;p=k<<32-p|l>>>(p>>>0)|0;return (u(o|0),p)|0}}else{if(g){if(f|0){c[f>>2]=(k>>>0)%(h>>>0);c[f+4>>2]=0}o=0;p=(k>>>0)/(h>>>0)>>>0;return (u(o|0),p)|0}if(!l){if(f|0){c[f>>2]=0;c[f+4>>2]=(k>>>0)%(i>>>0)}o=0;p=(k>>>0)/(i>>>0)>>>0;return (u(o|0),p)|0}g=i-1|0;if(!(g&i)){if(f|0){c[f>>2]=a|0;c[f+4>>2]=g&k|b&0}o=0;p=k>>>((hb(i|0)|0)>>>0);return (u(o|0),p)|0}g=(s(i|0)|0)-(s(k|0)|0)|0;if(g>>>0<=30){b=g+1|0;i=31-g|0;h=b;a=k<>>(b>>>0);b=k>>>(b>>>0);g=0;i=l<>2]=a|0;c[f+4>>2]=j|b&0;o=0;p=0;return (u(o|0),p)|0}while(0);if(!h){k=i;j=0;i=0}else{m=d|0|0;l=n|e&0;k=fb(m|0,l|0,-1,-1)|0;d=v()|0;j=i;i=0;do{e=j;j=g>>>31|j<<1;g=i|g<<1;e=a<<1|e>>>31|0;n=a>>>31|b<<1|0;gb(k|0,d|0,e|0,n|0)|0;p=v()|0;o=p>>31|((p|0)<0?-1:0)<<1;i=o&1;a=gb(e|0,n|0,o&m|0,(((p|0)<0?-1:0)>>31|((p|0)<0?-1:0)<<1)&l|0)|0;b=v()|0;h=h-1|0}while((h|0)!=0);k=j;j=0}h=0;if(f|0){c[f>>2]=a;c[f+4>>2]=b}o=(g|0)>>>31|(k|h)<<1|(h<<1|g>>>31)&0|j;p=(g<<1|0>>>31)&-2|i;return (u(o|0),p)|0}function jb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return ib(a,b,c,d,0)|0}function kb(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){u(b>>>c|0);return a>>>c|(b&(1<>>c-32|0}function lb(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){u(b<>>32-c|0);return a<=8192){z(b|0,d|0,e|0)|0;return b|0}h=b|0;g=b+e|0;if((b&3)==(d&3)){while(b&3){if(!e)return h|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}e=g&-4|0;f=e-64|0;while((b|0)<=(f|0)){c[b>>2]=c[d>>2];c[b+4>>2]=c[d+4>>2];c[b+8>>2]=c[d+8>>2];c[b+12>>2]=c[d+12>>2];c[b+16>>2]=c[d+16>>2];c[b+20>>2]=c[d+20>>2];c[b+24>>2]=c[d+24>>2];c[b+28>>2]=c[d+28>>2];c[b+32>>2]=c[d+32>>2];c[b+36>>2]=c[d+36>>2];c[b+40>>2]=c[d+40>>2];c[b+44>>2]=c[d+44>>2];c[b+48>>2]=c[d+48>>2];c[b+52>>2]=c[d+52>>2];c[b+56>>2]=c[d+56>>2];c[b+60>>2]=c[d+60>>2];b=b+64|0;d=d+64|0}while((b|0)<(e|0)){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0}}else{e=g-4|0;while((b|0)<(e|0)){a[b>>0]=a[d>>0]|0;a[b+1>>0]=a[d+1>>0]|0;a[b+2>>0]=a[d+2>>0]|0;a[b+3>>0]=a[d+3>>0]|0;b=b+4|0;d=d+4|0}}while((b|0)<(g|0)){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0}return h|0}function nb(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;if((c|0)<(b|0)&(b|0)<(c+d|0)){e=b;c=c+d|0;b=b+d|0;while((d|0)>0){b=b-1|0;c=c-1|0;d=d-1|0;a[b>>0]=a[c>>0]|0}b=e}else mb(b,c,d)|0;return b|0}function ob(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;h=b+e|0;d=d&255;if((e|0)>=67){while(b&3){a[b>>0]=d;b=b+1|0}f=h&-4|0;i=d|d<<8|d<<16|d<<24;g=f-64|0;while((b|0)<=(g|0)){c[b>>2]=i;c[b+4>>2]=i;c[b+8>>2]=i;c[b+12>>2]=i;c[b+16>>2]=i;c[b+20>>2]=i;c[b+24>>2]=i;c[b+28>>2]=i;c[b+32>>2]=i;c[b+36>>2]=i;c[b+40>>2]=i;c[b+44>>2]=i;c[b+48>>2]=i;c[b+52>>2]=i;c[b+56>>2]=i;c[b+60>>2]=i;b=b+64|0}while((b|0)<(f|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}return h-e|0}function pb(a){a=a|0;var b=0,d=0,e=0;e=y()|0;d=c[i>>2]|0;b=d+a|0;if((a|0)>0&(b|0)<(d|0)|(b|0)<0){C(b|0)|0;w(12);return -1}if((b|0)>(e|0))if(!(A(b|0)|0)){w(12);return -1}c[i>>2]=b;return d|0}function qb(a,b){a=a|0;b=b|0;return L[a&1](b|0)|0}function rb(a,b,c,d,e,f,g){a=a|0;b=b|0;c=+c;d=d|0;e=e|0;f=f|0;g=g|0;return M[a&1](b|0,+c,d|0,e|0,f|0,g|0)|0}function sb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return N[a&1](b|0,c|0,d|0)|0}function tb(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;return O[a&1](b|0,c|0,d|0,e|0)|0}function ub(a,b,c){a=a|0;b=b|0;c=c|0;P[a&1](b|0,c|0)}function vb(a){a=a|0;t(0);return 0}function wb(a,b,c,d,e,f){a=a|0;b=+b;c=c|0;d=d|0;e=e|0;f=f|0;t(1);return 0}function xb(a,b,c){a=a|0;b=b|0;c=c|0;t(2);return 0}function yb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;t(3);return 0}function zb(a,b){a=a|0;b=b|0;t(4)} + +// EMSCRIPTEN_END_FUNCS +var L=[vb,Aa];var M=[wb,Fa];var N=[xb,Ba];var O=[yb,Ca];var P=[zb,Ga];return{___errno_location:Da,___muldi3:eb,___udivdi3:jb,_bitshift64Lshr:kb,_bitshift64Shl:lb,_compress:U,_decompress:V,_free:cb,_i64Add:fb,_i64Subtract:gb,_malloc:bb,_memcpy:mb,_memmove:nb,_memset:ob,_sbrk:pb,dynCall_ii:qb,dynCall_iidiiii:rb,dynCall_iiii:sb,dynCall_iiiii:tb,dynCall_vii:ub,establishStackSpace:T,stackAlloc:Q,stackRestore:S,stackSave:R}}) + + +// EMSCRIPTEN_END_ASM +(asmGlobalArg,asmLibraryArg,buffer);var ___errno_location=Module["___errno_location"]=asm["___errno_location"];var ___muldi3=Module["___muldi3"]=asm["___muldi3"];var ___udivdi3=Module["___udivdi3"]=asm["___udivdi3"];var _bitshift64Lshr=Module["_bitshift64Lshr"]=asm["_bitshift64Lshr"];var _bitshift64Shl=Module["_bitshift64Shl"]=asm["_bitshift64Shl"];var _compress=Module["_compress"]=asm["_compress"];var _decompress=Module["_decompress"]=asm["_decompress"];var _free=Module["_free"]=asm["_free"];var _i64Add=Module["_i64Add"]=asm["_i64Add"];var _i64Subtract=Module["_i64Subtract"]=asm["_i64Subtract"];var _malloc=Module["_malloc"]=asm["_malloc"];var _memcpy=Module["_memcpy"]=asm["_memcpy"];var _memmove=Module["_memmove"]=asm["_memmove"];var _memset=Module["_memset"]=asm["_memset"];var _sbrk=Module["_sbrk"]=asm["_sbrk"];var establishStackSpace=Module["establishStackSpace"]=asm["establishStackSpace"];var stackAlloc=Module["stackAlloc"]=asm["stackAlloc"];var stackRestore=Module["stackRestore"]=asm["stackRestore"];var stackSave=Module["stackSave"]=asm["stackSave"];var dynCall_ii=Module["dynCall_ii"]=asm["dynCall_ii"];var dynCall_iidiiii=Module["dynCall_iidiiii"]=asm["dynCall_iidiiii"];var dynCall_iiii=Module["dynCall_iiii"]=asm["dynCall_iiii"];var dynCall_iiiii=Module["dynCall_iiiii"]=asm["dynCall_iiiii"];var dynCall_vii=Module["dynCall_vii"]=asm["dynCall_vii"];Module["asm"]=asm;Module["ccall"]=ccall;if(memoryInitializer){if(!isDataURI(memoryInitializer)){memoryInitializer=locateFile(memoryInitializer)}if(ENVIRONMENT_IS_NODE||ENVIRONMENT_IS_SHELL){var data=readBinary(memoryInitializer);HEAPU8.set(data,GLOBAL_BASE)}else{addRunDependency("memory initializer");var applyMemoryInitializer=function(data){if(data.byteLength)data=new Uint8Array(data);HEAPU8.set(data,GLOBAL_BASE);if(Module["memoryInitializerRequest"])delete Module["memoryInitializerRequest"].response;removeRunDependency("memory initializer")};var doBrowserLoad=function(){readAsync(memoryInitializer,applyMemoryInitializer,function(){throw"could not load memory initializer "+memoryInitializer})};var memoryInitializerBytes=tryParseAsDataURI(memoryInitializer);if(memoryInitializerBytes){applyMemoryInitializer(memoryInitializerBytes.buffer)}else if(Module["memoryInitializerRequest"]){var useRequest=function(){var request=Module["memoryInitializerRequest"];var response=request.response;if(request.status!==200&&request.status!==0){var data=tryParseAsDataURI(Module["memoryInitializerRequestURL"]);if(data){response=data.buffer}else{console.warn("a problem seems to have happened with Module.memoryInitializerRequest, status: "+request.status+", retrying "+memoryInitializer);doBrowserLoad();return}}applyMemoryInitializer(response)};if(Module["memoryInitializerRequest"].response){setTimeout(useRequest,0)}else{Module["memoryInitializerRequest"].addEventListener("load",useRequest)}}else{doBrowserLoad()}}}var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";out(what);err(what);ABORT=true;EXITSTATUS=1;throw"abort("+what+"). Build with -s ASSERTIONS=1 for more info."}Module["abort"]=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run(); + +var HS_LOG_LEVEL = 0; + +function heatshrink_compress(inputBuffer) { + if (inputBuffer.BYTES_PER_ELEMENT!=1) throw new Error("Expecting Byte Array"); + var input_size = inputBuffer.length; + var output_size = input_size + (input_size/2) + 4; + + var bufIn = Module._malloc(input_size); + Module.HEAPU8.set(inputBuffer, bufIn); + // int compress(uint8_t *input, uint32_t input_size, uint8_t *output, uint32_t output_size, int log_lvl) + output_size = Module.ccall('compress', 'number', ['number','number','number','number','number'], [bufIn,input_size,0,0,HS_LOG_LEVEL/*log level*/])+1; + var bufOut = Module._malloc(output_size); + output_size = Module.ccall('compress', 'number', ['number','number','number','number','number'], [bufIn,input_size,bufOut,output_size,HS_LOG_LEVEL/*log level*/]); + // console.log("Compressed to "+output_size); + + var outputBuffer = new Uint8Array(output_size); + for (var i=0;i>16; + var pg=(p>>8)&255; + var pb=p&255; + var dr = r-pr; + var dg = g-pg; + var db = b-pb; + var d = dr*dr + dg*dg + db*db; + if (dthresh; + }, + "2bitbw":function(r,g,b) { + var c = (r+g+b) / 3; + c += 31; // rounding + if (c>255)c=255; + return c>>6; + }, + "4bit":function(r,g,b,a) { + var thresh = 128; + return ( + ((r>thresh)?1:0) | + ((g>thresh)?2:0) | + ((b>thresh)?4:0) | + ((a>thresh)?8:0)); + }, + "4bitmac":function(r,g,b,a) { + return PALETTE.lookup(PALETTE.MAC16,r,g,b,a, true /* no transparency */); + }, + "vga":function(r,g,b,a) { + return PALETTE.lookup(PALETTE.VGA,r,g,b,a); + }, + "web":function(r,g,b,a) { + return PALETTE.lookup(PALETTE.WEB,r,g,b,a); + }, + "rgb565":function(r,g,b,a) { + return ( + ((r&0xF8)<<8) | + ((g&0xFC)<<3) | + ((b&0xF8)>>3)); + }, + }; + var COL_TO_RGB = { + "1bit":function(c) { + return c ? 0xFFFFFFFF : 0xFF000000; + }, + "2bitbw":function(c) { + c = c&3; + c = c | (c<<2) | (c<<4) | (c<<6); + return 0xFF000000|(c<<16)|(c<<8)|c; + }, + "4bit":function(c) { + if (!(c&8)) return 0; + return ((c&1 ? 0xFF0000 : 0xFF000000) | + (c&2 ? 0x00FF00 : 0xFF000000) | + (c&4 ? 0x0000FF : 0xFF000000)); + }, + "4bitmac":function(c) { + return 0xFF000000|PALETTE.MAC16[c]; + }, + "vga":function(c) { + if (c==TRANSPARENT_8BIT) return 0; + return 0xFF000000|PALETTE.VGA[c]; + }, + "web":function(c) { + if (c==TRANSPARENT_8BIT) return 0; + return 0xFF000000|PALETTE.WEB[c]; + }, + "rgb565":function(c) { + var r = (c>>8)&0xF8; + var g = (c>>3)&0xFC; + var b = (c<<3)&0xF8; + return 0xFF000000|(r<<16)|(g<<8)|b; + }, + }; + // What Espruino uses by default + var BPP_TO_COLOR_FORMAT = { + 1 : "1bit", + 2 : "2bitbw", + 4 : "4bitmac", + 8 : "web", + 16 : "rgb565" + }; + + function clip(x) { + if (x<0) return 0; + if (x>255) return 255; + return x; + } + + + /* + See 'getOptions' for possible options + */ + function RGBAtoString(rgba, options) { + options = options||{}; + if (!rgba) throw new Error("No dataIn specified"); + if (!options.width) throw new Error("No Width specified"); + if (!options.height) throw new Error("No Height specified"); + if ("string"!=typeof options.diffusion) + options.diffusion = "none"; + options.compression = options.compression || false; + options.brightness = options.brightness | 0; + options.mode = options.mode || "1bit"; + options.output = options.output || "object"; + options.inverted = options.inverted || false; + options.transparent = !!options.transparent; + var transparentCol = undefined; + if (options.transparent) { + if (options.mode=="4bit") + transparentCol=0; + if (options.mode=="vga" || options.mode=="web") + transparentCol=TRANSPARENT_8BIT; + } + var bpp = COL_BPP[options.mode]; + var bitData = new Uint8Array(((options.width*options.height)*bpp+7)/8); + + function readImage() { + var pixels = new Int32Array(options.width*options.height); + var n = 0; + var er=0,eg=0,eb=0; + for (var y=0; y>>24; + var or = (cr>>16)&255; + var og = (cr>>8)&255; + var ob = cr&255; + if (options.diffusion.startsWith("error") && a>128) { + er = r-or; + eg = g-og; + eb = b-ob; + } else { + er = 0; + eg = 0; + eb = 0; + } + + n++; + } + } + return pixels; + } + function writeImage(pixels) { + var n = 0; + for (var y=0; y>3] |= c ? 128>>(n&7) : 0; + else if (bpp==2) bitData[n>>2] |= c<<((3-(n&3))*2); + else if (bpp==4) bitData[n>>1] |= c<<((n&1)?0:4); + else if (bpp==8) bitData[n] = c; + else if (bpp==16) { bitData[n<<1] = c>>8; bitData[1+(n<<1)] = c&0xFF; } + else throw new Error("Unhandled BPP"); + // Write preview + var cr = COL_TO_RGB[options.mode](c); + if (c===transparentCol) + cr = ((((x>>2)^(y>>2))&1)?0xFFFFFF:0); // pixel pattern + var oa = cr>>>24; + var or = (cr>>16)&255; + var og = (cr>>8)&255; + var ob = cr&255; + if (options.rgbaOut) { + options.rgbaOut[n*4] = or; + options.rgbaOut[n*4+1]= og; + options.rgbaOut[n*4+2]= ob; + options.rgbaOut[n*4+3]=255; + } + n++; + } + } + } + + var pixels = readImage(); + if (options.transparent && transparentCol===undefined && bpp<=16) { + // we have no fixed transparent colour - pick one that's unused + var colors = new Uint32Array(1<=0) + colors[pixels[i]]++; + // find an empty one + for (var i=0;i>2)^(y>>2))&1)?0xFFFFFF:0); + rgba[n*4] = rgba[n*4]*na + chequerboard*a; + rgba[n*4+1] = rgba[n*4+1]*na + chequerboard*a; + rgba[n*4+2] = rgba[n*4+2]*na + chequerboard*a; + rgba[n*4+3] = 255; + n++; + } + } + } + + /* RGBAtoString options, PLUS: + + updateCanvas: update canvas with the quantized image + */ + function canvastoString(canvas, options) { + options = options||{}; + options.width = canvas.width; + options.height = canvas.height; + var ctx = canvas.getContext("2d"); + var imageData = ctx.getImageData(0, 0, options.width, options.height); + var rgba = imageData.data; + if (options.updateCanvas) + options.rgbaOut = rgba; + var str = RGBAtoString(rgba, options); + if (options.updateCanvas) + ctx.putImageData(imageData,0,0); + return str; + } + + /* RGBAtoString options, PLUS: + + */ + function imagetoString(img, options) { + options = options||{}; + var canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + var ctx = canvas.getContext("2d"); + ctx.drawImage(img,0,0); + return canvastoString(canvas, options); + } + + function getOptions() { + return { + width : "int", + height : "int", + rgbaOut : "Uint8Array", // to store quantised data + diffusion : ["none"], + compression : "bool", + transparent : "bool", + brightness : "int", + mode : Object.keys(COL_BPP), + output : ["object","string","raw"], + inverted : "bool", + } + } + + /* Decode an Espruino image string into a URL, return undefined if it's not valid. + options = { + transparent : bool // should the image be transparent, or just chequered where transparent? + } */ + function stringToImageURL(data, options) { + options = options||{}; + var p = 0; + var width = 0|data.charCodeAt(p++); + var height = 0|data.charCodeAt(p++); + var bpp = 0|data.charCodeAt(p++); + var transparentCol = -1; + if (bpp&128) { + bpp &= 127; + transparentCol = 0|data.charCodeAt(p++); + } + var mode = BPP_TO_COLOR_FORMAT[bpp]; + if (!mode) return undefined; // unknown format + var bitmapSize = ((width*height*bpp)+7) >> 3; + // If it's the wrong length, it's not a bitmap or it's corrupt! + if (data.length != p+bitmapSize) + return undefined; + // Ok, build the picture + var canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + var ctx = canvas.getContext("2d"); + var imageData = ctx.getImageData(0, 0, width, height); + var rgba = imageData.data; + var no = 0; + var nibits = 0; + var nidata = 0; + for (var i=0;i>(nibits-bpp)) & ((1<>16)&255; // r + rgba[no++] = (cr>>8)&255; // g + rgba[no++] = cr&255; // b + rgba[no++] = cr>>>24; // a + } + if (!options.transparent) + RGBAtoCheckerboard(rgba, {width:width, height:height}); + ctx.putImageData(imageData,0,0); + return canvas.toDataURL(); + } + +// decode an Espruino image string into an HTML string, return undefined if it's not valid. See stringToImageURL + function stringToImageHTML(data, options) { + var url = stringToImageURL(data, options); + if (!url) return undefined; + return ''; + } + + // ======================================================= + return { + RGBAtoString : RGBAtoString, + RGBAtoCheckerboard : RGBAtoCheckerboard, + canvastoString : canvastoString, + imagetoString : imagetoString, + getOptions : getOptions, + + stringToImageHTML : stringToImageHTML, + stringToImageURL : stringToImageURL + }; +})); From 20ddb0cb44f87c6f567d7c7f16c3b0597db3964e Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 7 May 2020 10:19:57 +0100 Subject: [PATCH 281/878] drop chunk size again - too tight --- js/appinfo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/appinfo.js b/js/appinfo.js index 6a91dce2d..b4d0b5426 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -72,7 +72,7 @@ var AppInfo = { } else { let code = storageFile.content; // write code in chunks, in case it is too big to fit in RAM (fix #157) - var CHUNKSIZE = 8192; + var CHUNKSIZE = 4096; storageFile.cmd = `\x10require('Storage').write(${JSON.stringify(storageFile.name)},${toJS(code.substr(0,CHUNKSIZE))},0,${code.length});`; for (var i=CHUNKSIZE;i Date: Thu, 7 May 2020 10:20:09 +0100 Subject: [PATCH 282/878] Add option for 16 bit images --- apps/imgclock/custom.html | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/imgclock/custom.html b/apps/imgclock/custom.html index 1506aa7d4..8c920571a 100644 --- a/apps/imgclock/custom.html +++ b/apps/imgclock/custom.html @@ -52,6 +52,12 @@

+
+ +

+

or Enter Wifi name:

+

and Wifi password:

+
+ +
+ +
+
+
+ + +

Try your QR Code:

Click

@@ -14,19 +30,54 @@ + + + + \ No newline at end of file From 05e3a1f51f273d1f736343b5650009fad590abc1 Mon Sep 17 00:00:00 2001 From: jeffmer Date: Sun, 17 May 2020 12:01:52 +0100 Subject: [PATCH 446/878] gpsnav 0.03 --- apps.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 04c2f637d..a0421c2ed 100644 --- a/apps.json +++ b/apps.json @@ -331,10 +331,11 @@ { "id": "gpsnav", "name": "GPS Navigation", "icon": "icon.png", - "version":"0.01", - "description": "Displays GPS Course and Speed, + Directions to waypoint and waypoint recording", + "version":"0.03", + "description": "Displays GPS Course and Speed, + Directions to waypoint and waypoint recording, now with waypoint editor", "tags": "tool,outdoors,gps", "readme": "README.md", + "interface":"waypoints.html", "storage": [ {"name":"gpsnav.app.js","url":"app.js"}, {"name":"waypoints.json","url":"waypoints.json","evaluate":false}, From ca65ff6be6591b90798f2df510c5cad27f88b44e Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 17:50:07 +0100 Subject: [PATCH 447/878] Create app.js --- apps/BLEcontroller/app.js | 424 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 apps/BLEcontroller/app.js diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js new file mode 100644 index 000000000..a486917cf --- /dev/null +++ b/apps/BLEcontroller/app.js @@ -0,0 +1,424 @@ +/* + +========================================================== + +Simple event based robot controller that enables robot +to switch into automatic or manual control modes. Behaviours +are controlled via a simple finite state machine. + +In automatic mode the +robot will look after itself. In manual mode, the watch +will provide simple forward, back, left and right commands. +The messages will be transmitted to a partner BLE Espruino +using BLE + +Written by Richard Hopkins, May 2020 + +========================================================== + +declare global variables for watch button statuses */ +top_btn = false; +middle_btn = false; +left_btn= false; // the left side of the touch screen +right_btn = false; // the right side of the touch screen +bottom_btn = false; + +/* + +CONFIGURATION AREA - STATE VARIABLES + +declare global variables for the toggle button +statuses; if you add an additional toggle button +you should declare it and initiase it here */ + +var status_auto = {value: false}; +var status_mic = {value: true}; +var status_spk = {value: true}; + +/* trsnsmit message */ +const transmit = (state,object,status) => { + message = { + state: state, + obj: object, + val: status, + }; + print(message); + return JSON.stringify(message); +}; + +/* + +CONFIGURATION AREA - ICON DEFINITIONS + +Retrieve 30px PNG icons from: +https://icons8.com/icon/set/speak/ios-glyphs + +Create icons using: +https://www.espruino.com/Image+Converter +Use compression: true +Transparency: true +Diffusion: flat +Colours: 16bit RGB +Ouput as: Image Object + +Add an additional element to the icons array +with a unique name and the data from the Image Object +*/ +const icons = [ + { + name: "walk", + data: "gEBAP4B/ALyh7b/YALHfY9tACY55HfYdNHto7pHpIbXbL5fXAD6VlHuYAjHf47/Hf47tHK47LDa45zHc4NHHeILJHeonTO9o9rHf47/eOoB/ANg=" + }, + { + name: "sit", + data: "gEBAP4B/AP4BacO4ANHPI/rACp1/Hf49rGtI5/He7n3ACY55HcYAZHf45/Hf45rHe4XHGbI7/Va47zZZrpbHfbtXD5Y/vHcYB/AP4BmA" + }, + { + name: "joystick", + data: "gEBAP4B/AP4BMavIALHPI9vHf47/eP45vHpY5xHo451Hf47/FuYAHHNItHABa33AP6xpAD455HqY7/Hf47/Hd49pHKIB/AP4B/AMwA==" + }, + { + name: "left", + data: "gEBAP4B/AP4BKa9ojHAC5pfHJKDTUsYdZHb6ZfO+I9dABabdLbIBdHf473PP47NJdY7/ePIB/RJop5Ys7t/AP6PvD7o7fP8Y1zTZoHPf/4B/AP4B+A==" + }, + { + name: "right", + data: "gEBAP4B/AP4BKa+oAXDo45hCaqFbUbLBfbbo7bHMojTR7Y5LHa51ZALo75Ov47/FeY77AP4B5WdbF3dv4B/R94fdHb5/jGuabNA57//AP4B/APw=" + }, + { + name: "forward", + data: "gEBAP4B/AKSX5avIALHPI9tACY55HsoAbHPI9fHfZFVGMo7/Hf47/Hf47/Hf47/Hf47/Hf47/Hf47/Hf49XHOIB/ALw=" + }, + { + name: "backward", + data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/Hf47/Hf47/Hf47/HfIAfHf491W/L15HMo9THNI9PHNo9LHOI9HHOoB/ALg=" + }, + { + name: "back", + data: "gEBAP4B/AP4B/AKgADHPI71HP45/HP45/HP45/HP45/Hf49/Hv49/Hv49/Hv49/Hv497He4B/AP4B/AJAA==" + }, + { + name: "spk_on", + data: "gEBAP4B/AP4Bic/YAFPP4v1HrYZRVJo7ZDKp5jMJYvZHaYAHVL4LHACZrhADLBTJKI7dPLI7/Hf47/HeZBVFqZHZRJp1lAJ47LOtZTnHbIZDKLpHNAL69ZANp1tQbY5/AP4B/ANQ" + }, + { + name: "spk_off", + data: "gEBAPhB7P/o9rFKI9pFKY9tXNYZNHrZXfMaoAHPOZhNF7LdXHpKpZEJpvPDZK1ZAB49NPLo9jHdI9NHd49PHebvxEJY9NI6I7dHpaDXcKqfPHLKjZHcpTjHbIZDKa73JHa4BXGY45xe5Y7zV+o9/Hv49JHe4BEA=" + }, + { + name: "mic_on", + data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/GbY7TIcY7/Hf47/Hf47/HdY9NCpp5lCb57fOdYvNeJo91HNrlvHf7tVIdY77AP4BiA=" + }, + { + name: "mic_off", + data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/GbY7TIcY7/Wf47/HJZLjHZ45RHrI7NHJYhLHqoZJA54hNHr5lTXL6vPSra5jKbo9REZrLRHa5DTXp47jAA7TTF7INLRqY7fdKavhXKo5te6wA==" + }, + { + name: "comms", + data: "gEBAP4B+QvbF7ABo7/He49tACI7/Hf47zHtI7jJq47lRqoAVEqY7nHsoAZGJo71HrKxfQaY7bdKo7/Hdqz5B5Y7zHK47RD55FRHao3XHKo7JG7L1NHeJTbHboB/AP4BG" + } +]; + +/* finds icon data by name in the icon array and returns an image object*/ +const drawIcon = (name) => { + for (var icon of icons) { + if (icon.name == name) { + image = { + width : 30, height : 30, bpp : 16, + transparent : 1, + buffer: require("heatshrink").decompress(atob(icon.data)) + }; + return image;} + } +}; + +/* + +CONFIGURATION AREA - BUTTON DEFINITIONS + +for a simple button, just define a primary colour +and an icon name from the icon array and +the text to display beneath the button + +for toggle buttons, additionally provide secondary +colours, icon name and text. Also provide a reference +to a global variable for the value of the button. +The global variable should be declared at the start of +the program and it may be adviable to use the 'status_name' +format to ensure it is clear. + +*/ +var joystickBtn = { + primary_colour: 0x653E, + primary_icon: 'joystick', + primary_text: 'Joystick', + }; + +var turnLeftBtn = { + primary_colour: 0x653E, + primary_text: 'Left', + primary_icon: 'left', + }; + +var turnRightBtn = { + primary_colour: 0x33F9, + primary_text: 'Right', + primary_icon: 'right', + }; + +var autoBtn = { + primary_colour: 0xE9C7, + primary_text: 'Stop', + primary_icon: 'sit', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'Move', + secondary_icon : 'walk', + value: status_auto + }; + +var micBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'mic_off', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'mic_on', + value: status_mic + }; + +var spkBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'spk_off', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'spk_on', + value: status_spk + }; + +/* + +CONFIGURATION AREA - SCREEN DEFINITIONS + +a screen can have a button (as defined above) +on the left and/or the right of the screen. + +in adddition a screen can optionally have +an icon for each of the three buttons on +the left hand side of the screen. These +are defined as btn1, bt2 and bt3. The +values are names from the icon array. + +*/ +const menuScreen = { + left: autoBtn, + right: joystickBtn, + btn1: "comms" +}; + +const joystickScreen = { + left: turnLeftBtn, + right: turnRightBtn, + btn1: "forward", + btn2: "backward", + btn3: "back" +}; + +const commsScreen = { + left: micBtn, + right: spkBtn, + btn3: "back" +}; + +/* base state definition + +Each of the screens correspond to a state; +this class provides a constuctor for each +of the states + +*/ +class State { + constructor(params) { + this.state = params.state; + this.events = params.events; + this.screen = params.screen; + } +} + +/* + +CONFIGURATION AREA - BUTTON BEHAVIOURS/STATE TRANSITIONS + +This area defines how each screen behaves. + +Each screen corresponds to a different State of the +state machine. This makes it much easier to isolate +behaviours between screens. + +The state value is transmitted whenever a button is pressed +to provide context (so the receiving device, knows which +button was pressed on which screen). + +The screens are defined above. + +The events section identifies if a particular button has been +pressed and released on the screen and an action can then be taken. + +The events function receives a notification from a mySetWatch which +provides an event object that identifies which button and whether +it has been pressed down or released. Actions can then be taken. +The events function will always return a State object. + +If the events function returns different State from the current +one, then the state machine will change to that new State and redrsw +the screen appropriately. + +To add in additional capabilities for button presses, simply add +an additional 'if' statement. + +For toggle buttons, the value of the sppropiate status object is +inversed and the new value transmitted. + +*/ + +/* The Home State/Page is where the application beings */ +const Home = new State({ + state: "Home", + screen: menuScreen, + events: (event) => { + if ((event.object == "right") && (event.status == "end")) { + transmit("Joystick", "joystick", "on"); + return Joystick; + } + if ((event.object == "top") && (event.status == "end")) { + return Comms; + } + if ((event.object == "left") && (event.status == "end")) { + status_auto.value = !status_auto.value; + transmit(this.state, "auto", onOff(status_auto.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +/* Joystick page state */ +const Joystick = new State({ + state: "Joystick", + screen: joystickScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + transmit("Joystick", "joystick", "off"); + return Home; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +/* Comms page state */ +const Comms = new State({ + state: "Comms", + screen: commsScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return Home; + } + if ((event.object == "left") && (event.status == "end")) { + status_mic.value = !status_mic.value; + transmit(this.state, "mic", onOff(status_mic.value)); + return this; + } + if ((event.object == "right") && (event.status == "end")) { + status_spk.value = !status_spk.value; + transmit(this.state, "spk", onOff(status_spk.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +/* translate button status into english */ +const startEnd = status => status ? "start" : "end"; + +/* translate status into english */ +const onOff= status => status ? "on" : "off"; + + +/* create watching functions that will change the global +button status when pressed or released + +This is actuslly the hesrt of the program. When a button +is not being pressed, nothing is happening (no loops). +This makes the progrsm more battery efficient. + +When a setWatch event is raised, the custom callbacks defined +here will be called. These then fired as events to the current +state/screen of the state mschine. + +Some events, will result in the stste of the state machine +chsnging, which is why the screen is redrswn after each +button press. + +*/ +const setMyWatch = (params) => { + setWatch(() => { + params.bool=!params.bool; + machine = machine.events({object: params.label, status: startEnd(params.bool)}); + drawScreen(machine.screen); + }, params.btn, {repeat:true, edge:"both"}); +}; + +/* object array used to set up the watching functions +*/ +const buttons = [ + {bool : bottom_btn, label : "bottom",btn : BTN3}, + {bool : middle_btn, label : "mdiddle",btn : BTN2}, + {bool : top_btn, label : "top",btn : BTN1}, + {bool : left_btn, label : "left",btn : BTN4}, + {bool : right_btn, label : "right",btn : BTN5} + ]; + +/* set up watchers for buttons */ +for (var button of buttons) + {setMyWatch(button);} + +/* Draw various kinds of buttons */ +const drawButton = (params,side) => { + g.setFontAlign(0,1); + icon = drawIcon(params.primary_icon); + text = params.primary_text; + g.setColor(params.primary_colour); + const x = (side == "left") ? 0 : 120; + if ((params.toggle) && (params.value.value)) { + g.setColor(params.secondary_colour); + text = params.secondary_text; + icon = drawIcon(params.secondary_icon); + } + g.fillRect(0+x,24,119+x, 239); + g.setColor(0x000); + g.setFont("Vector",15); + g.setFontAlign(0,0.0); + g.drawString(text,60+x,160); + options = {rotate: 0, scale:2}; + g.drawImage(icon,x+60,120,options); +}; + +/* Draw the pages corresponding to the states */ +const drawScreen = (params) => { + drawButton(params.left,'left'); + drawButton(params.right,'right'); + g.setColor(0x000); + if (params.btn1) {g.drawImage(drawIcon(params.btn1),210,40);} + if (params.btn2) {g.drawImage(drawIcon(params.btn2),210,125);} + if (params.btn3) {g.drawImage(drawIcon(params.btn3),210,195);} +}; + +machine = Home; // instantiate the state machine at Home +Bangle.drawWidgets(); // draw active widgets +drawScreen(machine.screen); // draw the screen From 033b227e674a50e55a1bdc356bedc90045c18dd9 Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 17:56:05 +0100 Subject: [PATCH 448/878] Create app-icon.js --- apps/BLEcontroller/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/BLEcontroller/app-icon.js diff --git a/apps/BLEcontroller/app-icon.js b/apps/BLEcontroller/app-icon.js new file mode 100644 index 000000000..da959f36a --- /dev/null +++ b/apps/BLEcontroller/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("nk8wkBiIA/AH4A/AA8QaIYdYd4gOLG5odMBhYcHCBAuEgJVVDqQLHCA0BNpA6QSYgd5LLYaFSq4dQLR4wJLyQdKQJBbOJZwdYBxypRS6AdZJZ4drPH54/PH541DjIdCDjRaBDjYAhTITUeDy4cEDzAdXCwoANGh4ANIRASKFBQdRBZodtLLq0TDv4dZAH4A/AH4ArA==")) From 0e67901c39932c90cf93d9529f50d13f959a7042 Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 17:59:52 +0100 Subject: [PATCH 449/878] Update app-icon.js --- apps/BLEcontroller/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/BLEcontroller/app-icon.js b/apps/BLEcontroller/app-icon.js index da959f36a..db64a917d 100644 --- a/apps/BLEcontroller/app-icon.js +++ b/apps/BLEcontroller/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("nk8wkBiIA/AH4A/AA8QaIYdYd4gOLG5odMBhYcHCBAuEgJVVDqQLHCA0BNpA6QSYgd5LLYaFSq4dQLR4wJLyQdKQJBbOJZwdYBxypRS6AdZJZ4drPH54/PH541DjIdCDjRaBDjYAhTITUeDy4cEDzAdXCwoANGh4ANIRASKFBQdRBZodtLLq0TDv4dZAH4A/AH4ArA==")) +E.toArrayBuffer(atob("PDyEARERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERAAAAAAEREREREREREREREREREREREREREREREREQAAAAAAEREREREREREREQAAEREREREREREREAAAAAAAAAAAERERERERERERAAAAABERERERERERAAAAAAAAAAAAEREREREREREQAAAAAAERERERERERAAAAAAAREREREREREREREREQAAAAAAERERERERERAAAAAAEREREREREREREREREAAAEQAAAAAAAAAAAAAAAAABEREREREREREREREREAABERAAAAAAAAAAAAAAAAABEREREREREREREREREAABERAAAAAAAAAAAAAAAAABEREREREREREREREREAAAEQAAAAAAAAAAAAAAAAABEREREREREREREREREQAAAAAAARERERERERAAAAAAEREREREREREREREREQAAAAAAARERERERERAAAAAAARERERERERERERERERAAAAAAABERERERERAAAAAAAAAAAAEREREREREREREQAAAAABEREREREREAAAAAAAAAAAERERERERERERERAAAAAAEREREREREREREQAAAAAAERERERERERERERAAAAAAERERERERERERERAAAAAAEREREREREREREREAAAAAAREREREREREREREREREREREREREREREREREAAAAAAREREREREREREREREREREREREREREREREREQAAAAABEREREREREREREREREREREREREREREREREQAAAAABERERERERERERERERERERERERERERERERERAAAAAAERERERERERERERERERERERERERERERERERAAAAAAEREREREREREREREREREREREREREREREREREAAAAAAREREREREREREREREREREREREREREREREREAAAAAAREREREREREREREREREREREREREREREREREQAAAAABEREREREREREREREREREREREREREREREREQAAAAABERERERERERERERERERERERERERERERERERAAAAAAERERERERERERERERERERERERERERERERERAAAAAAEREREREREREREREREREREREREREREREREREAAAAREREREREREREREREREREREREREREREREREREAABEREREREREREREREREREREREREREREREREREREQEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQAAABERERERERERERERERERERERERERERERERERAAAAAAAREREREREREREREREREREREREREREREREAAAAAAAAAEREREREREREREREREREREREREREREREAAAAAAAAAERERERERERERERERERERERAAAAAAAAAAAAAAAAAAAAAAAAAAAREREREREREREQAAAAAAAAAAAAAAAAAAAAAAAAAAABEREREREREREAAAAAAAAAAAAAARAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAEREAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAEREAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAARAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQ==")) From ed20c802da0f7b577754d37c4e439be01cc54290 Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:01:52 +0100 Subject: [PATCH 450/878] Add files via upload --- apps/BLEcontroller/BLEcontroller.png | Bin 0 -> 579 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/BLEcontroller/BLEcontroller.png diff --git a/apps/BLEcontroller/BLEcontroller.png b/apps/BLEcontroller/BLEcontroller.png new file mode 100644 index 0000000000000000000000000000000000000000..df529e982df191f6cd16e13b91503880546e3b05 GIT binary patch literal 579 zcmV-J0=)f+P)0&l=6uncr60#<-4LD4u}oUzxLt0>JPsZnf=H(GxN=RY=~QshW#_o)vQwR6Y53F~sJV_j|%*5y{mx(s~cZ7WuRX_Eh7pF8SZ{s6XtF}HHkrwH5v6Rw41 zNv~@GuIa$r4sHRLz>^=B{%f=THUEMs;D+eweGN>yk*LQe-jt3q8=UAHE`(~Zj@)Qt ztU1v8g9121lQz+evKsB_gZkjyq`k;P$V1t$Rs%<)Kikb8MP#4*f0#kFbpFtz5!vGy!T@R R(GCCr002ovPDHLkV1mbo0=NJG literal 0 HcmV?d00001 From 89a49189f4c4694a971e332b69a0a62a569e6900 Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:07:04 +0100 Subject: [PATCH 451/878] Update apps.json --- apps.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps.json b/apps.json index 04c2f637d..6385082f6 100644 --- a/apps.json +++ b/apps.json @@ -1760,5 +1760,20 @@ { "name": "jbm8b.img", "url": "app-icon.js", "evaluate": true } ], "version": "0.03" + }, +{ + "id": "BLEcontroller", + "name": "BLE Robot Controller with Joystick", + "shortName": "BLE Controller", + "icon": "BLEcontroller.png", + "version": "0.01", + "description": "A configurable controller for BLE robots, including a basic joystick.", + "tags": "tools", + "readme": "README.md", + "allow_emulator":true, + "storage": [ + { "name": "BLEcontroller.app.js", "url": "app.js" }, + { "name": "BLEcontroller.img", "url": "app-icon.js", "evaluate": true } + ] } ] From 6bf2b7d9691d224b8fdf33b557a378fa6f06e9fd Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:09:54 +0100 Subject: [PATCH 452/878] Create README.md --- apps/BLEcontroller/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 apps/BLEcontroller/README.md diff --git a/apps/BLEcontroller/README.md b/apps/BLEcontroller/README.md new file mode 100644 index 000000000..172bb1758 --- /dev/null +++ b/apps/BLEcontroller/README.md @@ -0,0 +1,3 @@ +=== BLE Controller +==Some text += More text From 0d013efb8e1c342a187c54027a75f88fe2acbcd2 Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:13:23 +0100 Subject: [PATCH 453/878] Update app-icon.js --- apps/BLEcontroller/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/BLEcontroller/app-icon.js b/apps/BLEcontroller/app-icon.js index db64a917d..0f5e1aff6 100644 --- a/apps/BLEcontroller/app-icon.js +++ b/apps/BLEcontroller/app-icon.js @@ -1 +1 @@ -E.toArrayBuffer(atob("PDyEARERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERAAAAAAEREREREREREREREREREREREREREREREREQAAAAAAEREREREREREREQAAEREREREREREREAAAAAAAAAAAERERERERERERAAAAABERERERERERAAAAAAAAAAAAEREREREREREQAAAAAAERERERERERAAAAAAAREREREREREREREREQAAAAAAERERERERERAAAAAAEREREREREREREREREAAAEQAAAAAAAAAAAAAAAAABEREREREREREREREREAABERAAAAAAAAAAAAAAAAABEREREREREREREREREAABERAAAAAAAAAAAAAAAAABEREREREREREREREREAAAEQAAAAAAAAAAAAAAAAABEREREREREREREREREQAAAAAAARERERERERAAAAAAEREREREREREREREREQAAAAAAARERERERERAAAAAAARERERERERERERERERAAAAAAABERERERERAAAAAAAAAAAAEREREREREREREQAAAAABEREREREREAAAAAAAAAAAERERERERERERERAAAAAAEREREREREREREQAAAAAAERERERERERERERAAAAAAERERERERERERERAAAAAAEREREREREREREREAAAAAAREREREREREREREREREREREREREREREREREAAAAAAREREREREREREREREREREREREREREREREREQAAAAABEREREREREREREREREREREREREREREREREQAAAAABERERERERERERERERERERERERERERERERERAAAAAAERERERERERERERERERERERERERERERERERAAAAAAEREREREREREREREREREREREREREREREREREAAAAAAREREREREREREREREREREREREREREREREREAAAAAAREREREREREREREREREREREREREREREREREQAAAAABEREREREREREREREREREREREREREREREREQAAAAABERERERERERERERERERERERERERERERERERAAAAAAERERERERERERERERERERERERERERERERERAAAAAAEREREREREREREREREREREREREREREREREREAAAAREREREREREREREREREREREREREREREREREREAABEREREREREREREREREREREREREREREREREREREQEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQAAABERERERERERERERERERERERERERERERERERAAAAAAAREREREREREREREREREREREREREREREREAAAAAAAAAEREREREREREREREREREREREREREREREAAAAAAAAAERERERERERERERERERERERAAAAAAAAAAAAAAAAAAAAAAAAAAAREREREREREREQAAAAAAAAAAAAAAAAAAAAAAAAAAABEREREREREREAAAAAAAAAAAAAARAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAEREAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAEREAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAARAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQ==")) +E.toArrayBuffer(atob("QECEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEREREhEhEREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREj////MzIREREAAAAAAAAAAAAAAAAAAAAAAAAAARERP//////zMzIRERAAAAAAAAAAAAAAAAAAAAAAAAARES/////////zMzIREQAAAAAAAAAAAAAAAAAAAAAAARET//////////8zMzEREAAAAAAAAAAAAAAAAAAAAAARET////////////MzMxERAAAAAAAAAAAAAAAAAAAAABET/////////////zMzMREAAAAAAAAAAAAAAAAAAAABES//////////////8zMyERAAAAAAAAAAAAAAAAAAABES///////////////zMzMREQAAAAAAAAAAAAAAAAAAERP//////zMzMzP///8zMzERAAAAAAAAAAAAAAAAAAARL//////zMzMzMz///zMzMhEAAAAAAAAAAAAAAAAAARE//////zM///MzM///8zMyERAAAAAAAAAAAAAAAAABEf/////zM///8zMzP//zMzMREAAAAAAAAAAAAAAAAAES//////M////zMzM///MzMxEQAAAAAAAAAAAAAAAAARL/////8z//MzMzMz///zMzIRAAAAAAAAAAAAAAAAARE//////zP/8zMzMzP///MzMhEQAAAAAAAAAAAAAAABET//////M//zMzMzM///8zMyERAAAAAAAAAAAAAAAAERP/////8zPzMzMzMz///zMzMREAAAAAAAAAAAAAAAARE//////zMzMzMzMzP///MzMxEQAAAAAAAAAAAAAAABET//////MzMzMzMzM///8zMzERAAAAAAAAAAAAAAAAERP//////zMzMzMzM////zMzMREAAAAAAAAAAAAAAAARE///////8zMzMzM/////MzMxEQAAAAAAAAAAAAAAABET////////MzMzM/////8zMyERAAAAAAAAAAAAAAABERE/////////8z///////zMyEREQAAAAAAAAAAAAAAERERP/////////////////MzERERAAAAAAAAAAAAAAERIhEv////////////////8zIRIhEQAAAAAAAAAAAAARH/ER/////////////////zMRH/ERAAAAAAAAAAAAABESIRL/////////////////MyESIREAAAAAAAAAAAAAERERE/////////////////8zMREREQAAAAAAAAAAAAAREREv/////////////////zMyERERAAAAAAAAAAAAARERE///////////////////MzMhEREQAAAAAAAAAAARERET//////////////////8zMzEREREAAAAAAAAAABEQERP//////////////////zMzMREBEQAAAAAAAAABERARE///////////////////MzMxEQEREAAAAAAAABERABET//////////////////8zMzERABERAAAAAAERERAAERP//////////////////zMzMREAAREREAAAEREREAARE///////////////////MzMxEQABERERAAEREREQABET//////////////////8zMzERAAEREREQAREzERAAERP//////////////////zMzMREAAREAERABEf8REAARE///////////////////MzMxEQABEQAREAEREREQABET//////////////////8zMzERAAEREREQABEREQAAERP/8///P/8z//P/8z//PzMzMREAABEREQAAARERAAARE//zP/M//zP/Mz/zP/MzMzMxEQAAEREQAAAAAREAABET//P//z//M//z//M//z8zMzERAAAREAAAAAABEQAAERP//////////////////zMzMREAABEQAAAAAAEREAAREv//////////////////MzMhEQABERAAAAAAABEQAAEREREREREREREREREREREREREQAAERAAAAAAAAEREAABEREREREREREREREREREREREQAAEREAAAAAAAARERAAAREREREREREREREREREREREQAAEREQAAAAAAAREREQAAAAAAAAEREREREREREQAAAAAAEREREAAAAAAREREREAAAAAAAAREREREREREREAAAAAERERERAAAAABEQABEQAAAAAAABERERERERERERAAAAAREAAREAAAAAEQAAERAAAAAREREREREREREREREAAAABEAABEQAAAAARAAABEAAAARERERERERERERERERAAAAEQAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")) From 0bb93839e65d107a5a56d105199ac80a55740e64 Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:14:17 +0100 Subject: [PATCH 454/878] Add files via upload --- apps/BLEcontroller/BLEcontroller.png | Bin 579 -> 3473 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/BLEcontroller/BLEcontroller.png b/apps/BLEcontroller/BLEcontroller.png index df529e982df191f6cd16e13b91503880546e3b05..e42fe5dae5a7bc3cfc4aa20380f5a036df9d081f 100644 GIT binary patch literal 3473 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 delta 572 zcmV-C0>k~08^Z)4iBL{Q4GJ0x0000DNk~Le0000y0000y2nGNE06P5Ha*-hve*ySO zL_t(&f$f?-OT%yw#(%zppx`Ll!AZYDK}5ktT@@$6$+4>-4uYRW2PwEnt>EqpBH}1I zh^~rOaS>mJq!5cu&g7DRD))n1+Hm(gy?>6TS1=62FboYAfOp_4BK`$Zv#N%BfD&*F zyaI2)DXkX?r}JJNp{T89bhe@1S;c+}|v zR)8x((Kub6LC3T@MM2THU2eua4jvwYNT&0+a!sk}RB+K{=eX#yQ>@EP!n)k*SeJhZ z>vF4OU2YQAA>3# zZUL9TlOLDyk*LQe-jt3q8=UAHE`(~Zj@)QttU1v8g9121lQz+ zevKsB_gZkjyq`k;P$V1t$Rs%<)Kikb8MP#4*f0#kFbpFtz5!vG61?|g1JMou0000< KMNUMnLSTYaZ~#sK From 673e1c3c7bb326b62c9f352713deb63259f43d11 Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:18:08 +0100 Subject: [PATCH 455/878] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 6385082f6..afac26dba 100644 --- a/apps.json +++ b/apps.json @@ -1767,7 +1767,7 @@ "shortName": "BLE Controller", "icon": "BLEcontroller.png", "version": "0.01", - "description": "A configurable controller for BLE robots, including a basic joystick.", + "description": "A configurable controller for BLE robots, with a basic four direction joystick.", "tags": "tools", "readme": "README.md", "allow_emulator":true, From 077728de67e620ef4dc9f71c4e62642759406429 Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:18:56 +0100 Subject: [PATCH 456/878] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index afac26dba..c3780cfeb 100644 --- a/apps.json +++ b/apps.json @@ -1768,7 +1768,7 @@ "icon": "BLEcontroller.png", "version": "0.01", "description": "A configurable controller for BLE robots, with a basic four direction joystick.", - "tags": "tools", + "tags": "tool,bluetooth", "readme": "README.md", "allow_emulator":true, "storage": [ From ba68904acf2e6a436794d40e4236d28d697c1dea Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:23:51 +0100 Subject: [PATCH 457/878] Update app-icon.js --- apps/BLEcontroller/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/BLEcontroller/app-icon.js b/apps/BLEcontroller/app-icon.js index 0f5e1aff6..662f43c5c 100644 --- a/apps/BLEcontroller/app-icon.js +++ b/apps/BLEcontroller/app-icon.js @@ -1 +1 @@ -E.toArrayBuffer(atob("QECEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEREREhEhEREREAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREj////MzIREREAAAAAAAAAAAAAAAAAAAAAAAAAARERP//////zMzIRERAAAAAAAAAAAAAAAAAAAAAAAAARES/////////zMzIREQAAAAAAAAAAAAAAAAAAAAAAARET//////////8zMzEREAAAAAAAAAAAAAAAAAAAAAARET////////////MzMxERAAAAAAAAAAAAAAAAAAAAABET/////////////zMzMREAAAAAAAAAAAAAAAAAAAABES//////////////8zMyERAAAAAAAAAAAAAAAAAAABES///////////////zMzMREQAAAAAAAAAAAAAAAAAAERP//////zMzMzP///8zMzERAAAAAAAAAAAAAAAAAAARL//////zMzMzMz///zMzMhEAAAAAAAAAAAAAAAAAARE//////zM///MzM///8zMyERAAAAAAAAAAAAAAAAABEf/////zM///8zMzP//zMzMREAAAAAAAAAAAAAAAAAES//////M////zMzM///MzMxEQAAAAAAAAAAAAAAAAARL/////8z//MzMzMz///zMzIRAAAAAAAAAAAAAAAAARE//////zP/8zMzMzP///MzMhEQAAAAAAAAAAAAAAABET//////M//zMzMzM///8zMyERAAAAAAAAAAAAAAAAERP/////8zPzMzMzMz///zMzMREAAAAAAAAAAAAAAAARE//////zMzMzMzMzP///MzMxEQAAAAAAAAAAAAAAABET//////MzMzMzMzM///8zMzERAAAAAAAAAAAAAAAAERP//////zMzMzMzM////zMzMREAAAAAAAAAAAAAAAARE///////8zMzMzM/////MzMxEQAAAAAAAAAAAAAAABET////////MzMzM/////8zMyERAAAAAAAAAAAAAAABERE/////////8z///////zMyEREQAAAAAAAAAAAAAAERERP/////////////////MzERERAAAAAAAAAAAAAAERIhEv////////////////8zIRIhEQAAAAAAAAAAAAARH/ER/////////////////zMRH/ERAAAAAAAAAAAAABESIRL/////////////////MyESIREAAAAAAAAAAAAAERERE/////////////////8zMREREQAAAAAAAAAAAAAREREv/////////////////zMyERERAAAAAAAAAAAAARERE///////////////////MzMhEREQAAAAAAAAAAARERET//////////////////8zMzEREREAAAAAAAAAABEQERP//////////////////zMzMREBEQAAAAAAAAABERARE///////////////////MzMxEQEREAAAAAAAABERABET//////////////////8zMzERABERAAAAAAERERAAERP//////////////////zMzMREAAREREAAAEREREAARE///////////////////MzMxEQABERERAAEREREQABET//////////////////8zMzERAAEREREQAREzERAAERP//////////////////zMzMREAAREAERABEf8REAARE///////////////////MzMxEQABEQAREAEREREQABET//////////////////8zMzERAAEREREQABEREQAAERP/8///P/8z//P/8z//PzMzMREAABEREQAAARERAAARE//zP/M//zP/Mz/zP/MzMzMxEQAAEREQAAAAAREAABET//P//z//M//z//M//z8zMzERAAAREAAAAAABEQAAERP//////////////////zMzMREAABEQAAAAAAEREAAREv//////////////////MzMhEQABERAAAAAAABEQAAEREREREREREREREREREREREREQAAERAAAAAAAAEREAABEREREREREREREREREREREREQAAEREAAAAAAAARERAAAREREREREREREREREREREREQAAEREQAAAAAAAREREQAAAAAAAAEREREREREREQAAAAAAEREREAAAAAAREREREAAAAAAAAREREREREREREAAAAAERERERAAAAABEQABEQAAAAAAABERERERERERERAAAAAREAAREAAAAAEQAAERAAAAAREREREREREREREREAAAABEAABEQAAAAARAAABEAAAARERERERERERERERERAAAAEQAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")) +E.toArrayBuffer(atob("MDCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAABERIQAAAAAAAAAAAAAAAAAAAAAAAAABERIRpiEQAAAAAAAAAAAAAAAAAAAAAAEREhOiImEqYAAAAAAAAAAAAAAAAAAAABESP///8zOFEQAAAAAAAAAAAAAAAAAAARI//////z8zp6AAAAAAAAAAAAAAAAAAES////////PzOFEAAAAAAAAAAAAAAAABEv////////8/MyGgAAAAAAAAAAAAAAARI//////////z8zIRAAAAAAAAAAAAAAARP/////8/P///M/IRAAAAAAAAAAAAAAES/////zgzM///M/OFEAAAAAAAAAAAAAET////84/zMzP/8z8hEAAAAAAAAAAAAAEf////M///gzP/8/MyEAAAAAAAAAAAABEv///zP/8zjzM/8/M4UQAAAAAAAAAAABEv///zP/M48zj//zPyEQAAAAAAAAAAABE////zP/ODMzj//zPyEQAAAAAAAAAAABE////zMzjyM48//zPyEQAAAAAAAAAAABE/////ODMzOPP/8/M4QQAAAAAAAAAAABE/////MzjzOD///zPyEQAAAAAAAAAAABE/////8zOPMz///zMzEQAAAAAAAAAAABEj//////PzP///8/MxhQAAAAAAAAAAARES////////////8/MRpyAAAAAAAAAAASMRP////////////zMRMhAAAAAAAAAAARMR////////////8/IRMhAAAAAAAAAAARES/////////////zMhp6AAAAAAAAAAEREv////////////8/MyEacAAAAAAAABERIv/////////////zPyERGAAAAAAAABEBE//////////////zPyEQEQAAAAAAAREBE//////////////zPyEQERAAAAABERABE//////////////zPyEQAREQAAEREgABE//////////////zPyEQABERIAESESABE//////////////zPyEQARESEAEfIRABE//////////////zPyEQAREBEAEREgABE//////z//////8/MzEQABERIAAREQABE/8/8z/zPz/z8/M/MzGAABERAAABEQABE/8/8/8/Pz/z8/PzPyEQABEQAAAAEQABE//////////////zPyEQABEAAAAAERAAETMzMzMzMjMzMzODIxEAAREAAAAAARAAEREhGmIRGhESaiYRKmEAARAAAAAAEREgABERIaYhEaERJqEmEQABERIAAAABERIaAAAAAAEREhGmIREAAAARESGgAAABEAARAAAAAAEREhGmIRGgAAARAAEQAAABEAARAAABERIRpiERoREgAAARAAEQAAAAAAAAAAABERIRpiERoREgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==")) From dfc54d8d73703eb816ed2c37817c0a61a09e9edf Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:24:17 +0100 Subject: [PATCH 458/878] Add files via upload --- apps/BLEcontroller/BLEcontroller.png | Bin 3473 -> 2642 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/BLEcontroller/BLEcontroller.png b/apps/BLEcontroller/BLEcontroller.png index e42fe5dae5a7bc3cfc4aa20380f5a036df9d081f..3fa8575f30c5b25c3b1b21708de7281fed85de1c 100644 GIT binary patch literal 2642 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 A$p8QV literal 3473 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 From 0d8501f2d64e221ff80512cb819cdf4123c05141 Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:26:13 +0100 Subject: [PATCH 459/878] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index c3780cfeb..ef6f68d11 100644 --- a/apps.json +++ b/apps.json @@ -1767,7 +1767,7 @@ "shortName": "BLE Controller", "icon": "BLEcontroller.png", "version": "0.01", - "description": "A configurable controller for BLE robots, with a basic four direction joystick.", + "description": "A configurable controller for BLE robots, with a basic four direction joystick. Easy to customise and add your own menus.", "tags": "tool,bluetooth", "readme": "README.md", "allow_emulator":true, From a38371d8d4e208552470718cf082c78e6e40f5df Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:36:54 +0100 Subject: [PATCH 460/878] Update README.md --- apps/BLEcontroller/README.md | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/apps/BLEcontroller/README.md b/apps/BLEcontroller/README.md index 172bb1758..a21db6240 100644 --- a/apps/BLEcontroller/README.md +++ b/apps/BLEcontroller/README.md @@ -1,3 +1,31 @@ -=== BLE Controller -==Some text -= More text +# BLE Robot Controller with Joystic + +A highly customisable state machine driven user interface that will communicate with another BLE device. The controller uses the three buttons and the left and right hand side of the watch to provide a flexible and attractive BLE interface. Amaze your friends by controlling your robot from your watch! + +Commands are sent from the Controller to the BLE robot in a JSON format. + +## Usage + +The application can be configured at will by chaning the definitions of the screens, events, icons and buttons. + +Most changes are possible via data, rather than code change. + +## Features + +In its default state, it has three screens that provide the ability to: +turn the robot on or off +turn on and off its voice and microphone +make the robot move by spinning left or right and moving forward and backwards + +## Controls + +The controls will vary by screen, but I suggest a convention of using BTN3 (the bottom button) for moving backwards up the menu stack. + +## Requests + +In the first instance, please consult my blog post on this application here. + +## Creator + +Richard Hopkins, FIET CEng +May 2020 From ce066c2a3852895a293df19fdaa3a2ca13bff37a Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Sun, 17 May 2020 18:37:10 +0100 Subject: [PATCH 461/878] Update README.md --- apps/BLEcontroller/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/BLEcontroller/README.md b/apps/BLEcontroller/README.md index a21db6240..049a5f824 100644 --- a/apps/BLEcontroller/README.md +++ b/apps/BLEcontroller/README.md @@ -1,4 +1,4 @@ -# BLE Robot Controller with Joystic +# BLE Robot Controller with Joystick A highly customisable state machine driven user interface that will communicate with another BLE device. The controller uses the three buttons and the left and right hand side of the watch to provide a flexible and attractive BLE interface. Amaze your friends by controlling your robot from your watch! From 31e56b23eddfd7f6c2e37d0f8fa983019bfc25bb Mon Sep 17 00:00:00 2001 From: Ben Whittaker Date: Sun, 17 May 2020 18:46:44 -0400 Subject: [PATCH 462/878] Stop Gadgetbridge from ignoring initial message. Gadgetbridge seems to ignore the first line sent to it after connecting. This commit works around this by prepending each message with a blank line. --- apps/gbridge/widget.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/gbridge/widget.js b/apps/gbridge/widget.js index a87b9d1ec..0d0f2468d 100644 --- a/apps/gbridge/widget.js +++ b/apps/gbridge/widget.js @@ -13,6 +13,7 @@ }; function gbSend(message) { + Bluetooth.println(""); Bluetooth.println(JSON.stringify(message)); } From 9ebb718cc259475efe88b6a585ddb9d44165212d Mon Sep 17 00:00:00 2001 From: Ben Whittaker Date: Sun, 17 May 2020 13:37:08 -0400 Subject: [PATCH 463/878] gbridge: report battery status more often Make the gbridge widget report battery status - every 10 minutes - 2 seconds after a new bluetooth connection is initiated --- apps.json | 2 +- apps/gbridge/ChangeLog | 1 + apps/gbridge/widget.js | 8 +++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 04c2f637d..ff13cdff6 100644 --- a/apps.json +++ b/apps.json @@ -95,7 +95,7 @@ { "id": "gbridge", "name": "Gadgetbridge", "icon": "app.png", - "version":"0.10", + "version":"0.11", "description": "The default notification handler for Gadgetbridge notifications from Android", "tags": "tool,system,android,widget", "type":"widget", diff --git a/apps/gbridge/ChangeLog b/apps/gbridge/ChangeLog index f23a4eb6d..f66040388 100644 --- a/apps/gbridge/ChangeLog +++ b/apps/gbridge/ChangeLog @@ -9,3 +9,4 @@ 0.08: Don't turn on LCD at start of every song 0.09: Update Bluetooth connection state automatically 0.10: Make widget play well with other Gadgetbridge widgets/apps +0.11: Report battery status on connect and at regular intervals diff --git a/apps/gbridge/widget.js b/apps/gbridge/widget.js index 0d0f2468d..ae7d0f8fa 100644 --- a/apps/gbridge/widget.js +++ b/apps/gbridge/widget.js @@ -197,5 +197,11 @@ WIDGETS["gbridgew"] = { area: "tl", width: 24, draw: draw }; - gbSend({ t: "status", bat: E.getBattery() }); + function sendBattery() { + gbSend({ t: "status", bat: E.getBattery() }); + } + + NRF.on("connect", () => setTimeout(sendBattery, 2000)); + setInterval(sendBattery, 10*60*1000); + sendBattery(); })(); From 89bd6532255bbbc50ac03624c1844b2f08ad6293 Mon Sep 17 00:00:00 2001 From: Francesco Bedussi Date: Mon, 18 May 2020 22:46:45 +0200 Subject: [PATCH 464/878] chore: ignore .vscode folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index be33fbc90..757619ec5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ package-lock.json .DS_Store *.js.bak appdates.csv +.vscode From 3148a59dc6ccaa6646c262375e96c59ba821619f Mon Sep 17 00:00:00 2001 From: Francesco Bedussi Date: Mon, 18 May 2020 22:57:08 +0200 Subject: [PATCH 465/878] fix: simpletimer - BTN2 to open launcher --- apps.json | 2 +- apps/simpletimer/ChangeLog | 1 + apps/simpletimer/app.js | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index adc1cf907..a34dcf3a4 100644 --- a/apps.json +++ b/apps.json @@ -1633,7 +1633,7 @@ "id": "simpletimer", "name": "Timer", "icon": "app.png", - "version": "0.02", + "version": "0.03", "description": "Simple timer, useful when playing board games or cooking", "tags": "timer", "readme": "README.md", diff --git a/apps/simpletimer/ChangeLog b/apps/simpletimer/ChangeLog index f9f79cd47..3f8d98248 100644 --- a/apps/simpletimer/ChangeLog +++ b/apps/simpletimer/ChangeLog @@ -1,2 +1,3 @@ 0.01: Initial version 0.02: Reset with gesture +0.03: BTN2 to open launcher diff --git a/apps/simpletimer/app.js b/apps/simpletimer/app.js index b8e07d107..0bd7992e2 100644 --- a/apps/simpletimer/app.js +++ b/apps/simpletimer/app.js @@ -111,6 +111,7 @@ function reset(value) { state = value === 0 ? "unset" : "set"; } +setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); function addWatch() { clearWatch(); setWatch(changeState, BTN1, { From d98fca9f01c4d6e2a864c2e49a06154d178f51c0 Mon Sep 17 00:00:00 2001 From: jeffmer Date: Tue, 19 May 2020 15:22:41 +0100 Subject: [PATCH 466/878] Create ChangeLog --- apps/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/ChangeLog diff --git a/apps/ChangeLog b/apps/ChangeLog new file mode 100644 index 000000000..1a4baf536 --- /dev/null +++ b/apps/ChangeLog @@ -0,0 +1 @@ + From 17fb9e795f861841400221059996c67122b42d8f Mon Sep 17 00:00:00 2001 From: jeffmer Date: Tue, 19 May 2020 15:23:43 +0100 Subject: [PATCH 467/878] Delete ChangeLog --- apps/ChangeLog | 1 - 1 file changed, 1 deletion(-) delete mode 100644 apps/ChangeLog diff --git a/apps/ChangeLog b/apps/ChangeLog deleted file mode 100644 index 1a4baf536..000000000 --- a/apps/ChangeLog +++ /dev/null @@ -1 +0,0 @@ - From b45fb06ec1ba35536dd4a76ef5f2ef0270f55c4e Mon Sep 17 00:00:00 2001 From: jeffmer Date: Tue, 19 May 2020 15:25:21 +0100 Subject: [PATCH 468/878] Create ChangeLog --- apps/widviz/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/widviz/ChangeLog diff --git a/apps/widviz/ChangeLog b/apps/widviz/ChangeLog new file mode 100644 index 000000000..1a4baf536 --- /dev/null +++ b/apps/widviz/ChangeLog @@ -0,0 +1 @@ + From b602188abe3974d8d5c363c3765b05b19043a401 Mon Sep 17 00:00:00 2001 From: jeffmer Date: Tue, 19 May 2020 15:28:34 +0100 Subject: [PATCH 469/878] Widget files --- apps/widviz/eye.png | Bin 0 -> 1519 bytes apps/widviz/widget.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 apps/widviz/eye.png create mode 100644 apps/widviz/widget.js diff --git a/apps/widviz/eye.png b/apps/widviz/eye.png new file mode 100644 index 0000000000000000000000000000000000000000..414ad33f582b9e69e51269d45fe309b333d808c7 GIT binary patch literal 1519 zcmVOEpmkE19Hr3VSFItI*?O0g~z9Ncw>>2GDK`Ua)#w z`vaj!>bJxKq;g(Ptx;++;OTRv3)Flk@X0mjEh3!u$h4NIux%@pYl?F2574kLa=69* zOMh?%C`?t&%h_9%r^`*@Bq@NJ?*!htGU^RSS^Wl?&}_iVwAn>+p++LWg(v_7C!!<% z$X)kD*T{IAE!gjwV7(>9(EZh#>6dCcpwpeMlN|)>adlD7<}$@njd+?tjWau+Un<{Ism=iC zBMb4_br;n{5qNo-a_e#>n(-+H0Ehv6bHm-xPDG;gTrZU?UaL^01$5EsJ=kognlf=# zeT{ZSK{og0UMJbu4*Mbipvx6h=+wW6>x&|=p;)%NQZ3}HXRnjo{@tKE zlwiUH$f;UAYw#o>KN;P8&SslB9TE}x@l%Bls(EO3{W!#O3zk+EW;d)W;4jLdz@r*24FJ5~IyOBG0Q@>Q{z2Oqw||KWJFr$m zaoRi+$J&$3XrOL;sL|@BnlF|qR`UgnUMG3J$3rzW62ajbZFAki=DLONKB1d0r@iNF zx2MlVaz}V%e$JM1CDm-Sdb{l*Hc$-UNQ;AVh{a0LD=U@2r$(!nGSf%|Up;GByHJ7) zQCx^t7v-F))oUb)SR9Q3^B*#`b-7}RN<^6*X>m|~lK^V71#dbMc?tn|YfV0P`{S|< z&^cs}SuMq~m`|k``np-oYs{1YMfR=ErzW`R2)EgSNkFH6cT(1mEs~Vx-!uA+`XkhD zlL6-%nDumLJRI<LEid6RrGIRUg~8SODY_4=4z#uDWs z0MIeWbJp5z^fpbC+q*_Wmv8&2CIyfHG8^#Xyu=BQ0UWyOh;Tz50069F?8tEo!72ni zp~<6+)6O(zikyrcx@xB;D9*#oQ@fu4LICzw1BCGrIdo}|{)=l}8#x{g?Hl$J2gP?A&c zG^q_TVf=SA2Kz6M^46@oE7dCtd2%gN6@~aNGfy(_wucU0p*PDQ6Yex6)gehh5)oQo zqs6AK3O+LW>i0vvPIj~vqDaHKf{mpz-cW@i@LZ|9VVzFEdEDa&@AzRTIFWEWOn}ta zXqkx&(kVZb*;(~9+HxJwlJvRAMyuB{K$jmTJ-*&3<=rXEKyY8vs5hKp`4JbZK+8gr zx^l(8DbUVbcb(`Um}y~CuMCW!N@b9nqi3vpvKDX?W+!p6ld@)3aQ z1(FvYmZz+&V*p(vq0g_oTJ8pt=9_VmAJ@IEL3*jsWWdX`;v%_7D-qx#6aa!`bl4xc z<0iX?L#?*pknet9gW{T97ez|5=qgQVc71GMYPNii`ENAqzM#zkrP3TwD$N0<(m&`h Vo=7w-CD;G}002ovPDHLkV1nTx;!6Mk literal 0 HcmV?d00001 diff --git a/apps/widviz/widget.js b/apps/widviz/widget.js new file mode 100644 index 000000000..36d695c60 --- /dev/null +++ b/apps/widviz/widget.js @@ -0,0 +1,37 @@ +(() => { + + var saved = null; + + function hide(){ + if (!Bangle.isLCDOn() || saved) return; + saved = []; + for (var wd of WIDGETS) { + saved.push(wd.draw); + wd.draw=()=>{}; + } + g.setColor(0,0,0); + g.fillRect(0,0,239,23); + } + + function reveal(){ + if (!Bangle.isLCDOn() || !saved) return; + for (var wd of WIDGETS) wd.draw = saved.shift(); + Bangle.drawWidgets(); + saved=null; + } + + function setup(){ + setWatch(hide, BTN4, {repeat:true,edge:"rising"}); + setWatch(reveal, BTN5, {repeat:true,edge:"rising"}); + } + + function draw(){ + var img = E.toArrayBuffer(atob("GBgBAAAAAAAAAAAAAAAAAH4AAf+AB4HgDgBwHDw4OH4cMOcMYMMGYMMGMOcMOH4cHDw4DgBwB4HgAf+AAH4AAAAAAAAAAAAAAAAA")); + g.setColor(0x07ff); + g.drawImage(img,this.x,this.y); + } + + WIDGETS["viz"] ={area:"tl", width:24,draw:draw,setup:setup}; + setup(); + +})(); From fe0387b3bb6d7465790134dfee50be3d700baa16 Mon Sep 17 00:00:00 2001 From: jeffmer Date: Tue, 19 May 2020 15:29:50 +0100 Subject: [PATCH 470/878] Update ChangeLog --- apps/widviz/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/widviz/ChangeLog b/apps/widviz/ChangeLog index 1a4baf536..ac6257425 100644 --- a/apps/widviz/ChangeLog +++ b/apps/widviz/ChangeLog @@ -1 +1 @@ - + 0.01: New Widget From 19ed596a16250ea6ede6646e317eeb4575ed4ada Mon Sep 17 00:00:00 2001 From: jeffmer Date: Tue, 19 May 2020 15:33:01 +0100 Subject: [PATCH 471/878] Update apps.json --- apps.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps.json b/apps.json index a34dcf3a4..f351bee16 100644 --- a/apps.json +++ b/apps.json @@ -1761,5 +1761,17 @@ { "name": "jbm8b.img", "url": "app-icon.js", "evaluate": true } ], "version": "0.03" + }, + { "id": "widviz", + "name": "Widget Visibility Widget", + "shortName":"Viz Widget", + "icon": "eye.png", + "version":"0.01", + "description": "Touch left screen to hide top bar widgets, right screen to redisplay. Will not work with apps that use BTN4 & BTN5.", + "tags": "widget", + "type": "widget", + "storage": [ + {"name":"widviz.wid.js","url":"widget.js"} + ] } ] From 7e39d8f1b5881dbd21b06db873fad699f45b4869 Mon Sep 17 00:00:00 2001 From: GRISHENK0 Date: Wed, 20 May 2020 14:45:25 +0200 Subject: [PATCH 472/878] Update French locales Change thousands separator and modify the speed unit --- apps/locale/locales.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/locale/locales.js b/apps/locale/locales.js index cbc56b85c..3becc760b 100644 --- a/apps/locale/locales.js +++ b/apps/locale/locales.js @@ -145,10 +145,10 @@ var locales = { "fr_FR": { lang: "fr_FR", decimal_point: ",", - thousands_sep: ".", + thousands_sep: " ", currency_symbol: "\x80", int_curr_symbol: "EUR", - speed: "kmh", + speed: "km/h", distance: { 0: "m", 1: "km" }, temperature: "°C", ampm: { 0: "", 1: "" }, From 5f8e424f5fd0d640f5688d960f33edaf1194e193 Mon Sep 17 00:00:00 2001 From: Ben Whittaker Date: Mon, 11 May 2020 20:58:31 -0400 Subject: [PATCH 473/878] imgclock: Make imgclock text area wider This prevents imgclock from cutting off the date in locales with long date formats such as "Wednesday, September 10, 2020". Also adjusts the position and alignment of the date when necessary to prevent it from flowing off the edge of the screen. --- apps.json | 2 +- apps/imgclock/ChangeLog | 3 ++- apps/imgclock/app.js | 14 ++++++++++---- apps/imgclock/custom.html | 16 +++++++++------- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/apps.json b/apps.json index a34dcf3a4..07cedf21a 100644 --- a/apps.json +++ b/apps.json @@ -168,7 +168,7 @@ "name": "Image background clock", "shortName":"Image Clock", "icon": "app.png", - "version":"0.06", + "version":"0.07", "description": "A clock with an image as a background", "tags": "clock", "type" : "clock", diff --git a/apps/imgclock/ChangeLog b/apps/imgclock/ChangeLog index ae978f9f9..20906fb87 100644 --- a/apps/imgclock/ChangeLog +++ b/apps/imgclock/ChangeLog @@ -4,4 +4,5 @@ 0.04: Fix hour alignment for single digits Scaling for background images <240px wide 0.05: Fix memory/interval leak when LCD turns on -0.06: Support 12 hour time \ No newline at end of file +0.06: Support 12 hour time +0.07: Don't cut off wide date formats \ No newline at end of file diff --git a/apps/imgclock/app.js b/apps/imgclock/app.js index dc961f58b..becf0a1fb 100644 --- a/apps/imgclock/app.js +++ b/apps/imgclock/app.js @@ -7,7 +7,7 @@ var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]; var inf = require("Storage").readJSON("imgclock.face.json"); var img = require("Storage").read("imgclock.face.img"); var IX = inf.x, IY = inf.y, IBPP = inf.bpp; -var IW = 110, IH = 45, OY = 24; +var IW = 174, IH = 45, OY = 24; var bgwidth = img.charCodeAt(0); var bgoptions; if (bgwidth<240) @@ -40,7 +40,7 @@ function draw() { new Uint8Array(cg.buffer).set(bgimg); // draw time cg.setColor(inf.col); - var x = 40; + var x = 74 + 32 * inf.align; cg.setFont("7x11Numeric7Seg",3); cg.setFontAlign(1,-1); cg.drawString(hours, x, 0); @@ -54,8 +54,14 @@ function draw() { cg.drawString(("0"+t.getSeconds()).substr(-2), x, 20); cg.setFont("6x8",1); cg.drawString(meridian, x+2, 0); - cg.setFontAlign(0,-1); - cg.drawString(locale.date(t),IW/2,IH-8); + let date = locale.date(t); + if (cg.stringWidth(date) < IW-64) { + cg.setFontAlign(0, -1); + cg.drawString(date,IW/2+32*inf.align,IH-8); + } else { + cg.setFontAlign(inf.align, -1); + cg.drawString(date,IW*(inf.align+1)/2,IH-8); + } // draw to screen g.drawImage(cgimg,IX,IY+OY); } diff --git a/apps/imgclock/custom.html b/apps/imgclock/custom.html index 8c920571a..8428725af 100644 --- a/apps/imgclock/custom.html +++ b/apps/imgclock/custom.html @@ -13,9 +13,9 @@ - + diff --git a/js/espruinotools.js b/lib/espruinotools.js similarity index 100% rename from js/espruinotools.js rename to lib/espruinotools.js From 572a468cab6cd1e72f0f0a86e4f0817aa379c739 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 28 May 2020 14:20:56 +0100 Subject: [PATCH 591/878] Set page scaling better for mobile --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index af68a6d45..480fdd2e1 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + From 0c0fc9ac8f223c496d50855c04c001550173bee5 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 28 May 2020 14:33:37 +0100 Subject: [PATCH 592/878] Improve upload of binary files --- CHANGELOG.md | 1 + js/appinfo.js | 9 +++++++-- js/utils.js | 15 +++++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5cd6aef5..29b6aa6e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,3 +18,4 @@ Changed for individual apps are listed in `apps/appname/ChangeLog` * Adding '#search' after the URL (when not the name of a 'filter' chip) will set up search for that term * If `bin/pre-publish.sh` has been run and recent.csv created, add 'Sort By' chip * New 'espruinotools' which fixes pretokenise issue when ID follows ID (fix #416) +* Improve upload of binary files diff --git a/js/appinfo.js b/js/appinfo.js index 54f1458db..b0b4e05ca 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -7,9 +7,14 @@ if (typeof btoa==="undefined") { // Converts a string into most efficient way to send to Espruino (either json, base64, or compressed base64) function toJS(txt) { + let isBinary = false; + for (let i=0;i127) isBinary=true; + } let json = JSON.stringify(txt); - let b64 = "atob("+JSON.stringify(btoa(json))+")"; - let js = b64.length < json.length ? b64 : json; + let b64 = "atob("+JSON.stringify(btoa(txt))+")"; + let js = (isBinary || (b64.length < json.length)) ? b64 : json; if (typeof heatshrink !== "undefined") { let ua = new Uint8Array(txt.length); diff --git a/js/utils.js b/js/utils.js index 859c5b10d..69dcda93b 100644 --- a/js/utils.js +++ b/js/utils.js @@ -32,8 +32,18 @@ function httpGet(url) { return new Promise((resolve,reject) => { let oReq = new XMLHttpRequest(); oReq.addEventListener("load", () => { - if (oReq.status==200) resolve(oReq.responseText) - else reject(oReq.status+" - "+oReq.statusText); + // ensure we actually load the data as a raw 8 bit string (not utf-8/etc) + if (oReq.status==200) { + let a = new FileReader(); + a.onloadend = function() { + let bytes = new Uint8Array(a.result); + let str = ""; + for (let i=0;i reject()); oReq.addEventListener("abort", () => reject()); @@ -41,6 +51,7 @@ function httpGet(url) { oReq.onerror = function () { reject("HTTP Request failed"); }; + oReq.responseType = 'blob'; oReq.send(); }); } From ab5861126ca5042637700a06c69d38fac15a819b Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 28 May 2020 14:34:40 +0100 Subject: [PATCH 593/878] App description can now be markdown --- CHANGELOG.md | 1 + README.md | 2 +- js/index.js | 9 +++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29b6aa6e5..48bfe74ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,3 +19,4 @@ Changed for individual apps are listed in `apps/appname/ChangeLog` * If `bin/pre-publish.sh` has been run and recent.csv created, add 'Sort By' chip * New 'espruinotools' which fixes pretokenise issue when ID follows ID (fix #416) * Improve upload of binary files +* App description can now be markdown diff --git a/README.md b/README.md index 04854c99e..ac4fc716d 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,7 @@ and which gives information about the app for the Launcher. "name": "Readable name", // readable name "shortName": "Short name", // short name for launcher "icon": "icon.png", // icon in apps/ - "description": "...", // long description + "description": "...", // long description (can contain markdown) "type":"...", // optional(if app) - 'app'/'widget'/'launch'/'bootloader' "tags": "", // comma separated tag list for searching diff --git a/js/index.js b/js/index.js index 34975f3a1..363081a15 100644 --- a/js/index.js +++ b/js/index.js @@ -52,6 +52,11 @@ function showReadme(appid) { } httpGet(appPath+app.readme).then(show).catch(()=>show("Failed to load README.")); } +function getAppDescription(app) { + let appPath = `apps/${app.id}/`; + let markedOptions = { baseUrl : appPath }; + return marked(app.description, markedOptions); +} function handleCustomApp(appTemplate) { // Pops up an IFRAME that allows an app to be customised if (!appTemplate.custom) throw new Error("App doesn't have custom HTML"); @@ -259,7 +264,7 @@ function refreshLibrary() {
@@ -470,7 +475,7 @@ function refreshMyApps() {

${escapeHtml(app.name)} (${version.text})

-

${escapeHtml(app.description)}

+

${getAppDescription(app)}

See the code on GitHub
From ed47314f02d36420d187df9e62ea5adeef1f5121 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 28 May 2020 14:36:54 +0100 Subject: [PATCH 594/878] Added animated clock using palette cycling --- .eslintignore | 1 + apps.json | 18 +- apps/animclk/ChangeLog | 1 + apps/animclk/V29.LBM.js | 482 ++++++++++++++++++++++++++++++++++ apps/animclk/animclk.pal | Bin 0 -> 512 bytes apps/animclk/animclk.pixels1 | 1 + apps/animclk/animclk.pixels2 | 1 + apps/animclk/app-icon.js | 1 + apps/animclk/app.js | 116 ++++++++ apps/animclk/app.png | Bin 0 -> 4797 bytes apps/animclk/create_images.js | 57 ++++ 11 files changed, 677 insertions(+), 1 deletion(-) create mode 100644 apps/animclk/ChangeLog create mode 100644 apps/animclk/V29.LBM.js create mode 100644 apps/animclk/animclk.pal create mode 100644 apps/animclk/animclk.pixels1 create mode 100644 apps/animclk/animclk.pixels2 create mode 100644 apps/animclk/app-icon.js create mode 100644 apps/animclk/app.js create mode 100644 apps/animclk/app.png create mode 100644 apps/animclk/create_images.js diff --git a/.eslintignore b/.eslintignore index 40173021d..544f416aa 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,3 +3,4 @@ lib/imageconverter.js lib/qrcode.min.js lib/heatshrink.js +apps/animclk/V29.LBM.js diff --git a/apps.json b/apps.json index b888a9934..6093d82df 100644 --- a/apps.json +++ b/apps.json @@ -1787,7 +1787,7 @@ {"name":"binclock.app.js","url":"app.js"}, {"name":"binclock.img","url":"app-icon.js","evaluate":true} ] - } , + }, { "id": "pizzatimer", "name": "Pizza Timer", @@ -1801,5 +1801,21 @@ {"name":"pizzatimer.app.js","url":"app.js"}, {"name":"pizzatimer.img","url":"app-icon.js","evaluate":true} ] + }, + { "id": "animclk", + "name": "Animated Clock", + "shortName":"Anim Clock", + "icon": "app.png", + "version":"0.01", + "description": "An animated clock face using Mark Ferrari's amazing 8 bit game art and palette cycling: http://www.markferrari.com/art/8bit-game-art", + "tags": "clock,animated", + "type": "clock", + "storage": [ + {"name":"animclk.app.js","url":"app.js"}, + {"name":"animclk.pixels1","url":"animclk.pixels1"}, + {"name":"animclk.pixels2","url":"animclk.pixels2"}, + {"name":"animclk.pal","url":"animclk.pal"}, + {"name":"animclk.img","url":"app-icon.js","evaluate":true} + ] } ] diff --git a/apps/animclk/ChangeLog b/apps/animclk/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/animclk/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/animclk/V29.LBM.js b/apps/animclk/V29.LBM.js new file mode 100644 index 000000000..5b986d77d --- /dev/null +++ b/apps/animclk/V29.LBM.js @@ -0,0 +1,482 @@ +CanvasCycle.processImage({filename:'V29.LBM',width:640,height:480,colors:[[0,0,0],[219,247,255],[203,243,255],[175,235,255],[155,231,255],[131,223,255],[95,223,255],[95,215,255],[63,215,255],[47,207,255],[0,199,255],[23,191,255],[11,183,255],[31,175,255],[47,163,247],[47,151,239],[59,139,231],[63,127,219],[71,115,203],[147,203,255],[103,171,223],[67,123,143],[199,171,159],[179,215,171],[191,215,223],[183,223,239],[175,235,255],[155,211,231],[135,187,207],[151,207,167],[195,207,171],[199,171,159],[95,151,179],[95,151,179],[83,135,159],[71,119,139],[63,107,123],[59,103,115],[31,91,115],[47,99,119],[63,107,123],[67,123,143],[67,123,143],[67,127,147],[71,127,151],[71,131,151],[71,131,155],[75,135,159],[159,199,215],[31,103,123],[7,75,95],[0,71,87],[0,67,83],[0,67,83],[0,67,83],[0,71,91],[15,91,111],[31,103,127],[51,123,143],[63,131,151],[75,139,159],[87,151,167],[123,175,187],[163,199,207],[255,255,255],[255,255,255],[131,175,191],[111,155,175],[119,167,183],[139,179,195],[163,199,207],[191,215,223],[167,203,215],[191,215,223],[207,227,235],[215,231,239],[191,215,227],[231,243,247],[215,231,239],[231,243,247],[179,203,219],[167,191,207],[155,183,199],[143,175,191],[135,167,183],[123,159,175],[115,151,167],[119,155,171],[123,159,175],[127,163,179],[131,167,183],[139,171,187],[155,187,203],[179,203,219],[199,219,235],[223,239,255],[79,147,171],[59,131,155],[43,119,143],[31,107,131],[43,119,143],[59,131,159],[79,147,171],[99,163,187],[119,83,79],[211,159,135],[87,55,55],[55,31,31],[23,15,11],[115,71,63],[175,127,115],[231,179,155],[115,107,135],[159,139,155],[143,127,151],[191,167,187],[143,127,151],[115,107,135],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[247,247,251],[231,227,247],[207,215,243],[187,219,243],[195,211,231],[187,207,203],[91,91,91],[75,59,51],[75,59,51],[75,59,51],[79,71,71],[79,91,103],[99,107,123],[119,131,143],[143,151,163],[171,175,183],[179,191,195],[187,207,203],[187,207,203],[187,207,203],[187,207,203],[147,143,171],[183,151,175],[131,127,159],[131,127,159],[131,127,159],[159,147,179],[195,175,191],[111,95,115],[111,95,115],[123,103,123],[151,127,151],[111,95,115],[151,123,135],[203,167,175],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,239,231],[243,223,239],[231,199,223],[207,179,219],[187,171,211],[171,159,211],[155,151,215],[151,151,215],[155,159,219],[163,171,227],[175,191,247],[255,255,255],[255,255,255],[207,167,143],[147,103,95],[91,63,63],[71,51,51],[139,119,103],[91,71,63],[23,15,11],[215,171,155],[143,111,103],[119,91,83],[219,175,155],[143,111,103],[103,79,79],[79,59,59],[95,71,83],[111,91,111],[59,47,47],[99,75,67],[135,119,107],[63,51,51],[51,43,51],[95,71,83],[111,91,111],[79,59,59],[143,111,103],[203,175,163],[183,155,147],[255,239,227],[243,227,215],[235,215,203],[207,183,171],[179,155,143],[255,227,199],[243,211,183],[231,195,167],[219,179,151],[211,163,135],[199,147,123],[187,131,111],[179,119,99],[107,103,131],[215,171,155],[143,111,103],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[11,11,11],[107,103,131],[219,219,235],[255,255,255]],cycles:[{reverse:0,rate:0,low:59,high:63},{reverse:0,rate:0,low:7,high:13},{reverse:0,rate:0,low:13,high:17},{reverse:0,rate:1227,low:32,high:47},{reverse:0,rate:1689,low:48,high:63},{reverse:0,rate:1689,low:64,high:79},{reverse:0,rate:1227,low:80,high:95},{reverse:0,rate:921,low:96,high:103},{reverse:0,rate:1689,low:128,high:143},{reverse:0,rate:1536,low:22,high:31},{reverse:0,rate:0,low:138,high:142},{reverse:0,rate:0,low:0,high:0},{reverse:0,rate:0,low:0,high:0},{reverse:0,rate:0,low:0,high:0},{reverse:0,rate:0,low:0,high:0},{reverse:0,rate:0,low:0,high:0}],pixels:[ +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,108,108,108,252,252,109,109,109,109,109,109,252,252,252,252,252,252,252,252,252,108,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,252,110,109,110,252,110,252,110,252,110,252,110,252,252,252,109,252,252,252,252,252,252,252,109,252,109,109,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,107,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,108,109,108,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,109,108,252,108,252,109,252,109,109,109,252,109,252,109,252,109,252,109,252,109,108,108,108,108,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,252,110,109,110,252,110,252,110,109,110,252,110,252,110,252,110,252,110,252,110,252,110,252,110,252,109,252,109,252,109,252,252,252,109,252,109,252,109,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,109,252,252,252,107,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,108,109,108,109,108,109,108,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,108,108,109,109,109,109,252,109,109,109,109,109,109,109,109,109,252,109,252,252,252,108,108,108,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,252,252,252,110,109,110,109,110,109,110,109,110,109,110,252,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,109,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,110,252,110,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,252,109,108,108,109,109,252,109,252,109,252,109,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,252,110,252,110,252,110,252,110,109,110,252,110,252,110,252,110,252,110,252,110,252,110,252,252,252,252,252,109,252,109,252,109,252,110,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,110,252,110,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,108,109,108,109,109,109,108,109,252,109,109,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,109,109,109,252,109,109,109,109,109,109,109,252,109,252,109,252,108,108,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,252,110,109,110,109,110,109,110,252,110,109,110,252,110,252,110,252,252,252,110,252,252,252,252,252,252,252,109,252,109,252,110,252,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,110,252,252,252,110,252,252,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,110,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,109,109,252,109,109,109,252,109,252,109,252,109,252,109,252,109,109,109,252,109,252,109,252,109,108,109,108,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,252,110,252,110,252,110,109,110,252,110,252,110,252,110,252,110,252,110,252,110,252,109,252,252,252,109,252,109,252,109,252,110,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,108,109,109,109,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,108,109,109,108,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,110,109,110,109,110,109,110,109,110,109,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,109,252,110,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,109,252,109,252,110,252,110,252,110,252,110,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,109,109,109,109,109,252,109,109,109,252,109,252,109,252,109,252,109,109,109,109,109,108,109,108,108,108,109,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,252,110,252,110,109,110,252,110,252,110,252,110,252,110,252,110,252,252,252,110,252,110,252,109,252,109,252,110,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,110,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,108,109,108,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,108,109,109,109,109,109,252,109,109,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,252,109,109,109,109,109,108,109,108,109,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,252,110,109,110,109,110,252,110,109,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,109,252,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,109,252,109,252,109,252,110,252,110,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,108,109,252,109,252,109,252,109,252,252,252,109,252,252,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,109,109,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,109,109,109,252,109,109,109,252,109,109,109,252,109,252,108,108,108,108,108,108,109,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,18,110,252,110,109,110,109,110,109,110,252,110,252,110,252,252,252,252,252,110,252,109,252,109,252,109,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,109,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,108,109,108,109,108,109,252,109,252,109,252,252,252,252,109,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,109,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,109,109,108,109,109,109,109,108,108,108,108,109,109,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,252,110,109,110,109,110,109,110,109,110,252,110,252,110,252,252,252,252,252,252,252,109,252,109,252,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,109,252,109,252,109,252,109,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,109,252,109,252,109,252,109,252,109,252,109,252,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,108,108,108,109,109,252,108,108,108,108,108,108,109,108,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,109,110,109,110,109,110,109,110,252,110,252,110,252,252,252,110,252,110,252,109,252,109,252,109,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,109,108,109,109,109,108,109,252,109,109,109,109,109,109,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,109,109,108,109,252,109,109,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,252,109,109,109,109,109,109,109,108,108,108,108,109,108,109,109,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,109,110,109,110,109,110,109,110,109,110,109,252,252,252,252,110,252,110,109,109,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,109,252,109,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,108,109,109,109,252,109,252,109,252,109,109,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,108,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,109,109,109,252,109,252,109,108,108,108,108,108,109,108,109,108,109,109,109,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,110,252,110,109,110,109,110,252,110,252,110,252,110,109,110,109,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,109,108,109,108,252,108,252,109,109,109,109,109,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,109,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,252,108,108,108,108,109,109,109,109,108,109,109,109,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,109,110,109,110,109,110,252,110,252,110,252,252,109,110,109,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,110,252,110,252,110,252,252,252,252,252,252,109,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,108,109,252,109,252,109,252,109,252,109,252,252,109,109,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,108,109,108,252,108,108,109,108,109,108,108,108,109,108,108,108,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,252,110,109,110,109,110,109,110,252,110,252,110,109,110,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,252,107,252,107,252,252,252,252,252,252,252,252,109,110,109,110,109,110,110,110,110,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,252,109,252,109,252,109,252,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,108,109,108,109,108,109,108,109,108,109,252,252,108,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,108,252,252,108,252,108,108,108,108,108,109,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,109,110,109,110,109,110,252,110,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,109,107,109,107,252,252,252,107,252,107,252,107,109,252,109,252,109,252,109,110,109,109,109,109,109,110,110,110,109,252,252,252,252,252,252,252,252,252,109,252,109,252,110,252,110,252,110,252,252,252,110,252,252,252,252,109,252,109,109,109,109,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,109,252,109,252,109,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,107,252,109,109,108,109,252,109,252,109,252,109,252,109,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,108,109,108,108,108,252,108,252,108,252,108,108,108,108,108,108,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,110,252,110,109,110,109,109,109,109,109,110,109,109,109,110,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,252,109,107,107,252,107,252,107,252,107,252,107,252,107,252,107,107,106,106,106,18,18,18,252,109,110,109,110,109,110,109,109,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,108,252,108,109,108,109,108,109,108,109,108,109,252,109,108,109,109,109,109,109,109,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,252,252,252,252,109,108,108,108,108,108,108,108,108,108,108,252,108,252,108,252,252,108,252,18,18,18,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,110,109,110,109,110,109,109,109,109,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,107,107,107,107,107,107,252,107,252,107,252,252,252,107,107,106,106,106,18,18,17,18,18,18,17,18,18,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,252,252,252,110,252,252,109,252,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,109,252,109,109,109,109,109,109,110,109,110,252,252,252,252,252,252,252,252,109,252,109,252,109,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,107,252,108,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,252,108,109,108,109,252,109,109,108,252,108,252,108,252,108,252,108,252,108,252,108,252,252,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,252,110,109,110,109,109,109,109,109,109,109,110,109,110,252,252,252,252,252,252,252,252,252,252,109,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,107,252,107,252,107,252,107,252,107,109,107,109,107,106,106,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,110,109,110,109,110,109,110,109,110,109,110,252,110,109,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,109,108,109,108,109,108,109,108,109,108,109,108,109,252,109,108,109,109,109,108,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,108,108,108,108,108,108,108,108,108,252,108,108,108,252,109,252,108,252,252,252,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,109,110,109,109,109,109,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,109,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,107,107,107,107,107,107,252,107,252,107,109,252,106,106,106,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,252,110,252,109,252,109,252,252,252,252,252,109,252,252,252,252,109,252,109,109,109,109,109,110,110,110,110,252,252,252,252,109,252,252,252,109,252,109,252,110,252,110,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,108,109,108,109,252,109,108,109,252,109,108,109,252,109,108,109,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,109,107,109,107,252,107,109,107,252,107,252,109,252,107,252,109,252,107,252,252,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,109,110,109,109,109,109,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,110,109,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,107,252,107,252,107,252,107,109,106,106,106,106,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,110,109,110,109,110,109,110,109,110,109,110,252,110,110,110,252,110,109,252,109,252,252,252,252,252,109,252,252,252,252,109,252,109,252,109,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,109,107,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,107,252,252,109,109,109,109,109,109,109,109,109,109,109,109,109,109,252,109,252,252,252,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,110,109,109,109,109,109,110,109,110,109,110,109,252,252,252,252,252,252,252,109,110,109,110,109,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,109,107,107,107,107,107,107,252,107,106,106,106,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,110,109,110,109,110,109,110,109,110,109,109,109,110,109,252,109,252,252,252,252,252,109,252,252,252,252,109,252,109,109,109,109,109,109,110,110,110,109,252,252,252,109,252,109,252,109,252,110,252,110,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,108,109,108,109,108,109,252,109,252,109,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,108,252,108,252,107,252,107,252,107,109,107,109,107,252,107,109,107,252,107,252,107,252,107,109,109,109,252,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,110,109,109,109,109,109,110,109,110,109,110,109,252,252,252,252,252,252,252,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,252,107,252,107,252,106,106,106,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,110,109,110,109,110,109,110,109,110,252,110,109,252,252,252,252,252,252,252,109,252,252,109,252,109,252,109,109,109,109,110,109,110,109,110,252,252,109,252,252,252,252,109,252,109,252,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,252,108,252,252,252,108,252,252,252,108,108,252,108,252,108,252,108,252,108,252,109,109,107,252,252,252,107,252,252,109,107,109,109,109,107,109,109,109,109,109,109,109,109,109,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,109,109,109,109,110,109,110,109,110,109,252,252,252,252,252,252,252,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,107,107,107,107,106,106,106,107,106,106,106,106,106,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,109,110,109,110,109,110,109,110,109,110,252,252,252,252,252,252,109,252,109,252,109,109,109,109,109,109,109,109,110,110,110,110,109,252,109,252,109,252,252,252,252,109,109,109,109,252,109,110,109,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,107,109,108,109,108,109,252,109,108,109,252,109,108,109,252,109,252,109,252,109,109,109,252,109,252,109,252,109,252,252,252,108,252,108,252,108,252,108,252,108,252,108,252,108,109,108,252,107,252,107,252,107,252,107,109,107,109,107,252,107,109,107,252,107,109,109,109,109,109,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,110,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,110,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,107,107,252,107,252,252,107,106,106,106,107,106,107,106,106,106,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,109,109,252,109,252,109,109,109,109,110,109,110,110,110,252,252,252,252,109,109,252,109,252,109,252,109,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,108,109,108,109,108,109,107,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,252,108,252,108,108,252,108,108,108,252,108,252,108,252,108,109,108,109,108,109,107,252,109,109,107,252,109,109,109,109,109,109,109,109,109,109,109,109,109,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,110,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,107,107,107,252,252,252,252,252,252,252,106,106,106,106,106,106,106,106,106,106,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,110,109,110,109,110,252,252,252,252,252,252,109,252,109,109,109,109,109,109,109,110,109,110,110,110,109,110,252,252,109,252,109,252,109,109,109,109,109,109,109,110,109,110,252,252,252,252,252,252,252,252,252,252,109,252,109,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,107,109,108,109,108,109,108,109,252,109,108,109,252,109,252,109,252,109,109,109,252,109,252,109,252,109,252,252,252,108,252,108,252,108,109,108,109,108,109,108,252,107,252,107,252,107,252,107,252,107,252,107,109,107,109,107,109,107,109,107,252,109,109,109,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,110,109,110,109,110,109,110,252,252,252,252,252,252,252,110,109,110,109,110,109,110,109,107,109,107,252,107,107,107,252,107,252,107,252,107,252,107,252,252,252,106,107,106,106,106,106,106,106,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,18,18,18,17,18,17,18,17,109,110,109,110,109,110,252,252,252,252,252,109,252,109,252,109,109,109,109,110,109,110,109,110,110,110,109,252,252,252,252,109,252,109,252,109,109,109,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,107,109,107,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,252,252,252,108,108,252,108,108,108,109,108,109,108,109,108,109,107,109,109,109,107,252,109,109,107,252,109,109,107,109,109,109,107,109,109,109,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,110,109,110,109,110,109,252,252,252,252,252,252,252,109,107,109,107,109,107,109,107,109,107,109,107,107,107,252,107,252,107,252,252,252,252,252,252,252,106,106,106,106,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,109,110,109,110,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,110,110,110,110,110,109,252,252,252,252,252,109,109,109,109,109,109,109,110,109,110,109,110,252,252,252,252,109,252,252,252,109,252,109,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,107,109,252,109,108,109,252,109,108,109,252,109,108,109,252,109,252,109,109,109,252,109,252,109,252,252,252,108,252,108,109,108,109,108,252,108,109,108,252,107,109,107,252,107,252,107,252,107,252,107,109,107,109,107,252,109,109,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,110,109,110,109,110,109,252,252,252,252,252,252,110,109,107,109,107,107,107,107,107,107,107,252,107,252,107,252,107,252,107,252,107,252,252,252,107,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,109,110,109,110,252,110,252,252,252,109,252,109,252,109,109,110,109,110,109,110,109,110,109,110,252,252,252,109,252,109,252,109,252,109,109,109,110,110,109,110,109,252,252,252,252,252,252,252,252,252,109,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,107,109,108,109,107,109,108,109,108,109,107,109,108,109,108,252,108,252,108,252,108,252,108,252,108,108,252,108,108,108,109,108,109,108,109,108,109,107,109,107,109,107,109,109,109,107,109,109,109,109,109,109,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,110,109,110,109,110,109,110,252,252,252,252,252,107,107,107,107,107,107,107,107,107,107,107,252,107,252,107,252,252,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,109,110,109,110,109,252,252,252,252,109,109,109,109,109,109,110,109,110,109,110,109,110,109,252,252,252,252,252,252,109,252,109,109,109,109,109,110,110,109,110,109,252,252,252,252,252,109,252,109,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,108,109,108,109,252,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,108,252,108,109,108,109,108,109,108,109,108,252,108,109,107,252,107,252,107,252,107,252,107,106,107,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,109,110,109,110,109,110,109,252,107,107,107,107,107,107,252,107,252,107,252,107,252,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,110,109,110,109,252,252,109,252,109,252,109,109,110,109,110,109,110,110,110,109,110,109,252,252,109,252,109,252,109,252,109,252,109,252,109,109,109,109,110,252,252,252,252,252,252,252,252,252,252,109,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,107,109,108,109,108,109,108,109,108,109,108,109,108,109,108,252,108,252,108,252,108,252,252,252,108,108,252,107,108,108,109,108,109,108,109,108,109,107,109,109,109,107,109,109,109,107,109,106,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,110,109,110,109,110,110,107,107,107,107,107,107,107,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,18,18,17,18,110,109,110,109,252,109,109,252,109,109,109,109,109,109,110,109,110,109,110,109,110,252,252,252,252,252,109,252,109,109,109,252,109,109,109,109,109,109,110,252,252,109,252,109,252,109,252,109,252,109,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,252,109,107,109,252,109,108,109,252,109,108,109,252,109,108,109,252,109,252,252,252,109,252,252,252,107,252,108,109,108,109,108,109,108,252,107,252,107,252,107,252,107,252,107,252,106,106,106,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,109,110,109,110,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,110,110,110,109,252,109,109,252,109,109,109,109,110,109,110,109,110,109,110,109,252,252,252,252,109,252,109,252,109,252,109,252,109,109,109,109,110,109,252,252,252,252,252,252,252,109,252,252,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,107,109,107,109,107,109,107,109,108,109,108,109,252,252,252,252,252,252,108,252,252,252,108,252,252,108,252,108,109,108,109,108,109,109,109,107,252,109,252,252,252,107,107,107,106,106,106,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,110,110,109,110,109,252,109,109,109,109,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,109,252,109,109,109,109,109,109,109,109,110,252,252,252,252,109,252,109,252,109,252,109,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,108,109,252,109,108,109,108,109,252,109,252,109,252,109,252,109,252,252,252,109,252,107,252,107,252,252,252,108,109,108,109,108,252,108,252,107,252,107,252,107,107,107,107,107,107,106,106,106,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,110,109,110,109,110,252,109,109,110,109,110,110,110,109,110,109,110,252,252,252,252,252,109,252,109,252,109,252,109,252,109,109,109,109,110,252,252,252,252,252,252,252,252,252,252,252,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,107,109,108,109,108,109,252,109,252,109,252,252,252,252,252,252,108,252,108,107,108,107,252,252,252,109,109,109,109,108,109,109,109,109,252,109,109,106,107,107,107,107,107,107,106,106,106,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,109,110,109,110,109,109,109,110,109,110,110,110,109,110,109,252,252,252,252,252,252,252,252,109,252,109,109,109,109,109,109,109,109,110,109,252,252,252,109,252,109,252,109,252,109,252,109,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,109,107,109,108,109,252,109,252,109,252,109,252,252,252,252,252,109,109,109,108,107,252,107,252,252,109,108,109,108,252,108,109,109,252,108,252,109,107,106,107,106,107,106,107,107,107,106,106,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,110,109,110,109,110,109,110,110,110,109,110,109,110,252,252,252,109,252,252,252,109,252,109,252,109,252,109,252,109,109,109,109,110,109,252,252,252,252,252,252,252,109,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,107,109,108,109,108,109,252,109,252,252,252,252,252,109,252,252,252,109,109,107,252,252,109,109,109,109,109,109,109,109,109,109,109,109,108,106,107,106,107,107,107,107,107,107,107,107,106,106,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,109,110,109,109,109,110,109,110,109,110,109,252,252,252,252,252,252,252,252,109,252,109,252,109,109,109,109,109,109,110,109,110,109,252,109,252,109,252,109,252,109,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,109,107,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,107,252,107,252,107,109,109,109,109,109,109,252,109,252,109,252,106,108,106,107,106,107,106,107,106,107,107,107,107,107,106,106,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,109,110,109,110,109,110,109,110,109,110,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,109,109,109,109,110,109,110,252,252,252,252,252,252,252,252,109,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,109,107,109,108,109,108,109,109,109,109,109,252,109,252,109,252,252,252,109,252,252,252,109,109,109,109,109,109,109,109,109,109,109,106,106,108,106,106,106,107,107,107,106,107,107,107,107,107,106,106,106,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,110,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,109,252,109,109,109,109,109,109,109,109,109,109,110,109,252,109,252,252,252,109,252,109,252,109,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,109,107,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,109,109,109,109,109,109,252,109,106,106,107,106,107,106,107,106,107,106,107,106,107,107,107,106,107,107,106,106,106,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,17,18,17,17,110,109,110,109,110,252,110,109,110,252,252,252,252,252,109,252,109,252,109,252,109,252,109,109,109,109,109,109,110,109,252,252,252,252,252,252,252,252,252,109,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,109,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,109,107,109,108,109,109,109,109,109,252,109,252,109,252,109,252,109,252,252,252,252,109,109,109,109,109,109,109,108,106,106,106,106,106,106,106,106,107,106,107,106,107,107,107,107,107,107,106,106,106,106,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,110,109,110,109,110,109,110,109,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,109,110,109,252,109,252,109,252,109,252,109,252,109,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,109,107,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,109,109,109,109,109,109,107,107,109,106,106,106,106,106,107,106,107,106,107,106,107,106,107,106,107,107,107,106,106,106,106,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,17,18,17,17,17,17,17,17,110,110,110,109,110,109,110,109,252,252,252,109,252,252,109,252,109,252,109,252,109,252,109,109,109,109,110,109,110,109,252,252,252,252,252,252,252,252,252,109,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,108,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,109,107,109,107,109,109,109,109,109,252,109,252,109,252,252,252,109,252,252,252,252,252,109,109,109,109,107,107,107,107,107,106,106,106,106,106,106,107,106,107,106,107,107,107,107,107,107,107,106,106,106,106,106,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,110,110,110,109,110,109,110,252,252,252,252,109,252,252,252,252,109,252,109,109,109,109,109,109,109,109,110,109,110,109,252,109,252,252,252,109,252,109,252,109,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,107,109,252,109,252,109,252,109,252,109,252,109,252,109,252,107,252,109,252,109,252,252,109,107,107,107,252,107,107,107,252,106,106,106,107,106,107,106,107,106,107,106,107,106,107,107,107,106,106,106,106,106,106,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,110,110,110,109,110,252,110,109,252,252,110,252,252,252,109,252,109,252,109,109,109,252,109,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,109,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,109,107,109,107,109,109,109,109,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,109,107,107,107,252,107,109,109,107,107,106,106,106,106,106,106,107,106,107,107,107,107,107,107,107,106,106,106,106,106,106,106,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,110,110,110,110,109,110,109,252,109,110,109,252,252,252,252,109,109,109,252,109,109,109,110,110,109,110,109,110,252,252,109,252,109,252,109,252,109,252,109,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,109,107,109,252,109,252,109,252,109,252,109,252,109,252,109,252,107,252,109,252,109,252,252,107,107,109,107,252,107,252,107,252,107,252,106,106,106,107,106,107,106,107,106,107,106,107,107,107,106,106,106,106,106,106,106,106,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,17,16,17,17,17,17,17,17,110,110,110,110,110,110,109,110,109,110,109,110,252,109,252,109,252,109,109,109,109,110,109,110,109,110,109,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,109,107,109,107,109,252,109,107,109,252,109,252,109,252,252,252,109,252,252,252,252,107,107,107,107,109,109,109,109,252,109,252,107,109,252,106,106,106,106,106,106,107,107,107,107,107,107,107,106,107,106,106,106,106,106,106,106,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,110,110,110,109,110,109,110,109,110,109,110,109,252,252,109,109,109,109,110,110,110,109,110,109,110,252,252,252,252,252,252,252,252,109,252,109,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,107,109,252,109,252,109,252,109,252,109,252,109,252,109,252,107,252,252,252,109,107,107,252,107,252,107,252,107,109,109,252,109,109,107,252,107,106,106,107,106,107,106,107,106,107,107,107,106,107,106,106,106,106,106,106,106,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,110,110,110,109,110,109,110,109,110,109,110,109,252,109,252,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,109,107,109,107,109,107,109,252,109,252,109,252,252,252,252,252,252,252,107,107,107,107,107,252,107,252,107,252,252,252,252,252,252,109,109,252,106,106,106,106,106,107,107,107,107,107,106,107,106,107,106,106,106,106,106,106,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,110,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,252,109,110,109,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,107,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,107,107,107,252,107,252,107,252,107,252,107,252,107,252,252,252,107,109,107,106,106,107,106,107,106,107,107,107,106,107,106,107,106,106,106,107,106,106,106,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,110,110,110,109,110,109,110,252,110,109,110,109,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,109,252,109,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,109,109,109,109,109,109,109,107,109,252,109,252,109,252,252,252,252,252,252,252,107,107,107,107,107,252,107,107,107,252,252,252,252,252,252,252,252,252,252,109,109,106,106,106,106,107,107,107,106,107,106,107,106,107,106,106,106,106,106,106,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,17,16,17,17,110,110,109,110,109,110,109,110,109,110,109,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,110,252,110,252,109,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,107,107,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,252,252,107,109,109,106,106,107,107,107,106,107,106,107,106,107,106,106,106,106,106,106,106,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,109,110,109,110,109,110,109,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,109,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,109,108,109,109,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,107,252,107,252,107,252,252,252,252,252,252,252,252,252,252,109,106,252,106,107,106,107,106,107,106,107,106,107,106,106,106,106,106,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,109,110,109,110,109,110,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,109,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,107,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,252,109,252,252,107,252,107,252,109,107,106,107,106,106,107,107,106,107,106,106,106,106,106,106,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,110,109,110,109,110,109,110,109,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,252,109,109,109,109,109,109,109,109,252,109,252,109,252,252,252,109,252,252,252,252,107,107,107,107,107,107,107,107,252,107,252,107,252,252,252,252,252,109,109,109,252,252,252,252,252,252,252,107,107,106,107,106,107,107,107,106,106,106,106,106,106,106,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,109,110,109,110,109,110,109,110,109,110,109,110,109,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,109,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,110,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,109,109,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,107,107,252,107,107,107,252,107,252,107,252,107,252,107,252,107,252,109,252,107,252,252,252,107,252,252,252,252,252,106,107,106,106,107,107,106,107,106,107,106,106,106,106,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,109,110,109,110,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,252,107,109,107,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,107,252,107,252,107,252,107,252,252,109,109,109,109,252,252,252,252,252,252,252,252,252,107,107,106,107,106,107,106,107,106,106,106,106,106,106,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,110,109,110,109,110,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,107,107,107,107,107,252,107,252,107,252,107,252,107,252,107,107,107,252,107,252,109,252,109,252,107,252,107,252,252,252,107,107,106,107,106,107,106,106,106,106,106,107,106,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,109,110,109,110,109,110,109,110,252,109,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,109,109,107,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,107,107,107,107,107,107,107,107,107,107,252,107,107,107,109,109,109,109,252,109,252,109,252,252,107,107,252,252,252,107,107,107,107,106,107,106,107,106,106,106,106,106,106,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,109,110,109,110,109,110,109,110,109,109,109,109,252,110,252,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,110,252,110,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,107,107,107,107,252,107,252,107,252,107,107,107,252,107,109,107,252,107,252,109,252,107,252,109,252,107,252,107,252,252,252,107,107,252,107,106,107,106,106,106,107,106,106,106,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,16,17,110,109,110,109,110,109,110,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,109,107,109,109,109,252,109,252,109,252,252,252,252,252,252,252,107,107,107,107,107,107,107,107,107,107,107,252,107,109,109,109,109,109,109,252,109,252,252,252,252,107,107,252,107,252,252,252,107,107,107,107,106,107,106,106,106,106,106,106,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,110,109,110,109,110,109,110,109,109,109,109,109,109,109,109,252,252,252,252,252,252,110,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,109,109,252,109,107,109,252,109,252,109,252,109,252,109,252,109,252,252,252,107,107,107,252,107,107,252,252,252,252,252,109,109,109,109,252,109,107,107,252,107,252,109,252,109,252,252,107,107,252,107,252,252,252,107,252,107,107,106,106,106,106,106,106,106,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,16,17,16,17,16,16,16,17,110,109,110,109,110,109,110,252,110,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,110,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,107,252,252,252,252,252,252,252,109,109,109,109,109,109,107,109,252,109,252,252,252,252,252,252,252,252,252,252,107,252,107,252,107,252,252,109,109,109,109,109,109,109,252,109,107,107,252,252,252,109,252,252,252,107,107,107,107,107,252,252,252,107,252,107,107,106,106,106,106,106,106,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,110,109,110,109,110,109,110,109,110,109,110,252,109,109,109,252,109,109,252,252,252,109,252,252,252,252,252,252,252,110,252,109,252,109,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,108,109,252,252,252,252,252,252,252,107,252,252,252,252,252,252,252,252,109,109,252,109,109,109,252,109,252,109,252,109,252,107,252,109,252,252,252,109,252,107,252,107,252,107,252,107,109,109,109,107,107,106,106,106,106,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,16,16,17,16,109,110,109,110,109,110,252,110,252,110,252,110,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,252,109,252,252,252,252,252,252,107,252,252,252,107,252,107,252,107,109,109,109,109,109,109,109,109,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,107,107,107,107,107,109,107,109,107,109,109,107,106,107,106,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,252,110,110,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,109,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,107,252,252,252,252,109,252,109,108,109,252,252,252,252,107,252,252,252,107,252,252,252,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,107,107,107,109,107,109,107,109,107,109,109,107,106,107,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,109,110,109,110,109,110,252,110,252,110,252,110,252,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,252,107,252,107,109,107,109,109,109,109,109,109,109,109,109,252,109,109,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,109,109,109,109,106,107,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,109,110,109,110,109,110,109,110,109,110,109,110,252,110,109,110,252,110,110,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,252,252,109,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,109,109,109,109,109,109,109,109,109,109,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,110,109,110,109,110,109,110,252,110,252,110,252,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,109,109,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,252,109,109,109,109,109,109,109,109,109,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,109,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,252,252,110,252,110,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,109,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,109,109,109,109,109,109,109,109,109,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,109,110,109,110,109,110,252,110,252,110,252,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,108,252,252,252,252,252,252,252,252,252,109,109,108,109,252,109,109,109,252,252,252,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,109,109,252,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,109,110,109,110,109,110,109,110,109,110,252,110,109,110,252,252,109,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,252,109,252,109,252,109,252,109,252,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,252,109,109,109,109,109,109,109,109,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,110,109,110,109,110,109,110,109,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,15,16,16,16,16,16,16,16,110,109,110,109,110,109,110,109,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,109,109,109,109,109,109,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,110,109,110,109,110,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,252,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,109,252,109,109,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,16,15,16,16,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,109,109,109,109,109,109,109,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,109,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,110,109,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,109,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,109,109,109,109,109,109,109,109,109,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,108,109,252,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,108,108,109,109,109,109,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,109,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,109,252,109,252,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,109,108,109,108,109,109,109,109,109,109,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,109,110,109,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,109,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,109,109,109,109,109,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,109,110,109,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,109,109,109,252,109,252,109,252,252,252,252,252,252,252,108,107,107,109,107,109,107,109,109,109,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,110,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,252,109,252,252,252,252,252,252,252,108,108,107,107,107,109,109,109,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,110,109,110,109,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,109,252,252,252,252,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,108,108,108,109,107,109,107,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,16,15,15,15,109,110,109,110,109,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,109 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,252,252,252,252,252,252,108,108,108,108,108,109,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,109,252,252,252,252,252,252,107,107,109,107,109,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,110,109,110,109,110,109,110,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,109,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,252,252,252,252,252,108,108,107,107,107,107,107,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,110,109,110,109,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,109,252,109,252,108,252,108,252,107,109,107,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,15,15,15,14,15,15,15,15,109,110,109,110,252,110,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,252,109,252,252,252,107,107,107,107,107,107,107,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,109,110,109,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,109,252,109,252,107,107,107,252,107,252,107,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,14,15,15,15,14,15,14,15,110,109,110,109,109,252,109,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,109,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,252,107,107,107,107,107,107,107,252,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,107,107,107,107,107,107,107,252,106,107,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,109,110,252,109,252,109,252,252,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,107,107,107,107,107,107,107,106,107,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,252,252,109,109,109,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,252,107,252,107,252,106,107,106,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,110,110,109,109,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,107,106,107,107,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,15,15,15,14,110,110,109,109,109,109,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,107,252,107,252,107,106,106,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,15,252,110,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,107,107,107,107,107,107,107,107,106,106,107,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,110,109,110,109,109,109,109,252,110,252,109,110,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,252,109,107,107,107,107,109,107,107,109,252,106,107,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,109,110,252,110,252,109,252,109,109,110,252,110,110,110,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,109,109,109,107,107,107,107,107,107,109,107,109,106,106,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,15,14,14,14,14,110,109,110,109,110,109,109,252,252,109,109,109,110,110,110,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,109,107,107,109,107,107,107,109,107,109,107,106,106,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,252,110,109,110,252,109,252,109,252,109,109,110,109,110,110,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,109,109,109,109,107,107,107,107,107,107,107,107,107,106,106,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,110,110,109,110,109,110,109,252,252,109,109,109,110,110,110,110,252,109,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,109,109,107,107,107,107,107,109,107,109,107,109,106,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,110,109,110,252,110,252,252,252,109,252,109,109,110,110,110,252,109,109,109,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,109,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,109,109,109,107,107,107,107,107,107,107,107,107,107,106,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,110,110,109,110,109,252,252,252,252,109,109,109,109,110,110,109,252,109,109,109,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,107,109,109,109,107,107,107,109,107,107,107,109,107,106,106,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,14,14,15,14,15,14,15,14,110,110,252,110,252,110,252,109,252,109,252,109,109,109,109,110,252,109,252,109,252,109,109,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,109,109,109,109,107,107,107,107,107,107,107,107,107,109,106,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,110,109,110,109,110,109,252,252,252,252,109,109,109,109,110,110,110,252,109,109,109,109,109,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,109,109,109,109,107,107,109,107,107,107,109,107,109,107,106,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,15,14,14,14,110,110,252,110,252,110,252,109,252,109,252,109,252,109,110,110,252,109,252,109,109,109,109,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,109,109,109,109,107,107,107,107,107,107,107,109,106,106,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,110,109,110,109,110,252,252,252,109,252,109,109,109,109,110,252,110,252,109,109,109,109,109,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,109,109,109,109,109,109,107,107,107,107,109,107,109,106,106,106,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,110,110,252,110,252,110,252,252,252,109,252,109,252,109,109,110,252,110,252,109,109,109,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,109,109,109,109,109,107,107,107,107,107,107,107,106,106,106,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,110,109,110,109,110,109,110,252,252,252,109,252,109,109,109,110,110,109,110,109,109,109,109,109,109 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,109,107,109,109,109,109,109,107,107,107,109,107,109,106,107,106,106,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,110,252,110,252,110,252,110,252,252,252,109,252,109,252,109,109,110,110,110,252,110,252,109,109,109,109 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,109,109,109,109,109,109,109,107,107,107,107,107,106,106,106,106,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,110,110,109,110,109,110,252,110,109,252,252,109,252,109,109,109,109,110,252,110,109,110,109,109,109,109 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,108,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,109,107,109,109,109,109,109,109,109,107,109,107,107,106,107,106,106,106,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,110,109,110,252,110,252,110,252,252,252,109,109,109,252,109,252,109,110,110,252,110,252,110,252,109,109 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,109,108,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,109,109,109,109,109,109,109,109,109,107,107,107,106,106,106,106,106,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,110,109,110,109,110,109,110,109,252,109,109,109,109,252,252,252,109,109,109,252,110,252,252,109,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,109,107,109,109,109,109,109,109,109,109,109,107,107,106,107,106,107,106,106,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,109,110,109,110,109,110,252,110,252,109,252,109,109,110,109,252,252,109,109,252,252,252,252,252,109,252,109 +,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,109,109,109,109,109,109,109,109,109,109,109,107,107,106,106,106,106,106,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,14,14,13,14,110,109,110,109,110,109,110,109,252,109,109,109,109,110,110,109,110,110,252,252,252,252,252,252,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,107,109,107,109,107,109,109,109,109,109,109,109,109,109,109,106,106,106,106,106,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,109,110,109,110,252,110,109,252,252,109,252,109,109,110,110,252,252,252,252,252,252,252,252,252,252,252,109 +,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,108,108,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,109,109,109,109,109,109,109,109,109,109,109,109,109,109,107,106,106,106,106,106,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,13,14,14,14,13,14,13,14,110,109,110,109,110,109,252,109,252,109,109,109,109,110,110,110,252,252,252,252,252,109,252,252,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,108,252,108,252,108,252,252,252,252,252,108,252,108,252,108,252,252,252,252,107,107,252,107,109,107,109,107,109,107,109,109,109,109,109,109,107,107,109,109,109,107,106,106,106,106,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,110,109,110,109,110,252,109,252,109,252,109,109,109,110,252,252,252,252,252,252,252,252,252,252,252,109 +,252,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,108,252,108,252,108,108,108,108,108,252,108,108,108,252,252,252,107,252,252,107,107,107,107,107,107,109,109,109,109,109,109,109,109,107,107,107,107,109,107,107,107,106,106,106,106,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,110,109,110,109,252,109,252,109,252,109,110,110,252,252,252,252,252,252,252,109,252,109,252,109,252 +,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,108,252,108,252,108,108,108,252,108,108,108,252,107,252,107,252,107,252,107,107,107,107,107,109,107,109,107,109,107,109,109,109,109,107,107,109,107,109,107,109,107,109,106,106,106,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,110,252,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,252,252,108,108,108,108,108,108,108,108,107,107,252,107,252,107,252,107,107,107,107,107,107,107,109,107,109,109,109,109,109,109,109,107,107,107,109,107,107,107,107,106,106,106,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,13,14,13,13,13,14,13,14,110,109,110,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,108,108,108,108,108,252,108,252,108,252,107,252,107,252,107,252,107,252,107,252,107,109,107,109,107,109,107,109,107,109,109,109,107,109,107,109,107,109,107,109,107,106,106,106,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109 +,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,108,108,108,108,108,108,108,108,108,107,107,252,107,107,107,252,107,252,107,252,252,107,107,107,107,107,107,109,109,109,109,109,109,107,107,109,107,107,107,107,107,106,106,106,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,109,110,109,110,109,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252 +,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,252,108,108,108,252,107,252,107,252,107,252,107,252,107,252,107,252,107,107,107,109,107,109,107,109,107,109,109,109,109,109,107,109,107,107,107,106,106,106,106,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,109,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109 +,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,108,108,108,108,108,108,107,107,107,107,107,252,107,252,107,252,107,252,107,252,109,109,109,109,109,107,107,109,109,109,109,109,109,107,107,107,107,107,106,106,106,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,110,109,110,109,110,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252 +,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,108,108,108,108,252,108,252,108,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,109,107,109,107,109,107,109,107,109,109,109,109,109,109,109,106,109,106,106,106,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,252,109,252,108,108,108,108,108,108,108,108,108,107,107,107,107,252,107,107,107,252,107,252,107,252,252,252,109,109,109,109,109,109,109,109,109,109,109,109,109,108,106,108,106,106,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,109,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,109,252,252,252 +,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,109,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,252,108,252,252,108,108,108,108,108,108,252,108,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,109,107,109,107,109,109,109,107,109,109,109,109,107,106,107,106,106,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,14,13,13,13,109,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,109,252,252 +,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,108,108,252,252,252,108,108,108,108,108,108,108,108,107,107,107,107,107,252,107,252,107,252,107,252,252,252,109,109,109,109,109,109,109,109,109,109,109,109,107,107,107,107,106,106,106,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,109,108,252,108,252,108,252,252,108,108,108,108,252,108,252,108,252,107,252,107,252,107,252,107,252,107,252,107,252,107,109,107,109,107,109,109,109,109,109,109,107,107,107,107,107,106,107,106,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,110,109,110,252,110,252,252,252,252,252,252,252,252,252,252,109,252,252 +,252,252,252,252,108,252,109,252,252,252,252,252,109,252,109,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,108,108,109,108,252,252,252,108,108,108,108,108,108,108,107,107,252,107,107,107,252,107,252,107,252,252,109,107,109,109,109,109,109,109,109,109,109,109,109,107,107,107,107,107,106,106,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,109,110,109,110,109,110,252,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,108,108,252,108,252,108,252,109,252,252,108,108,252,108,108,108,252,107,252,107,252,107,252,107,252,107,252,107,109,107,109,107,109,107,109,109,109,109,109,109,107,107,107,107,107,107,106,106,106,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,109,110,252,110,252,110,252,252,252,252,252,252,252,252,252,252,252 +,252,252,252,252,108,252,252,252,252,252,252,252,109,252,109,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,252,108,109,109,252,252,252,108,108,108,108,108,107,107,107,107,107,107,252,107,109,107,109,107,109,109,109,109,109,109,109,109,109,109,109,109,109,109,107,107,107,107,107,106,106,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,110,109,110,252,110,252,110,252,252,252,252,252,252,109,252,252,252 +,252,252,252,108,252,252,252,252,252,252,252,109,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,108,108,252,108,252,108,109,108,252,109,252,252,108,108,108,107,252,107,252,107,252,107,252,107,109,107,109,107,109,107,109,107,109,107,109,109,109,109,109,109,109,109,107,107,107,106,107,106,106,106,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,110,109,110,252,110,252,110,252,252,252,252,252,252,252,252,252 +,252,252,108,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,108,108,108,109,109,109,109,252,252,252,108,108,108,107,107,107,107,107,107,252,107,107,107,109,109,109,107,109,109,109,109,109,109,109,109,109,109,109,109,109,107,107,106,107,106,106,106,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,110,109,110,252,110,252,110,252,252,252,252,252,252,252,252 +,252,252,252,108,252,252,252,252,252,252,252,109,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,108,108,252,108,109,108,252,108,252,252,252,252,108,108,252,107,107,107,252,107,252,107,109,107,109,107,109,107,109,107,109,107,109,109,109,107,109,109,109,109,109,107,107,106,107,106,106,106,106,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,110,252,110,252,110,252,110,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,108,108,109,109,109,109,252,252,252,252,252,108,108,108,107,107,107,107,107,107,107,107,109,107,109,107,109,109,109,109,109,109,109,109,109,109,109,109,109,107,107,106,107,106,106,106,106,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,12,13,13,13,13,13,109,252,110,252,110,252,252,252,252,252,252,252,252 +,252,252,252,108,252,252,252,252,252,252,252,109,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,109,252,252,252,108,252,108,252,109,252,252,252,252,108,108,108,107,252,107,252,107,109,107,109,107,109,107,109,107,109,107,109,107,109,109,109,109,109,109,109,107,107,106,107,106,107,106,106,106,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,109,252,110,252,110,252,109,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,108,252,108,109,108,109,252,109,109,108,252,252,252,252,252,252,252,108,108,108,107,107,107,107,107,107,109,107,109,107,109,109,109,107,109,109,109,109,109,109,109,109,109,107,107,106,107,106,107,106,106,106,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,13,13,12,13,109,252,110,252,252,252,252,252,252,252,252 +,252,252,252,108,252,252,252,252,252,252,252,109,252,252,252,108,252,252,252,252,252,252,109,252,252,252,109,252,252,252,252,252,252,108,252,108,252,109,109,252,109,252,108,252,108,252,108,252,252,252,252,252,108,252,107,107,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,109,109,109,109,106,107,109,106,107,106,107,106,106,106,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,252,110,252,110,252,110,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,109,252,252,109,108,252,109,252,252,252,252,252,252,252,252,108,108,107,107,107,107,107,107,107,107,109,107,109,107,109,109,109,109,109,109,109,107,109,107,107,106,107,106,107,106,106,106,106,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,252,110,252,252,252,252,252,252,252,252 +,252,252,252,108,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,252,252,252,109,252,108,252,108,252,252,252,252,252,252,252,108,108,107,252,107,109,107,109,107,109,107,109,107,109,107,109,107,109,109,109,107,109,107,107,106,107,106,107,106,106,106,106,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,252,110,252,109,252,109,252,252,109 +,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,108,107,107,107,107,107,107,107,109,107,109,107,106,107,106,107,109,107,109,107,109,107,109,107,107,106,107,106,106,106,106,106,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,110,252,252,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,109,109,252,109,252,109,252,108,252,252,252,108,252,252,252,252,252,107,107,107,107,107,109,107,109,107,107,107,107,107,109,107,109,107,109,107,109,107,109,107,107,106,107,106,106,106,106,106,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,109,110,252,110,252,252,252,109,252 +,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,109,109,107,109,107,107,107,107,107,106,107,109,107,109,107,109,107,107,109,107,106,107,106,106,106,106,106,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,109,110,252,252,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,252,109,252,109,252,109,252,109,252,109,252,107,252,252,252,252,252,252,107,107,252,107,109,109,109,107,107,107,109,107,109,107,109,107,109,107,109,107,107,107,107,106,107,106,106,106,106,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,252,110,252,109,252,252,252 +,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,109,109,107,107,107,107,107,107,107,109,107,109,107,109,107,106,106,107,107,107,106,106,106,106,106,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,252,110,252,252,252,252 +,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,107,107,252,107,109,109,107,107,107,107,109,107,109,107,109,107,109,107,107,106,107,107,107,107,107,106,106,106,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,12,12,13,12,252,110,252,109,252 +,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,109,109,107,107,107,107,107,109,107,109,107,109,107,106,106,107,107,107,107,107,106,106,106,106,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,110,252,252,252,252 +,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,107,252,107,109,107,109,109,107,107,109,107,109,107,109,107,109,107,107,106,107,106,107,107,107,107,106,106,106,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,214,214,201,201,216,12,12,12,12,12,12,12,12,12,12,110,252,252,252 +,252,252,108,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,108,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,109,109,107,107,107,109,107,109,107,109,107,106,106,107,106,107,106,107,107,107,106,106,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,202,202,202,214,201,201,216,216,216,216,216,216,216,12,12,12,12,12,252,252,252 +,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,108,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,107,107,107,252,107,107,107,109,107,109,107,109,107,109,107,109,107,109,107,109,106,107,106,107,106,107,107,107,107,106,106,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,202,202,202,202,203,214,201,201,201,216,216,216,216,216,216,216,216,216,12,252,110,252 +,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,107,107,107,109,107,106,107,109,107,109,107,109,107,109,106,107,106,107,107,107,107,107,106,107,106,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,202,202,202,202,202,203,202,202,214,214,201,201,216,216,216,216,216,216,216,216,216,216,252,252 +,252,108,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,107,252,107,109,107,107,107,109,107,106,107,109,107,109,107,109,107,109,106,107,106,107,106,107,106,107,107,107,106,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,202,202,202,202,202,203,202,202,202,203,202,214,201,201,216,216,216,216,216,216,216,216,216,216,252 +,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,108,109,108,109,108,109,252,252,252,109,252,252,252,252,252,252,252,252,252,107,252,107,109,109,109,109,109,107,106,107,106,107,109,107,109,107,109,106,107,106,107,106,107,107,107,107,107,106,106,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,202,202,202,202,202,203,202,202,202,203,202,203,203,214,201,216,216,216,216,216,216,216,216,216,216,252 +,252,108,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,107,252,107,109,107,109,109,106,107,109,107,109,107,109,107,109,106,107,106,107,106,107,107,107,107,107,106,106,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,202,202,202,202,202,202,203,202,202,202,203,202,203,203,203,214,201,201,216,201,216,216,216,216,216,216,216,216 +,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,108,252,252,252,108,109,108,109,108,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,107,252,109,109,109,109,109,106,107,106,107,109,107,109,107,109,106,106,106,107,106,107,107,107,107,106,106,106,106,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,202,202,202,202,203,203,203,203,202,202,202,202,203,202,203,202,214,201,201,216,214,201,216,201,216,216,216,216,216 +,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,108,252,252,252,252,252,108,109,108,109,108,109,252,109,252,109,252,109,252,109,252,252,252,252,252,107,252,252,252,109,109,107,109,109,109,107,109,107,109,107,109,107,107,106,107,106,107,106,107,107,107,107,106,106,106,106,106,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,202,202,202,202,203,203,202,202,203,202,202,202,202,203,203,203,203,202,202,214,201,216,214,214,201,216,201,216,216,216,216 +,108,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,108,252,252,252,252,252,252,252,108,109,108,109,109,109,109,109,252,252,252,252,252,252,252,252,252,252,107,107,106,107,109,107,109,106,106,106,106,107,109,107,109,106,106,106,107,106,107,106,107,107,107,107,106,106,106,106,106,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,12,12,12,12,12,12,12,11,202,203,203,203,202,202,202,202,203,203,203,202,202,202,203,203,203,202,202,202,214,201,214,214,214,214,201,216,201,216,216,216 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,109,108,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,107,107,107,109,107,109,107,107,106,107,107,109,107,109,106,106,106,107,106,107,106,107,107,107,107,107,106,106,106,106,106,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,202,202,202,203,202,202,202,203,202,203,202,203,202,202,202,203,202,203,202,203,202,203,214,201,214,204,203,214,201,201,216,201,216,216 +,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,108,252,252,252,252,252,252,252,108,109,109,109,109,109,252,109,252,252,252,252,252,252,252,252,107,107,252,107,109,107,109,107,109,106,107,106,107,106,107,107,107,107,107,106,106,106,107,107,107,106,107,106,106,106,106,106,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,203,202,203,203,202,202,202,202,202,202,203,203,202,202,202,202,203,202,203,203,202,202,203,202,203,214,214,203,204,204,214,201,201,216,201,216 +,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,108,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,109,252,252,252,252,252,252,107,107,252,107,109,107,109,107,109,107,107,106,107,106,107,106,107,106,107,106,107,106,107,106,107,106,107,106,106,106,106,106,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,203,202,203,202,202,202,202,202,203,202,203,202,203,202,202,204,203,202,203,202,203,203,203,202,203,202,203,202,214,203,204,203,204,214,201,216,201,216,201 +,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,252,109,252,109,252,252,252,252,252,252,107,107,107,107,107,107,109,107,109,107,109,106,106,106,107,107,107,106,107,107,107,107,106,107,107,106,107,106,106,106,106,106,106,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,12,11,12,12,202,202,203,202,202,202,202,202,202,202,203,202,203,202,203,203,202,202,202,202,203,202,203,203,203,202,202,202,202,202,203,203,203,203,204,204,214,201,201,216,201,216 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,109,252,252,252,252,252,107,107,107,109,107,109,107,109,107,109,107,107,106,107,106,107,106,107,106,107,106,107,107,107,107,107,106,107,106,106,106,106,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,203,202,202,202,203,202,203,202,203,202,203,202,203,202,203,202,203,203,202,202,202,202,203,202,203,203,203,203,202,202,203,202,203,202,203,203,204,203,204,214,201,201,201,216,201 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,108,252,252,109,109,109,252,252,252,252,252,252,252,107,252,107,107,107,107,107,109,107,109,107,109,106,107,106,107,106,107,107,107,107,107,107,107,107,107,106,107,106,106,106,106,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,202,202,202,202,202,202,202,202,202,203,202,203,202,203,203,203,203,203,203,202,202,202,202,202,202,203,203,203,204,204,202,202,202,203,203,203,203,204,204,204,204,204,214,214,201,201,216 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,252,252,252,252,107,107,107,109,107,109,107,109,107,109,107,107,106,107,106,107,106,107,106,107,107,107,107,107,106,107,106,106,106,106,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,202,203,202,203,202,202,202,202,202,203,202,203,202,203,202,203,202,203,203,202,202,202,214,214,214,201,202,203,203,203,214,214,214,202,202,203,202,203,203,204,203,204,203,204,204,214,214,214,201,201 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,107,109,107,109,107,107,107,107,107,107,107,107,106,107,106,107,106,107,106,106,106,106,106,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,202,202,202,202,202,202,202,202,202,202,202,202,203,203,203,203,203,203,202,202,202,202,203,214,214,214,214,214,203,203,214,201,201,201,214,202,202,202,203,203,203,204,203,203,204,204,204,204,214,214,201,201 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,108,252,252,109,252,109,252,252,252,252,252,252,252,107,107,107,109,107,109,107,109,107,109,107,107,106,107,107,107,106,107,106,107,106,107,106,107,106,106,106,106,106,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,202,202,203,202,202,202,203,202,203,202,203,202,203,202,203,202,202,202,203,202,202,202,203,202,204,203,204,203,204,203,204,214,214,201,216,201,214,202,203,202,203,204,204,203,204,203,204,204,204,204,214,214,201 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,109,252,252,252,252,252,252,109,252,252,107,107,107,109,107,109,107,109,107,109,107,107,107,107,106,107,106,107,106,107,106,107,106,107,106,106,106,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,202,202,202,202,202,202,202,202,202,202,202,202,203,202,202,202,202,202,202,202,202,202,203,203,203,204,204,203,204,204,204,202,214,201,214,216,201,214,202,202,203,204,204,204,203,203,204,204,204,204,204,214,214,214 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,107,107,107,109,107,109,107,109,107,109,107,107,106,107,106,107,106,107,106,107,106,107,106,107,106,106,106,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,202,202,203,202,202,202,202,202,203,202,203,202,203,202,202,202,203,202,203,202,203,202,203,202,203,203,204,204,204,203,204,202,203,202,214,214,201,216,201,202,204,203,204,203,204,203,204,203,204,203,204,204,204,214,214 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,252,252,107,106,107,106,107,109,107,109,107,107,106,107,106,107,106,107,106,106,106,107,106,107,106,106,106,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,202,202,202,202,202,202,202,202,202,202,202,202,203,202,202,202,203,203,203,202,203,203,202,202,203,203,203,203,204,204,204,203,202,202,203,203,214,214,214,201,214,203,203,203,204,204,203,203,204,204,204,204,204,204,204,214 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,252,109,252,107,106,107,252,107,109,107,109,107,109,106,107,106,107,106,107,106,107,106,107,106,106,106,107,106,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,11,12,11,11,202,203,202,202,202,203,202,202,202,203,202,203,202,203,202,202,203,204,202,203,202,202,202,203,203,204,203,204,204,204,203,202,202,203,202,203,203,214,214,214,201,214,203,204,203,204,204,203,204,204,203,204,203,204,204,214 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,109,109,252,109,106,107,106,107,109,107,109,107,109,106,107,106,107,106,107,106,106,106,106,106,107,107,107,106,106,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,202,202,202,202,202,202,202,202,202,202,202,202,202,202,203,203,204,204,202,202,202,202,203,203,203,203,204,204,204,203,203,202,202,202,203,203,203,203,203,214,214,201,214,203,203,204,204,204,204,204,204,204,204,204,204,204 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,109,107,252,107,252,107,252,107,252,107,109,107,109,106,107,106,107,106,107,106,106,106,107,106,107,106,107,106,106,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,202,202,202,202,203,202,202,202,203,202,202,202,203,202,203,203,204,204,202,202,202,202,203,203,204,203,204,204,204,203,204,202,203,202,203,202,203,203,203,203,204,203,214,214,214,203,204,204,204,204,204,203,204,203,204,204,204 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,109,109,109,252,252,252,107,106,107,109,107,109,107,107,106,107,106,107,106,106,106,106,106,107,107,107,106,106,106,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,202,202,202,202,202,202,202,202,202,202,202,202,202,203,203,202,202,204,204,203,202,202,203,203,203,204,204,204,204,203,203,202,202,203,202,203,203,203,203,203,203,204,204,204,214,214,203,204,204,204,203,204,204,204,201,201,201 +,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,252,107,252,107,252,107,252,107,106,107,252,107,109,107,107,106,107,106,107,106,106,106,107,106,107,106,107,106,106,106,106,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,12,11,11,11,11,202,202,202,203,202,203,202,203,202,202,202,202,202,203,202,202,202,203,203,204,204,203,202,203,203,204,204,204,203,204,202,202,202,203,202,203,202,203,203,203,203,204,203,204,203,204,204,204,204,204,214,214,201,201,201,201,216,216 +,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,107,109,107,109,109,109,109,252,252,106,107,252,107,109,106,107,106,107,106,107,106,106,106,106,106,107,107,106,106,106,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,202,202,202,202,202,202,202,202,202,202,202,202,202,202,203,202,203,203,203,203,204,203,202,202,203,203,204,204,204,202,202,202,202,202,203,202,203,203,203,203,203,203,204,203,204,204,204,204,203,214,201,201,201,216,216,216,216,216 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,252,107,109,107,252,107,252,107,252,109,252,107,252,107,252,106,107,107,107,106,107,106,106,106,107,106,107,106,106,106,106,106,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,202,202,203,202,202,202,203,202,202,202,203,202,202,202,203,202,203,202,203,203,204,204,204,203,204,203,202,204,204,204,202,202,202,202,203,202,203,202,203,203,203,204,204,203,204,204,204,203,202,214,201,201,201,216,201,216,216,216,216 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,107,107,109,107,109,107,109,109,109,109,252,109,252,109,106,107,106,106,107,107,107,107,107,106,106,106,107,106,107,107,106,106,106,106,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,202,202,202,202,202,202,202,202,202,202,202,202,202,202,204,202,202,202,202,203,203,204,204,204,202,204,204,204,204,204,204,204,202,202,202,202,202,203,202,203,203,203,203,204,204,204,204,204,204,204,214,214,214,214,201,201,216,201,216,216,216 +,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,107,252,107,109,107,252,107,252,109,252,109,252,107,252,106,107,106,107,106,107,106,107,106,107,106,107,106,106,106,106,106,106,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,202,202,202,203,202,203,202,203,202,203,202,203,202,202,202,204,202,202,202,203,202,203,203,204,202,204,203,204,203,204,204,204,204,202,202,203,202,203,202,204,203,203,203,204,203,204,204,204,203,204,203,202,202,203,214,214,201,201,216,201,216,216 +,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,109,107,109,107,252,109,109,109,109,109,109,109,252,252,106,106,106,106,107,106,107,107,107,107,107,107,106,107,107,106,106,106,106,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,202,202,202,202,202,202,202,202,203,202,202,202,202,202,203,204,202,202,203,203,203,203,204,204,202,203,204,204,204,204,204,204,204,202,202,202,203,202,203,204,203,203,203,203,204,204,204,204,204,203,202,202,203,203,203,203,214,201,201,216,201,216 +,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,108,108,108,108,108,252,107,109,107,252,107,252,107,109,107,109,107,252,107,252,109,252,109,107,106,107,106,107,106,107,106,107,107,107,106,107,106,106,106,106,106,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,202,202,202,203,202,203,202,203,202,202,202,202,202,202,203,204,202,203,202,203,203,204,203,204,202,203,204,204,204,204,204,204,202,202,202,202,202,203,203,204,203,203,203,204,203,204,204,204,203,202,202,203,202,203,203,204,214,201,201,216,216,201 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,108,109,107,107,107,109,107,109,107,109,109,109,109,252,109,252,109,109,106,107,106,107,107,107,107,107,106,107,106,107,106,106,106,106,106,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,202,202,202,202,202,202,203,202,202,202,202,202,202,202,204,204,202,202,203,203,203,203,204,204,202,203,204,204,204,204,204,204,202,202,203,202,203,203,204,204,202,203,203,203,204,204,204,204,203,202,202,202,203,203,203,203,203,214,201,201,201,216 +,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,108,108,108,252,108,107,107,252,107,109,107,252,107,109,107,252,107,252,109,252,107,109,109,252,106,107,107,107,106,107,106,107,106,107,106,106,106,106,106,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,203,202,202,202,203,202,203,202,203,202,202,202,203,202,203,203,204,202,203,202,203,203,204,204,204,202,204,203,204,203,204,204,203,202,202,202,202,202,203,203,204,203,204,203,204,203,204,204,204,202,203,203,204,202,203,203,204,203,214,214,201,201,201 +,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,108,108,108,108,108,107,107,107,109,107,109,107,109,107,109,109,109,109,109,109,109,109,109,109,107,106,107,106,107,106,107,106,107,106,106,106,106,106,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,10,11,11,11,202,202,202,202,202,203,203,202,202,202,202,202,202,202,203,203,204,203,203,203,203,203,203,204,202,203,204,204,204,204,204,204,202,202,202,202,202,203,202,204,204,203,203,203,203,204,204,204,203,202,202,203,202,203,204,204,204,204,214,214,214,201,201 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,109,107,109,107,252,107,252,107,109,107,252,107,252,107,109,109,252,109,252,109,107,106,107,106,107,106,106,106,106,106,106,106,106,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,202,202,203,202,202,202,203,202,202,202,202,202,203,202,203,203,204,202,203,202,203,203,204,203,202,203,204,203,204,204,204,204,202,202,202,202,202,202,204,202,203,203,204,203,204,204,204,204,204,202,203,202,202,202,203,203,204,204,204,204,214,214,201 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,107,107,107,107,107,107,109,107,109,107,109,109,109,107,109,109,109,109,109,109,109,109,107,106,107,106,106,106,106,106,106,106,106,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,11,11,10,11,202,202,202,202,202,203,203,203,202,202,202,202,202,203,203,204,202,203,203,203,203,203,203,202,203,203,204,204,204,204,204,204,202,202,202,203,202,203,204,203,203,203,203,204,204,204,204,204,203,202,202,203,202,203,203,204,204,204,204,204,204,214,214 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,107,107,107,252,107,109,107,252,107,252,107,252,107,252,107,252,107,109,109,252,109,252,106,107,106,106,106,107,106,106,106,106,106,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,203,202,202,202,203,202,203,202,202,202,202,202,202,202,203,203,204,202,203,203,204,203,202,202,203,203,204,203,204,203,204,204,202,202,203,202,203,203,204,203,203,203,204,203,204,204,204,204,204,202,202,202,202,202,203,203,204,203,204,204,204,204,204 +,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,107,107,107,107,107,107,107,109,107,109,107,109,109,109,109,109,109,109,109,109,106,107,106,106,106,106,106,106,106,106,106,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,202,202,202,202,202,203,203,202,202,202,202,202,202,203,203,204,202,203,203,203,203,204,202,203,203,204,204,204,204,204,204,202,202,202,202,203,203,203,203,204,203,204,203,204,204,204,204,204,202,203,203,204,202,203,203,204,204,204,204,204,204,204,204 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,107,109,107,252,107,252,107,252,107,109,107,109,107,109,109,252,109,252,106,107,106,106,106,107,106,106,106,106,106,106,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,202,202,202,202,203,202,203,202,202,202,202,202,203,203,204,204,203,202,203,203,204,202,202,202,204,204,204,203,204,204,204,202,202,202,203,202,203,203,204,203,204,203,204,203,204,203,204,202,203,202,204,203,204,202,204,204,204,203,204,204,204,204,204 +,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,107,107,252,108,108,108,107,107,107,107,109,107,107,107,252,109,109,109,109,109,109,109,109,109,107,106,106,106,106,106,106,106,106,106,106,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,202,202,202,202,202,202,203,203,203,202,202,202,202,202,203,203,204,204,202,202,204,202,203,204,202,204,204,203,204,204,204,204,202,202,202,202,203,203,203,203,203,203,204,204,204,202,202,202,203,203,203,203,204,204,204,203,204,204,204,204,203,204,204,204 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,252,252,108,108,107,109,107,109,107,252,107,252,107,252,107,109,107,252,107,109,109,252,106,106,106,107,106,106,106,106,106,106,106,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,202,203,202,203,202,203,202,203,202,202,202,202,202,203,203,204,203,204,204,202,202,203,203,204,202,204,203,204,203,204,203,204,202,203,202,203,203,203,203,203,203,204,203,204,204,202,202,203,202,203,203,204,203,204,204,204,204,204,203,204,204,204,204,204 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,107,252,252,252,252,109,108,107,107,107,107,107,107,109,107,252,107,109,109,109,109,109,109,109,109,106,106,106,106,106,106,106,106,106,106,106,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,202,202,202,202,202,202,203,203,202,202,202,202,202,202,204,203,203,203,202,202,203,203,204,203,202,203,204,204,204,204,204,204,202,202,203,203,203,203,203,203,204,203,204,204,204,202,202,202,203,203,203,203,204,204,204,204,204,204,204,204,203,204,204,204 +,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,108,108,252,107,252,252,109,109,107,108,107,107,252,107,252,107,252,107,252,107,109,107,109,109,252,109,107,106,106,106,106,106,106,106,106,106,106,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,202,202,202,203,202,203,203,203,202,202,202,203,202,203,202,203,203,202,202,203,203,204,204,204,202,204,203,204,203,204,204,202,202,203,202,203,203,204,203,204,203,204,204,204,202,203,202,202,202,204,204,204,203,204,204,204,203,204,203,204,204,204,204,204 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,107,252,252,109,109,252,252,107,107,107,107,109,107,107,107,252,109,109,109,109,109,109,109,107,106,106,106,106,106,106,106,106,106,106,106,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,202,202,202,202,203,203,203,202,202,202,202,202,202,202,203,203,203,202,202,203,203,204,204,203,204,203,204,203,204,204,202,202,203,202,203,203,203,203,203,203,204,204,204,204,202,202,202,203,203,204,204,204,204,204,204,204,204,204,204,204,203,204,204,204 +,252,252,252,252,252,108,252,252,252,252,252,252,252,252,108,108,108,252,107,109,109,252,109,252,107,252,107,107,107,252,107,252,107,109,107,109,109,252,109,107,106,107,106,106,106,106,106,106,106,106,106,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,202,203,202,203,202,203,203,203,202,202,202,202,202,203,202,203,203,202,202,203,203,204,204,204,203,204,203,204,203,204,203,202,202,203,202,203,203,203,203,204,203,204,203,204,202,202,202,203,203,204,204,204,203,204,204,204,203,204,203,204,204,203,204,204 +,252,252,252,252,108,252,252,252,252,252,252,252,252,252,108,107,108,107,109,109,109,109,252,252,252,107,107,107,107,107,252,107,252,109,109,109,109,109,109,106,106,106,106,106,106,106,106,106,106,106,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,202,202,202,202,203,203,203,202,202,202,202,202,202,202,203,203,204,202,203,203,204,204,203,203,204,203,204,204,204,204,202,202,203,203,203,203,204,203,203,203,204,204,204,204,202,202,203,203,203,204,204,204,204,204,204,204,204,199,199,199,203,204,204,204 +,252,252,252,252,252,252,252,252,252,252,252,252,252,108,107,252,108,109,109,252,109,252,109,252,252,252,107,107,107,252,107,252,107,109,107,109,109,252,109,106,106,106,106,106,106,106,106,106,106,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,11,10,10,10,202,202,202,202,203,202,203,203,203,202,202,202,202,202,203,203,204,203,202,202,203,203,204,203,204,203,204,203,204,203,204,202,203,202,203,203,203,203,204,203,204,203,204,204,204,202,203,203,204,203,204,204,204,203,204,204,199,199,233,233,201,201,201,201,201 +,252,252,252,252,108,252,252,252,252,252,252,252,252,107,108,108,252,109,109,109,252,109,252,252,252,252,107,107,107,107,107,107,252,109,109,109,109,109,109,106,106,106,106,106,106,106,106,106,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,202,202,202,202,202,203,203,203,202,202,202,202,203,203,203,203,203,202,202,203,203,204,204,203,203,204,204,204,204,204,202,202,202,203,203,203,203,204,203,203,203,204,204,204,204,202,203,203,203,204,204,204,204,204,199,199,233,233,233,200,200,200,200,200,200 +,252,252,252,252,252,252,252,252,252,252,252,252,107,252,108,252,108,252,109,252,109,252,109,252,252,107,107,252,107,252,107,252,107,252,107,109,109,252,106,106,106,107,106,106,106,106,106,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,10,10,10,10,10,202,202,202,202,203,202,203,203,203,202,202,202,203,202,203,202,203,202,203,202,204,203,204,203,204,203,204,203,204,202,203,203,203,203,203,203,204,203,204,203,204,204,204,204,204,202,203,203,204,203,204,204,199,199,233,233,200,200,200,200,200,201,201,201,201 +,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,109,109,109,109,252,109,252,252,107,107,107,107,107,107,252,252,109,109,109,109,109,109,107,106,106,106,106,106,106,106,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,202,202,202,202,202,203,203,203,202,202,202,203,203,202,202,203,203,202,202,203,203,204,204,203,203,204,203,204,204,204,202,203,203,203,203,204,204,204,204,204,204,204,204,204,204,203,203,203,203,204,199,199,233,233,233,233,200,200,200,194,194,234,234,234,234 +,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,108,252,109,252,109,252,109,252,107,107,107,252,107,252,107,252,107,109,109,252,109,107,106,106,106,106,106,106,106,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,202,202,202,202,203,202,203,202,202,202,202,202,203,203,204,202,204,202,203,203,204,204,204,203,204,203,204,203,204,202,203,203,203,203,204,203,204,203,204,203,204,203,204,204,203,202,203,203,199,199,199,233,233,233,200,200,200,233,234,234,233,201,201,201,201 +,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,109,109,109,109,252,252,252,252,107,107,107,107,252,252,252,252,109,109,109,109,109,106,107,106,106,106,106,106,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,202,202,202,202,202,203,203,202,202,202,202,203,203,203,203,202,204,204,202,203,203,204,204,203,203,204,204,204,204,202,203,203,203,203,203,203,203,204,204,204,204,204,204,204,202,203,199,199,199,233,233,233,233,200,200,200,233,234,234,233,200,200,200,200,233 +,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,109,252,109,252,109,252,109,252,107,252,107,252,107,252,107,109,109,252,109,109,106,107,106,107,106,106,106,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,202,202,202,202,203,203,203,202,202,202,202,202,203,202,202,203,204,203,202,202,204,204,204,203,204,203,204,203,202,203,204,203,203,203,204,203,204,203,204,204,204,204,204,199,199,199,234,234,233,233,234,233,200,200,200,233,234,234,233,200,200,233,234,233,233 +,252,252,252,252,252,252,252,252,252,252,252,108,108,108,109,109,109,109,252,109,252,252,252,252,107,107,107,107,109,109,109,109,109,109,109,109,107,106,252,106,106,106,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,202,202,202,202,202,202,203,203,202,202,202,202,203,202,202,202,203,203,204,203,202,204,204,204,204,203,204,203,204,204,203,203,203,203,203,203,204,203,204,204,204,204,199,199,234,234,234,233,233,233,234,233,200,233,233,233,234,233,233,200,200,234,234,234,233,233 +,252,252,252,252,252,252,252,252,252,252,252,108,108,109,108,252,108,252,109,252,109,252,252,252,107,252,107,109,107,109,109,109,109,109,109,252,106,252,106,106,106,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,202,202,202,202,202,203,202,203,202,202,202,202,203,202,202,203,203,204,204,203,203,204,203,204,204,204,203,204,203,203,203,203,203,204,204,204,203,204,203,204,204,199,234,234,234,233,233,234,233,234,233,200,233,234,192,234,233,200,200,200,200,200,233,233,234,234 +,252,252,252,252,252,252,252,252,252,252,108,108,108,108,109,109,252,109,252,109,252,252,252,107,107,107,252,107,109,109,109,109,109,109,109,107,107,106,106,106,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,202,202,202,202,202,202,203,202,202,202,202,202,202,202,203,203,203,203,204,203,203,203,204,204,204,203,204,204,204,203,203,203,203,203,204,203,204,203,204,199,234,234,234,199,234,234,234,234,234,234,234,234,234,234,234,233,200,233,200,200,200,234,233,234,234,234 +,252,252,252,252,252,252,252,252,252,108,108,109,108,252,108,252,109,252,109,252,109,252,109,107,107,252,107,109,109,252,109,107,109,107,107,107,106,107,106,106,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,202,202,202,202,202,203,203,202,202,202,202,202,202,202,202,203,203,204,203,204,203,204,203,204,204,204,203,204,203,203,203,204,203,204,204,204,203,204,199,192,199,192,192,199,192,193,192,192,193,193,234,234,234,234,234,234,234,200,234,233,234,233,234,234,234,233 +,252,252,252,252,252,252,252,252,108,108,108,108,109,108,109,109,252,109,252,252,252,252,107,107,107,107,252,109,109,107,107,106,107,106,107,106,107,106,106,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,202,202,202,202,203,203,203,202,202,202,202,202,202,202,202,202,203,203,204,204,204,204,204,204,204,203,204,204,204,203,203,203,204,204,204,203,204,199,192,199,192,192,199,199,192,192,193,192,193,193,193,234,200,192,234,234,234,234,234,234,233,234,234,194,234,233 +,252,252,252,252,252,252,252,108,108,109,108,252,108,252,109,252,109,252,109,252,252,252,107,252,107,252,252,109,107,109,106,107,107,107,106,107,106,106,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,202,202,203,202,202,203,202,202,202,202,202,203,202,202,202,203,203,204,203,204,203,204,203,204,203,204,203,204,203,203,203,204,203,204,204,204,203,199,192,192,192,193,199,192,192,193,192,193,193,193,192,234,234,200,233,234,234,234,234,234,234,234,194,234,233,233 +,252,252,252,252,252,252,108,108,108,108,108,108,252,109,252,109,252,252,252,252,252,252,107,107,252,252,252,107,106,106,107,107,107,106,107,106,107,106,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,10,9,10,10,202,202,203,202,203,203,202,202,202,202,202,202,202,202,203,203,203,203,204,204,204,203,204,204,203,203,204,204,204,203,203,203,204,204,204,203,199,192,199,192,192,192,199,192,192,192,193,193,193,192,192,192,234,234,234,234,234,234,234,234,234,194,194,234,233,233 +,252,252,252,252,252,252,108,108,108,252,108,252,109,252,109,252,109,252,109,252,252,252,252,107,107,252,107,106,107,106,107,107,107,107,106,107,106,107,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,202,202,203,202,203,202,203,202,203,202,202,202,203,202,203,202,203,203,204,203,204,203,204,204,204,203,204,203,204,203,203,203,204,203,204,204,204,199,192,192,193,192,192,199,193,192,193,193,193,192,192,192,192,192,192,192,234,192,193,193,234,193,194,194,234,234,233 +,252,252,252,252,252,252,108,108,108,108,109,109,252,109,252,252,252,252,252,252,252,252,252,107,252,107,106,107,106,107,109,109,107,106,107,106,106,106,106,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,202,202,202,203,203,203,203,202,202,202,202,202,202,202,202,203,203,203,203,204,204,204,204,202,203,204,203,204,204,203,203,203,203,204,204,204,199,192,199,192,192,193,199,199,192,193,193,193,193,192,192,192,192,192,192,193,192,193,193,193,193,194,194,194,194,194,234 +,252,252,252,252,252,252,108,252,108,252,108,252,108,252,109,252,252,252,252,252,252,252,109,252,252,106,107,106,107,107,107,252,107,107,106,107,106,106,106,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,202,202,203,202,203,202,203,202,202,202,202,202,202,202,203,202,203,203,204,204,204,203,202,204,204,203,204,203,204,203,204,203,204,203,204,199,192,199,193,192,192,199,193,192,192,192,193,192,193,192,193,192,192,192,193,192,193,192,193,193,194,193,194,194,194,194,194 +,252,252,252,252,252,108,108,108,109,108,109,109,252,252,252,252,252,252,252,252,252,107,107,107,106,109,109,107,106,107,252,109,107,107,107,106,106,106,106,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,202,202,202,203,203,203,202,202,202,202,202,202,202,202,202,203,203,203,204,204,204,202,203,204,203,203,203,204,204,203,203,204,203,204,204,199,192,192,192,199,199,199,192,193,193,193,192,192,192,193,192,192,193,192,192,192,192,192,192,193,193,194,194,194,194,194,194 +,252,252,252,252,252,108,108,109,108,252,108,252,109,252,109,252,252,252,107,107,107,106,106,252,107,109,107,107,107,107,107,252,107,107,106,106,106,106,106,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,202,202,203,202,203,203,202,202,203,202,202,202,202,202,203,203,204,203,204,204,202,202,204,204,204,203,204,203,204,203,203,203,204,203,199,192,199,199,193,199,193,192,193,192,193,192,192,192,193,192,192,192,193,192,193,192,193,193,194,193,194,194,194,194,194,194,194 +,252,252,252,252,252,108,252,108,108,108,109,252,252,252,252,252,108,107,107,107,107,107,252,107,109,109,252,106,107,107,252,252,107,107,106,106,106,106,106,106,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,202,202,202,203,203,203,202,202,202,202,202,202,202,203,203,203,203,204,204,204,202,203,203,204,203,204,203,204,204,203,203,203,203,204,199,192,192,193,192,192,192,193,192,193,193,192,192,192,192,193,192,192,192,192,192,193,193,193,193,194,194,194,194,194,194,194,194 +,252,108,108,252,108,252,108,252,108,109,108,252,109,108,108,252,108,252,107,252,107,252,107,109,107,252,109,107,107,252,107,109,107,107,106,106,106,106,106,106,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,202,202,203,202,203,203,202,202,202,202,202,202,203,202,203,203,204,203,204,202,203,203,204,204,204,203,204,203,204,203,204,203,204,199,192,192,199,192,193,192,193,192,193,193,193,192,192,192,193,192,193,192,192,192,193,193,194,193,194,193,194,194,194,194,194,194,194 +,108,108,108,108,252,252,108,108,252,108,109,109,252,108,108,108,252,107,107,107,252,252,252,109,109,109,109,106,107,106,252,109,107,107,106,106,106,106,106,106,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,202,202,202,202,203,203,203,202,202,202,202,202,202,204,203,203,203,203,204,204,202,202,203,203,204,203,203,203,204,204,203,203,204,199,192,199,192,192,192,192,193,192,193,194,193,193,192,192,192,192,192,192,193,192,192,192,193,193,194,193,194,194,194,194,194,194,194,194 +,108,252,108,252,252,252,108,108,108,252,108,252,108,252,108,252,108,252,107,109,107,252,107,109,109,252,107,107,106,252,107,109,107,107,106,106,106,106,106,106,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,202,202,202,203,202,203,203,202,202,203,202,202,202,204,202,203,203,204,203,202,202,203,203,204,204,204,203,204,203,204,203,204,203,199,192,192,192,192,192,193,192,193,193,194,193,192,192,193,192,193,192,193,192,193,192,193,193,194,193,194,194,194,194,194,194,194,194,194 +,108,108,252,252,108,108,252,252,109,108,108,108,108,108,108,108,108,107,109,107,109,109,109,109,109,109,252,106,107,106,252,109,107,106,106,106,106,106,106,106,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,202,202,203,203,203,202,202,202,202,202,202,202,202,204,203,203,203,203,204,202,202,203,203,204,204,203,204,203,204,204,203,203,199,192,199,192,192,192,193,194,193,193,193,193,194,192,192,192,192,193,193,192,192,192,193,193,193,193,194,194,194,194,194,194,194,194,194,194 +,108,252,108,252,108,252,108,109,109,108,108,252,108,252,108,252,108,109,107,252,107,109,107,252,107,252,109,107,106,252,107,252,106,107,106,106,106,106,106,106,106,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,9,9,9,10,202,202,202,203,203,202,202,203,202,203,202,203,202,203,204,204,203,204,202,203,202,203,203,204,204,204,203,204,203,204,203,204,199,192,192,192,192,193,193,194,193,194,194,194,192,192,192,192,192,193,192,193,192,193,192,193,193,194,193,194,194,194,194,194,194,194,194,194 +,108,108,252,108,252,108,252,109,109,108,108,108,108,108,108,108,252,107,109,107,252,109,109,109,252,109,252,107,107,106,252,106,107,106,107,106,106,106,106,106,106,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,202,202,203,203,203,202,202,203,202,202,202,202,202,203,204,203,204,204,202,202,203,203,204,204,203,203,203,203,204,204,203,199,192,199,192,192,193,193,193,193,193,193,194,194,194,192,192,192,192,192,193,193,192,192,193,193,193,193,194,194,194,194,194,194,194,193,194,194 +,252,108,108,252,108,252,108,252,109,108,108,108,108,252,108,252,108,109,107,252,107,109,107,109,109,252,109,107,106,107,106,107,106,107,106,106,106,106,106,106,106,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,10,9,9,202,203,203,202,202,202,202,203,202,203,202,202,202,203,204,203,203,204,202,203,203,204,203,204,203,204,203,204,203,204,203,199,192,192,192,192,192,193,192,193,193,194,193,194,194,192,192,192,192,193,192,192,192,193,192,193,193,194,193,194,194,194,193,194,194,194,194,194 +,252,108,108,108,252,108,252,252,109,109,108,108,108,108,108,108,109,107,109,109,252,109,109,109,109,109,252,107,107,106,107,106,107,106,107,106,106,106,106,106,106,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,202,203,202,202,202,202,202,202,203,202,202,202,202,203,204,204,203,203,202,202,203,203,204,204,203,203,204,203,204,204,203,199,192,192,192,192,192,192,193,193,193,193,194,194,192,192,192,192,192,192,193,192,192,192,193,193,193,194,194,194,194,194,194,193,194,194,194,194 +,252,108,108,252,108,252,108,252,252,109,108,108,108,252,108,252,108,109,107,252,107,109,107,252,109,252,109,252,106,107,106,107,106,107,106,107,106,106,106,106,106,106,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,202,202,203,202,203,202,202,202,203,203,202,202,203,202,203,203,204,203,202,202,203,203,204,203,204,203,204,203,204,203,204,203,199,192,193,193,194,193,194,192,193,193,194,193,194,192,193,192,193,192,193,192,192,192,193,192,193,193,194,193,194,193,194,194,193,194,194,194,194 +,252,108,108,108,252,252,252,252,252,252,109,108,108,108,108,108,109,107,107,107,252,109,109,109,252,109,252,109,107,252,252,109,107,106,107,106,106,106,106,106,106,106,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,202,203,203,202,202,202,202,202,203,202,204,202,202,203,203,204,204,204,202,202,202,203,203,204,204,204,203,204,203,204,204,199,192,192,192,193,193,193,193,194,194,193,193,194,193,192,192,192,192,193,193,192,192,192,192,193,193,193,193,194,194,194,194,194,193,194,193,194,194 +,108,252,108,252,108,252,108,252,252,252,252,109,108,252,108,108,108,252,107,252,107,109,107,252,107,252,107,107,107,252,252,109,109,107,106,107,106,106,106,106,106,106,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,202,202,203,202,202,202,202,202,202,203,204,202,202,202,203,203,204,203,202,202,203,203,204,204,204,203,204,203,204,204,204,199,192,192,193,192,194,193,194,193,194,193,194,194,194,192,192,192,193,192,193,193,192,193,194,192,193,193,194,193,194,193,194,193,194,194,194,194,194 +,108,108,108,108,252,252,252,252,252,252,252,252,109,108,108,108,108,107,107,107,252,107,109,109,109,109,252,107,107,252,252,109,109,109,107,106,107,106,106,106,106,106,106,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,202,202,202,202,202,202,202,202,202,203,204,202,202,203,203,204,204,204,202,203,203,203,203,204,203,204,203,204,204,204,204,199,192,192,192,192,193,192,194,193,194,194,194,194,194,192,192,192,192,193,193,192,192,193,194,194,193,193,193,194,194,194,193,194,194,194,193,194,194 +,108,108,108,252,108,252,108,252,252,252,108,252,252,109,108,108,108,109,107,252,107,252,107,252,107,252,109,107,107,252,252,109,109,107,109,107,106,107,106,106,106,106,106,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,202,202,202,202,202,203,202,202,202,202,203,204,202,202,202,203,203,204,202,202,202,203,203,204,204,204,203,204,203,204,204,204,199,193,192,193,192,192,193,193,193,193,194,194,194,193,192,193,192,193,192,193,192,193,193,194,193,194,193,194,194,194,193,194,193,194,193,194,194,194 +,108,108,108,108,252,252,252,252,252,108,252,252,252,108,109,109,108,107,107,107,252,107,252,107,109,109,252,109,107,252,109,109,107,107,109,109,107,106,107,106,106,106,106,106,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,202,202,202,202,202,202,203,202,202,202,203,204,202,202,203,203,204,203,203,202,202,203,203,204,204,203,204,204,204,204,204,203,199,192,193,192,192,193,192,193,193,194,193,194,194,193,192,192,192,192,193,193,192,192,193,193,194,194,194,194,194,194,194,194,194,194,194,193,194,194 +,108,252,108,252,108,252,108,252,252,252,108,252,108,252,252,109,109,107,107,107,107,252,107,252,107,252,107,252,107,252,109,109,107,252,107,109,107,107,106,107,106,107,106,106,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,202,202,202,202,203,202,202,202,202,202,202,203,204,202,202,202,204,204,203,202,203,202,203,203,204,203,204,203,204,203,204,203,204,199,192,192,192,192,192,193,193,193,193,194,194,194,193,192,193,192,193,192,193,192,193,192,193,193,194,194,194,194,194,193,194,193,194,193,194,195,194 +,108,108,108,108,252,108,252,252,252,108,252,108,108,252,252,252,109,107,107,107,109,109,252,252,109,109,252,107,107,109,109,109,107,107,109,109,109,109,107,106,107,106,106,106,106,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,9,9,9,202,202,202,203,202,202,202,202,202,202,202,203,204,202,202,203,203,204,203,202,202,203,203,204,204,204,204,204,204,204,204,203,199,199,192,193,192,192,193,192,193,193,194,194,194,194,192,192,192,192,192,193,193,192,192,193,193,194,194,194,194,194,194,193,193,194,193,194,194,194,194 +,108,108,108,252,108,252,108,252,252,108,108,252,108,252,108,252,252,109,107,252,107,252,107,252,109,252,107,252,107,109,109,109,109,107,107,252,107,109,109,107,106,107,106,106,106,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,202,202,202,202,203,203,202,203,202,202,202,202,204,202,202,203,203,204,202,203,202,203,203,204,204,204,203,204,203,204,204,204,203,199,199,193,192,192,193,193,193,193,194,193,194,194,193,192,192,193,192,193,193,193,192,193,193,194,193,194,194,194,194,194,193,194,193,194,193,194,195,194 +,108,108,108,108,252,252,252,252,252,108,108,108,108,108,252,252,252,252,107,107,252,109,252,252,252,252,107,107,107,107,109,107,109,109,107,107,109,109,109,107,107,106,107,106,106,106,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,9,9,9,8,202,202,202,202,203,202,202,202,203,202,202,202,204,204,202,202,204,204,203,202,203,203,203,203,204,204,204,204,204,204,204,204,204,199,192,192,192,193,192,193,192,193,193,194,193,194,192,192,192,192,193,193,193,193,192,192,193,193,194,194,194,194,194,193,193,194,194,194,194,194,194,194 +,108,252,108,252,108,252,108,252,252,252,108,108,108,252,252,252,252,252,107,107,107,252,107,252,252,107,107,109,107,109,107,109,107,252,107,109,107,109,107,109,109,107,106,107,106,106,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,202,202,203,202,203,203,203,202,203,202,203,202,202,204,204,202,203,203,204,202,202,202,203,203,204,204,204,203,204,204,204,203,204,203,199,192,193,192,192,192,192,193,193,193,193,194,194,192,192,192,193,192,193,192,193,192,193,192,194,193,194,194,194,194,194,193,195,194,194,193,194,195,194 +,108,108,108,108,252,252,252,252,252,252,252,108,108,107,252,252,252,252,107,107,107,107,252,252,252,107,107,107,107,109,109,109,109,109,107,109,107,107,109,109,109,109,107,106,107,106,106,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,202,202,202,202,202,202,203,202,202,202,202,202,202,204,204,202,202,203,203,204,202,202,203,203,204,204,204,204,204,204,204,204,204,204,204,199,192,192,192,193,192,193,193,194,193,194,194,194,192,192,192,192,193,192,193,193,192,192,193,194,194,194,194,194,194,194,194,194,195,194,194,195,195,194 +,108,108,108,252,108,252,108,252,252,252,252,252,108,252,252,252,107,252,107,252,107,252,107,252,107,252,107,107,107,109,107,109,107,109,109,107,109,107,107,109,107,109,109,107,106,107,106,106,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,202,202,202,202,202,203,203,203,202,203,202,202,202,204,204,202,202,202,203,204,202,202,202,203,203,204,203,204,203,204,204,204,204,204,199,199,192,192,192,192,193,193,193,193,194,194,194,194,192,192,192,193,192,193,193,194,193,192,193,194,193,194,193,194,195,195,194,195,194,194,194,195,194,194 +,108,108,108,108,252,252,109,252,252,252,252,252,252,252,108,107,252,252,252,107,107,107,252,107,252,109,109,107,109,109,107,107,109,109,109,109,109,107,107,107,109,109,109,109,109,106,107,106,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,153,154,154,154,154,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,202,202,202,202,202,202,202,203,203,202,202,202,202,203,203,204,202,203,202,204,203,203,202,203,203,204,204,204,204,204,204,204,204,204,203,199,192,192,193,192,193,192,193,193,194,193,194,193,194,194,192,192,192,193,193,193,193,193,193,194,194,194,194,194,194,194,194,194,194,195,194,194,194,195,194 +,252,108,108,252,108,252,108,252,252,252,109,252,252,252,109,252,107,252,252,108,107,109,107,252,107,252,107,252,109,109,107,109,107,252,107,109,109,109,107,107,107,109,107,109,109,107,106,106,106,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,153,153,153,153,153,153,154,154,154,153,154,154,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,202,202,202,202,203,202,203,203,203,202,202,202,203,203,204,204,202,203,203,203,203,203,202,202,203,203,204,203,204,203,204,204,204,204,204,199,192,192,192,193,193,193,193,193,193,193,193,194,194,194,193,192,193,192,193,193,193,193,194,193,194,194,194,194,194,195,194,194,195,193,194,194,195,195,194 +,109,108,108,108,109,108,252,252,252,252,252,252,252,252,252,252,108,107,252,107,108,107,252,107,109,109,109,109,252,109,107,107,109,107,109,109,109,109,109,107,107,109,109,109,109,107,107,106,106,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,153,153,153,153,152,152,152,152,152,153,153,154,153,154,154,154,154,154,154,153,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,202,202,202,202,202,202,203,203,203,203,203,202,203,203,204,204,202,203,204,203,203,203,202,202,203,203,204,204,204,204,204,204,204,204,204,203,199,192,192,193,192,193,192,193,192,194,193,194,193,194,194,192,193,192,193,193,193,193,193,193,194,194,194,194,194,193,194,194,194,194,195,194,195,194,195,194 +,252,108,108,252,108,252,252,252,252,252,109,252,109,252,252,252,107,252,107,108,107,252,107,109,107,252,107,252,109,252,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,109,107,107,106,106,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9,153,153,152,152,152,157,157,155,156,157,157,152,153,153,153,153,153,153,154,154,154,154,154,154,154,154,8,9,8,9,8,9,8,9,8,9,8,9,202,202,202,202,202,203,202,203,202,203,202,202,202,204,204,202,202,204,204,203,203,204,202,203,203,204,204,204,203,204,204,204,204,204,204,204,199,192,192,192,193,192,193,192,193,194,194,193,194,192,193,194,192,192,192,193,193,194,193,194,193,194,194,194,194,193,194,195,194,195,194,194,195,195,195,194 +,109,252,108,108,252,252,109,252,252,252,252,252,252,252,252,252,108,107,108,252,107,107,107,107,109,109,109,109,252,252,107,107,109,107,109,107,109,109,109,107,107,107,109,109,109,109,109,107,107,106,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,152,157,156,156,155,155,157,157,156,155,156,156,157,152,153,153,152,152,153,153,153,153,153,154,154,154,154,154,154,154,154,8,8,8,8,8,8,8,8,202,202,202,202,203,203,203,202,203,202,204,202,202,202,202,202,203,203,204,204,203,202,202,203,203,204,204,204,204,203,204,204,204,204,204,199,192,192,192,193,192,193,192,193,193,194,193,194,193,192,193,194,192,194,193,193,193,193,193,193,194,194,194,194,194,193,194,194,195,195,195,194,195,195,195,194 +,252,252,108,108,108,252,108,252,252,252,109,252,252,252,252,252,108,252,107,252,107,252,107,109,107,252,107,252,109,252,107,109,107,252,107,109,107,252,107,107,107,109,107,109,107,109,109,107,107,106,106,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,152,157,157,157,156,156,155,157,156,156,155,157,156,157,156,152,153,157,156,152,152,153,153,154,153,153,154,153,154,154,154,154,154,154,154,154,8,9,8,8,202,202,203,204,202,203,202,202,202,203,204,203,202,202,202,203,203,204,203,204,203,204,202,203,203,204,204,204,203,204,203,204,204,204,204,199,192,192,192,192,193,192,192,193,193,194,194,193,192,193,193,194,193,194,192,193,193,194,193,194,193,194,194,194,195,194,194,195,194,195,194,195,194,195,195,195 +,109,252,109,108,108,252,252,252,252,252,252,252,252,252,252,252,108,107,108,109,107,107,107,107,109,107,109,109,252,109,107,107,107,107,109,107,109,107,109,107,107,107,109,107,109,109,109,107,107,106,106,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,157,157,157,157,156,156,155,155,157,157,156,156,155,156,156,156,156,152,157,157,156,156,152,153,153,153,154,154,154,154,153,154,154,154,154,154,154,154,154,154,202,202,203,204,202,202,202,202,202,203,203,204,202,202,202,203,203,203,203,204,204,204,203,203,204,204,204,204,204,204,204,204,204,204,204,204,199,192,192,192,193,192,193,192,193,193,194,194,194,192,193,194,194,193,194,193,193,193,193,194,194,194,193,194,194,195,194,194,194,195,195,195,195,195,195,195,195 +,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,108,107,108,109,252,252,107,107,109,107,252,107,252,107,252,109,252,107,109,107,252,107,252,107,107,107,109,107,109,107,109,109,109,107,107,106,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,9,8,8,8,157,157,157,156,157,155,156,155,157,156,156,155,155,156,157,156,156,155,157,156,157,155,152,153,153,153,153,153,153,154,154,154,154,154,154,154,154,154,154,154,202,202,204,202,202,202,202,202,203,203,204,204,203,202,203,202,203,203,204,203,204,204,203,203,202,204,204,204,204,204,204,203,204,203,204,204,199,192,192,192,192,192,192,193,193,193,193,194,192,192,193,193,194,194,193,194,193,193,194,193,194,193,194,194,195,194,195,195,195,195,195,194,195,195,195,194,192 +,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,107,108,107,109,109,252,107,107,107,109,109,109,109,252,109,252,107,252,107,107,107,109,107,109,107,107,107,107,107,109,109,109,109,107,106,106,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,157,157,157,157,156,156,155,155,157,157,156,156,155,155,157,156,155,157,157,156,156,156,156,152,153,153,153,153,153,153,153,153,153,154,153,154,154,154,154,154,202,202,202,202,202,203,202,202,203,203,204,204,202,202,202,203,203,203,203,204,204,204,203,202,203,204,204,204,204,204,204,204,204,204,204,204,192,192,192,192,193,192,193,192,193,193,194,192,192,193,193,193,193,194,194,194,194,194,194,194,194,193,193,194,194,195,195,195,195,195,195,195,194,195,194,192,199 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,108,107,252,109,252,252,252,107,109,107,252,107,252,109,252,109,107,107,252,107,252,107,252,107,107,107,109,107,109,107,109,107,109,107,107,106,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,9,8,157,157,157,156,156,155,156,155,157,156,156,155,156,155,157,157,157,156,157,156,156,155,156,152,153,153,152,152,152,152,152,152,153,153,153,153,154,153,154,153,202,202,203,202,203,202,202,202,203,203,204,203,204,202,203,202,203,203,204,203,204,204,202,202,204,204,204,203,204,204,204,203,204,204,204,199,192,192,192,192,192,192,192,193,193,193,193,192,193,192,193,193,194,194,194,194,194,193,194,193,194,194,194,193,195,194,195,193,195,194,195,194,194,195,192,199,192 +,109,252,109,252,109,252,252,252,252,252,252,252,252,252,108,107,108,107,252,252,252,107,107,107,107,107,109,109,252,109,252,107,107,107,252,107,252,107,109,107,107,107,107,107,109,107,109,109,107,106,106,106,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,157,157,157,156,156,156,155,155,157,157,156,156,156,155,155,155,157,157,157,156,156,156,202,202,202,152,152,202,202,203,202,202,203,152,152,152,152,153,153,153,154,202,202,202,202,202,202,202,203,203,203,203,204,204,202,202,203,203,203,203,203,203,204,202,203,203,204,204,204,204,204,204,204,204,204,204,199,192,192,192,192,192,192,193,192,193,193,194,192,192,193,193,193,194,194,194,194,193,194,194,194,194,193,193,195,194,195,195,195,195,194,194,195,195,192,199,192,193 +,252,109,252,252,252,252,252,252,252,252,252,252,252,108,107,109,107,252,107,252,109,107,107,252,107,252,107,252,107,252,109,107,109,252,107,252,107,252,107,109,107,107,107,109,107,109,107,109,106,107,106,106,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,157,157,157,157,156,156,155,155,157,157,156,156,155,156,155,155,156,202,202,202,202,202,202,202,202,202,202,202,202,203,202,203,202,203,203,204,152,153,153,154,202,203,202,203,202,202,202,203,202,203,203,204,203,204,202,203,202,203,202,203,203,204,202,203,203,204,204,204,204,204,204,204,204,204,204,204,199,193,192,192,192,192,192,192,193,193,194,192,192,193,192,193,193,194,195,194,194,194,193,194,194,194,195,193,193,195,194,195,195,194,195,195,195,192,199,192,192,192 +,109,252,109,252,252,252,252,252,252,252,252,252,252,107,108,107,109,109,252,109,252,252,107,107,109,107,109,109,252,107,252,109,107,107,107,107,252,107,109,107,109,107,107,107,109,109,109,109,107,106,107,106,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,157,157,157,157,156,156,156,155,157,156,157,156,156,155,202,202,202,202,202,202,202,202,202,202,202,202,202,202,203,203,204,204,203,203,203,204,204,152,153,153,202,202,203,202,202,202,202,202,203,203,203,203,204,204,202,202,202,202,203,203,203,202,203,203,203,203,204,204,204,204,204,204,204,204,204,204,192,192,193,192,192,192,192,193,193,194,192,192,193,193,193,193,194,195,195,195,194,194,194,195,195,195,193,193,195,195,195,195,195,194,194,195,192,199,192,192,193,192 +,252,252,252,252,252,252,252,109,252,252,252,252,252,108,107,109,107,252,107,252,252,252,109,107,107,252,107,107,107,252,107,252,107,252,107,252,107,252,107,109,107,109,107,107,107,109,107,109,106,107,106,106,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,157,157,157,157,156,156,155,155,157,157,156,157,155,156,202,202,202,202,202,202,202,202,203,202,202,203,202,203,203,204,204,203,202,203,203,204,203,204,152,153,202,203,202,202,202,202,202,203,202,203,203,204,203,204,202,203,202,203,203,202,202,203,203,204,203,204,204,204,203,204,204,204,203,204,204,204,192,192,192,192,192,192,193,193,193,192,192,193,192,193,193,194,194,195,195,194,195,195,194,195,193,195,193,195,195,195,195,195,195,194,195,192,199,192,192,192,192,192 +,109,252,109,252,252,252,109,252,252,252,252,252,252,107,108,107,109,107,252,252,252,252,252,252,107,107,107,107,109,252,252,107,107,107,107,107,107,107,252,107,109,107,107,107,109,107,109,109,107,106,107,106,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,7,8,8,8,157,157,157,157,156,156,156,155,155,157,157,156,156,156,155,202,202,202,202,202,202,203,203,202,202,202,202,203,203,204,204,204,203,203,203,203,203,204,204,155,152,203,202,202,202,202,202,202,202,203,203,203,203,204,204,202,202,203,202,202,202,203,203,203,203,204,204,204,204,204,204,204,204,204,204,204,204,192,193,192,193,192,193,192,193,192,192,192,192,193,193,193,194,195,195,195,195,194,195,195,195,195,195,194,195,195,195,195,195,194,195,192,199,192,192,192,192,193,192 +,252,109,252,252,252,252,252,252,252,252,252,252,107,108,107,252,108,252,107,252,109,252,109,252,107,107,107,252,107,252,109,252,107,252,107,252,107,252,107,109,107,109,107,109,107,109,107,109,106,107,106,106,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,157,157,157,157,157,156,156,155,155,156,157,156,156,155,156,202,203,202,203,202,203,202,202,202,203,202,203,203,204,203,204,204,203,203,204,203,204,203,204,155,155,202,202,202,202,202,202,202,203,202,203,203,204,203,204,202,203,202,202,202,203,202,203,203,204,203,204,203,204,204,204,204,204,204,204,204,199,192,193,192,192,192,192,193,192,192,193,192,193,193,194,194,195,194,195,195,194,195,195,195,195,195,195,195,195,194,195,195,195,195,192,199,199,192,193,192,193,192,193 +,252,252,109,252,252,252,109,252,252,252,252,252,108,107,108,107,109,109,252,109,252,252,252,109,252,107,107,107,252,252,252,107,107,107,107,107,252,107,107,107,109,109,107,107,109,109,109,109,107,106,107,106,106,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,7,7,7,8,157,157,157,157,156,156,155,155,157,157,156,156,156,156,202,202,202,202,202,203,202,202,202,203,203,203,203,203,203,204,204,204,203,203,203,204,204,204,204,203,155,202,202,202,202,202,202,202,202,203,203,203,203,204,204,202,202,203,202,202,203,203,203,204,204,204,204,204,204,204,204,204,204,204,204,204,192,199,192,192,192,192,193,192,192,192,192,193,193,193,193,195,195,195,195,194,195,195,195,195,195,195,194,195,194,195,195,195,195,192,199,192,192,192,192,192,192,193,192 +,252,109,252,252,252,109,252,252,252,252,252,252,108,252,107,109,108,252,107,252,109,252,252,252,109,107,107,252,107,252,107,107,107,252,107,252,107,252,107,252,107,252,107,107,107,109,107,109,106,107,106,106,106,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,157,157,157,156,156,155,155,156,157,156,157,156,156,155,202,202,203,202,202,202,203,202,203,203,204,203,204,203,204,203,204,203,204,203,204,203,204,203,202,202,155,202,202,202,202,202,202,202,203,202,203,203,204,204,202,202,203,202,202,202,203,203,204,203,204,203,204,204,204,203,204,204,204,204,204,204,192,192,192,192,192,192,192,193,192,192,192,192,193,192,193,194,195,194,195,195,195,195,195,195,195,195,195,194,195,194,195,195,192,199,192,192,193,192,193,192,193,192,193 +,252,252,109,252,109,252,252,252,252,252,252,252,108,108,108,108,109,109,252,252,252,252,252,109,252,107,107,107,252,252,107,107,107,107,107,107,107,107,252,107,109,109,109,107,107,107,109,109,107,106,107,106,106,106,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,157,157,157,157,156,155,155,156,157,157,157,156,156,155,155,202,202,202,203,202,202,203,204,203,203,203,203,203,204,204,204,204,203,203,203,203,204,204,202,202,202,202,202,202,203,203,202,202,202,202,203,203,204,204,204,202,202,204,202,202,203,203,204,204,204,203,204,204,204,204,204,204,204,204,204,204,204,192,192,192,192,193,192,193,192,192,192,192,192,192,193,194,195,195,195,195,194,195,194,195,195,195,195,194,195,195,195,195,195,199,192,192,192,192,192,192,192,192,193,192 +,252,109,252,252,252,252,252,252,252,252,252,252,108,108,108,252,108,252,109,252,109,252,252,252,109,252,107,252,252,107,107,252,107,252,107,252,107,252,107,109,107,109,107,109,107,109,107,107,106,107,106,106,106,106,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,202,206,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,157,157,157,157,156,156,155,157,156,157,156,157,156,156,155,202,202,203,202,203,202,202,202,204,204,203,203,204,203,204,204,204,203,203,203,204,202,202,202,202,202,202,202,203,202,203,202,202,202,203,203,204,203,204,202,202,203,204,202,204,202,203,203,204,203,204,203,204,203,204,203,204,204,204,204,204,199,192,192,193,192,192,192,192,193,192,192,192,192,193,193,195,195,194,195,194,195,195,195,195,195,195,195,195,194,195,195,195,199,192,192,192,192,192,192,193,192,193,192,193 +,252,252,109,252,109,252,252,252,252,252,252,252,108,108,108,108,252,109,252,109,252,252,252,252,252,252,107,107,252,252,107,107,107,107,107,107,252,107,109,107,109,109,109,109,109,107,109,106,107,106,106,106,106,106,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,202,203,203,206,207,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,157,157,157,157,156,155,157,156,157,157,156,156,156,156,202,202,202,202,202,202,202,202,203,203,204,203,203,203,204,204,204,204,203,203,202,202,202,202,202,202,202,202,203,203,203,203,202,202,203,203,204,204,203,203,202,202,203,203,204,202,203,203,203,203,204,203,204,204,204,204,204,204,204,204,204,204,192,192,192,192,193,192,192,193,192,192,192,193,192,192,193,195,194,194,194,194,194,195,194,195,195,195,195,194,195,195,195,199,199,192,192,192,192,192,192,192,192,192,193,192 +,252,252,252,109,252,252,252,252,252,252,252,252,108,109,108,109,252,252,109,252,109,252,109,252,109,252,107,252,107,252,107,107,107,252,107,252,107,109,107,109,107,252,107,109,109,107,107,107,106,107,106,106,106,106,106,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,202,203,202,203,203,204,206,207,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,7,6,7,157,157,157,157,155,157,156,157,157,157,156,156,156,156,202,202,202,202,202,202,202,203,203,204,204,204,203,204,203,204,204,203,202,203,202,203,202,203,202,203,203,203,202,203,203,203,202,202,203,204,202,203,202,203,202,203,203,204,202,203,202,203,202,203,203,204,203,204,203,204,204,204,204,204,204,204,192,192,192,193,192,192,192,192,192,192,192,192,193,193,192,194,194,194,194,194,195,194,194,195,195,195,195,195,195,195,199,199,192,193,192,192,192,193,192,193,192,193,192,193 +,252,252,109,252,109,252,252,252,252,252,252,252,108,108,109,252,109,109,252,252,252,252,252,252,252,252,107,107,252,252,107,107,107,107,107,107,252,107,109,107,109,109,109,109,109,107,109,106,107,106,106,106,106,106,106,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,202,202,203,203,202,202,203,203,206,207,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,157,157,157,157,156,155,156,157,157,157,156,156,156,156,155,202,202,202,202,202,202,203,203,203,204,204,203,204,204,204,204,202,202,202,202,203,202,202,202,203,203,203,203,203,203,203,203,202,202,204,202,202,202,202,202,203,203,204,204,203,202,203,203,203,203,203,203,204,204,204,204,204,204,204,204,204,199,192,192,192,192,192,192,193,192,192,193,192,193,193,194,194,194,194,194,194,192,193,194,195,195,195,195,195,195,195,199,199,192,192,192,192,192,192,192,193,193,193,192,193,193 +,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,252,108,252,109,252,109,252,252,252,109,252,252,107,107,252,109,252,107,252,107,252,107,109,107,252,107,252,107,109,107,107,107,109,106,106,106,106,106,106,106,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,202,203,202,203,202,202,202,203,203,204,206,207,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,157,157,157,157,155,156,157,156,157,156,157,156,156,155,156,202,203,202,203,202,203,202,203,203,204,204,204,203,204,203,202,202,203,202,203,202,203,202,203,203,203,202,203,203,203,202,202,202,203,203,204,203,204,202,203,202,204,203,204,202,203,202,203,203,204,203,204,203,204,203,204,204,204,204,204,204,199,192,192,192,192,192,193,192,192,192,192,193,193,193,193,194,194,194,194,192,194,194,195,195,195,194,195,195,195,199,199,192,192,192,192,192,193,192,193,192,193,192,193,192,193 +,252,252,109,252,109,252,252,252,252,252,252,252,108,108,108,108,252,109,252,109,252,252,252,252,252,252,252,107,107,107,109,109,107,107,107,107,109,107,109,107,109,109,109,109,107,107,107,109,107,106,106,106,106,106,106,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,202,202,202,202,202,202,203,202,204,202,202,203,203,206,207,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,6,7,6,7,6,7,6,6,157,157,157,157,157,157,156,155,156,157,156,156,156,156,202,202,202,202,202,202,202,203,203,203,204,204,202,203,203,202,202,202,202,203,202,203,202,203,203,203,203,204,204,204,202,202,202,203,203,203,203,204,202,203,203,203,203,204,202,202,202,203,203,203,203,203,203,203,199,199,204,204,204,204,204,204,192,192,192,192,192,193,193,193,193,192,193,192,193,193,194,193,194,194,192,193,194,195,195,195,195,195,195,195,199,192,192,192,192,192,192,192,192,193,192,193,192,193,193,193,193 +,252,109,252,252,252,252,252,252,252,252,252,252,107,252,108,252,252,252,109,252,109,252,109,252,252,252,109,107,107,252,107,252,107,252,107,252,107,109,107,109,107,252,107,107,107,109,107,109,106,106,106,106,106,106,106,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,202,202,202,202,203,203,204,202,204,202,203,203,204,206,207,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,157,157,157,156,156,155,155,157,157,156,157,156,156,155,202,202,202,202,203,202,203,203,204,203,204,202,203,202,202,202,203,202,203,202,203,202,203,203,203,203,204,204,204,202,203,202,203,202,203,203,204,202,203,203,204,203,204,202,203,202,203,202,203,202,203,203,199,199,192,193,204,203,204,204,192,199,192,192,193,192,192,192,193,193,194,192,192,193,193,194,194,194,192,192,193,192,194,193,195,195,195,195,195,195,199,192,192,192,192,192,193,192,193,192,193,192,193,192,193,192,193 +,252,252,109,252,109,252,252,252,252,252,252,252,108,108,109,252,109,109,252,252,252,252,252,252,252,252,252,107,107,107,109,109,252,107,252,107,107,107,109,107,109,109,109,107,107,107,107,109,107,106,106,106,106,106,106,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,202,202,202,202,203,203,204,204,202,204,202,202,203,203,206,207,207,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,157,157,157,156,156,156,155,155,157,157,157,156,156,155,155,202,202,202,202,202,203,203,203,203,204,204,202,202,202,202,203,203,203,203,203,203,203,203,203,203,204,204,202,202,202,202,203,203,203,203,204,204,202,202,203,203,204,204,202,202,203,202,203,203,203,199,199,193,192,194,194,204,204,204,199,199,199,192,193,193,192,192,193,193,193,193,192,193,192,194,193,194,192,192,193,193,193,193,195,195,195,195,195,194,195,199,192,192,193,192,192,192,192,192,192,192,193,193,193,193,193,193 +,252,109,252,252,252,252,252,252,252,252,252,109,107,109,108,252,108,252,109,252,109,252,252,252,252,252,252,107,107,109,107,252,109,252,107,109,107,109,107,252,107,252,107,252,107,109,107,107,106,106,106,106,106,106,106,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,202,203,202,202,202,203,203,204,202,204,202,203,203,204,206,207,207,207,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,7,6,6,157,157,157,157,156,156,155,155,156,157,156,156,155,156,155,202,202,203,202,203,202,203,203,204,203,204,202,202,202,203,202,203,203,203,202,203,203,203,204,204,204,204,202,202,202,203,202,203,203,204,203,204,202,202,202,203,203,204,199,199,199,203,202,199,199,192,192,193,193,194,194,194,193,199,199,193,193,194,193,192,192,193,192,193,193,194,192,192,193,193,194,192,192,193,192,193,194,195,194,195,194,195,195,195,195,199,199,192,192,192,192,193,192,192,192,193,193,194,193,193,193,193 +,109,252,109,252,252,252,252,252,252,252,252,252,108,108,108,108,252,109,252,109,252,252,252,252,252,252,252,107,107,107,107,107,252,109,107,107,109,107,109,107,109,109,107,107,109,109,107,106,107,106,106,106,106,106,106,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,202,202,202,202,202,203,203,204,203,202,202,203,204,203,206,207,207,207,206,207,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,157,157,157,156,156,155,156,155,157,156,156,156,156,155,202,202,202,202,202,202,203,203,203,204,204,204,203,203,203,203,203,203,204,203,204,204,204,204,204,204,204,202,202,202,202,202,203,203,203,203,204,204,202,202,203,203,204,199,199,192,193,192,192,192,192,192,192,193,194,193,194,194,192,192,193,193,193,193,194,192,192,192,193,193,193,193,192,193,194,192,192,192,192,192,193,194,194,195,195,195,195,195,195,195,199,199,192,199,192,192,192,192,192,192,193,192,193,193,193,192,193,193 +,252,252,252,252,252,252,252,252,252,252,252,252,107,252,108,252,252,252,109,252,109,252,109,252,252,252,109,107,107,109,107,109,107,252,109,109,107,252,107,109,107,252,106,107,107,107,106,107,106,106,106,106,106,106,106,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,202,202,203,202,203,202,203,202,203,204,204,203,202,202,203,204,204,206,207,207,207,207,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,145,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,5,6,6,6,157,157,156,157,155,156,155,155,156,157,156,156,155,156,202,203,202,202,202,203,202,203,203,204,204,202,202,203,202,203,203,204,203,204,204,204,203,204,204,204,204,202,202,203,202,203,203,204,203,204,204,204,202,202,202,204,204,199,192,193,192,193,193,194,194,192,192,193,193,194,194,192,193,194,192,193,193,194,193,192,192,193,193,194,193,194,192,194,193,192,192,193,192,193,193,194,194,195,195,195,194,195,195,195,199,192,199,193,192,192,192,193,192,193,192,193,193,194,193,193,193,193 +,109,252,109,252,252,252,252,252,252,252,252,252,108,107,109,252,109,109,252,109,252,252,252,252,252,252,252,107,107,107,109,107,109,109,109,107,109,107,109,107,109,109,106,107,107,106,107,106,107,106,106,106,106,106,106,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,202,202,202,202,202,203,202,203,204,202,203,204,204,202,202,203,204,204,206,207,206,207,207,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,145,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,157,157,157,156,156,156,155,155,157,157,156,156,156,156,155,202,202,202,202,203,203,203,203,204,204,202,202,202,202,203,203,203,203,204,204,204,204,204,204,204,204,202,202,203,203,203,203,203,203,204,204,202,202,203,202,203,204,199,199,192,192,193,193,193,193,194,194,192,192,193,193,192,193,194,194,193,193,193,193,194,192,192,192,193,193,194,194,192,193,193,192,192,192,193,193,194,194,193,194,194,194,195,195,195,195,199,192,199,192,193,192,192,192,192,192,192,193,193,193,193,193,194,193 +,252,109,252,252,252,252,252,252,252,252,252,252,107,109,108,252,108,252,109,252,109,252,109,252,252,252,252,107,107,107,107,252,107,252,109,109,107,109,107,252,107,252,107,107,106,107,106,107,106,107,106,106,106,106,106,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,202,202,203,202,202,202,203,202,203,203,204,202,204,204,203,202,203,204,204,206,207,206,207,207,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,145,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,157,157,157,156,156,155,156,155,157,156,157,156,156,155,156,202,202,202,203,202,203,203,204,204,202,202,204,202,203,203,204,203,204,203,204,204,204,204,204,203,204,202,203,202,203,203,204,203,204,204,203,202,203,202,203,202,204,199,193,192,193,192,193,193,193,192,194,193,194,193,192,192,193,193,195,195,193,193,194,193,192,192,193,192,194,193,194,194,193,192,192,192,193,193,194,194,193,194,195,194,195,195,195,195,195,199,192,192,193,192,192,192,192,192,192,193,194,193,194,193,194,193,193 +,109,252,109,252,252,252,252,252,252,252,252,252,108,107,108,108,252,109,252,109,252,252,252,252,252,252,252,107,107,107,107,107,109,109,109,107,109,107,109,107,109,109,107,107,107,106,107,106,107,106,106,106,106,106,106,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,202,202,202,202,203,202,202,203,204,202,204,203,204,202,204,202,202,203,204,206,207,205,206,206,207,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,145,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,5,6,5,6,6,6,5,6,157,157,156,157,156,156,155,155,157,156,156,156,156,156,202,202,202,202,202,203,203,204,204,202,203,203,204,203,203,203,203,203,203,204,204,204,204,204,204,204,204,202,202,203,203,203,203,204,204,204,202,203,203,203,203,203,199,199,192,192,192,193,193,193,193,192,193,194,194,192,192,193,193,194,193,195,195,193,193,194,192,192,192,193,193,193,194,194,192,193,192,192,192,192,193,193,193,194,194,195,195,195,195,195,195,199,192,192,192,193,193,192,192,192,192,193,194,194,193,193,193,193,194 +,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,109,252,252,109,252,109,252,109,252,252,252,108,107,107,252,107,107,107,252,107,109,107,109,107,109,107,252,107,107,106,107,106,107,106,107,106,106,106,106,106,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,202,203,202,203,202,203,202,203,204,202,202,203,203,204,204,202,204,203,204,206,207,205,205,207,207,207,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,145,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,157,157,157,156,156,155,156,155,157,156,156,156,156,155,202,202,203,202,203,203,204,202,202,202,203,203,204,202,203,203,204,203,204,203,204,204,204,204,204,204,204,202,203,202,203,203,204,203,204,202,203,202,203,202,203,203,199,192,192,192,193,192,193,192,193,193,194,194,192,192,193,192,194,194,194,195,195,193,194,192,192,192,193,193,194,193,194,192,193,192,192,192,193,192,193,193,194,193,195,194,195,195,195,194,195,192,192,192,193,192,193,193,192,192,193,193,194,193,194,193,194,193,192 +,252,252,109,252,109,252,252,252,252,252,252,252,109,108,108,252,109,109,252,109,252,109,252,252,252,252,108,107,107,107,107,107,109,107,109,109,107,107,109,107,109,109,109,107,106,106,107,106,107,106,107,106,106,106,106,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,202,202,202,202,202,203,204,203,202,204,202,203,202,203,203,204,202,204,203,204,206,207,205,206,206,207,207,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,145,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,157,157,157,157,156,156,156,155,155,157,157,156,156,155,155,202,202,202,202,204,203,202,202,202,203,203,204,204,203,203,204,204,204,204,203,204,204,204,204,204,204,204,202,202,203,203,204,204,204,202,202,202,203,203,203,203,199,199,192,192,192,192,192,192,193,193,194,194,192,192,193,194,194,193,194,193,195,195,195,192,193,192,192,193,193,193,194,194,194,192,192,192,192,192,193,193,193,193,194,195,195,195,195,195,194,199,192,192,192,192,193,193,193,192,192,193,193,193,194,194,194,193,193,192 +,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,252,252,109,252,109,252,109,252,252,252,108,107,107,107,107,252,107,109,109,109,107,109,107,252,107,252,107,107,106,106,106,107,106,107,106,106,106,106,106,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,108,252,108,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,202,202,203,202,202,203,204,203,204,204,202,202,204,203,204,202,203,203,204,204,206,207,205,205,207,207,207,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,145,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,157,157,157,157,156,156,155,156,155,157,156,156,155,156,202,203,202,204,204,203,202,202,202,203,202,203,203,204,204,204,203,204,204,203,203,204,203,204,204,204,204,155,155,203,202,204,203,204,202,202,202,203,202,203,203,204,199,192,192,193,192,192,192,193,193,194,193,192,192,193,192,194,192,194,194,195,193,194,194,193,192,192,192,193,193,194,193,194,193,192,192,193,192,193,192,193,193,194,193,194,194,195,194,195,195,199,192,192,192,193,192,193,193,192,192,193,193,194,193,194,193,193,192,192 +,252,252,252,252,109,252,109,252,252,252,252,252,109,108,108,108,252,109,109,109,252,252,252,252,252,252,108,107,107,107,107,107,252,109,109,109,109,107,109,107,109,109,109,106,107,106,106,106,107,106,107,106,107,106,106,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,108,108,108,108,109,109,109,107,109,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,202,202,202,202,202,204,204,204,203,202,202,203,204,204,204,202,202,203,203,204,206,207,205,206,206,207,207,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,150,144,144,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,157,157,157,157,157,156,157,156,156,155,155,157,156,156,202,202,202,202,203,203,204,203,202,202,202,202,203,203,203,204,204,203,204,204,204,204,204,204,204,204,204,155,155,155,155,202,203,203,204,202,202,202,203,203,203,203,203,199,199,192,192,192,192,192,193,193,194,194,192,192,193,193,194,194,194,194,195,192,193,193,193,193,194,193,192,192,193,194,194,194,192,192,192,193,193,194,194,193,194,194,194,194,195,195,195,195,195,199,192,192,193,193,193,193,193,192,192,192,193,193,194,194,193,192,192,192 +,252,252,252,109,252,252,252,252,252,252,252,252,252,109,108,109,252,252,109,252,109,252,109,252,252,252,108,107,107,252,107,107,107,109,107,109,107,109,107,109,107,252,107,106,107,107,106,106,106,107,106,107,106,107,106,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,108,252,108,252,108,109,109,109,107,109,107,109,107,109,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,202,202,202,202,203,203,204,204,204,202,203,203,204,203,204,202,203,202,204,204,205,206,205,206,207,206,207,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,150,144,144,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,157,157,157,155,156,157,157,157,156,156,155,155,157,203,202,202,202,203,202,203,203,204,204,203,202,202,202,203,203,204,203,204,204,204,203,204,203,204,203,204,204,204,204,156,155,155,155,202,203,204,202,202,202,203,202,203,203,204,203,199,192,192,192,193,192,193,193,194,193,192,192,193,192,193,192,194,194,194,194,192,192,193,193,193,194,194,192,193,193,194,193,194,192,192,192,193,193,194,193,194,194,194,193,194,195,195,195,195,195,199,192,192,192,193,192,193,192,193,192,193,193,194,194,192,192,192,192,192 +,252,252,252,252,109,252,252,252,252,252,252,252,252,107,108,252,109,109,109,109,252,109,252,252,252,252,108,107,107,107,107,107,107,107,109,109,109,107,109,109,109,109,106,107,107,106,107,106,106,106,107,106,107,106,106,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,108,108,108,252,108,252,109,109,109,107,107,109,107,109,107,109,109,107,107,107,107,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,202,202,202,202,203,203,204,204,204,202,203,203,204,204,202,202,203,203,204,204,205,205,206,205,206,207,207,207,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,150,150,144,146,144,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,157,157,157,157,157,156,156,155,155,157,157,156,156,155,157,202,202,202,202,202,203,203,204,204,204,202,202,202,203,203,203,203,204,204,204,204,204,203,203,204,204,204,204,204,204,155,155,155,155,202,202,202,202,202,202,202,203,203,203,203,199,199,192,192,192,192,193,193,193,193,194,192,192,192,194,194,194,194,194,194,192,192,193,193,193,193,195,194,192,192,194,193,193,193,192,192,192,192,193,193,194,194,194,193,194,194,195,195,195,195,195,199,199,192,193,193,193,193,192,192,193,193,193,194,194,192,192,193,192,193 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,252,252,109,252,109,252,109,252,109,252,108,252,107,107,107,107,107,109,109,109,107,109,107,109,107,252,107,107,107,107,107,107,106,107,106,107,106,107,106,106,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,108,108,252,252,252,108,252,252,109,107,109,107,109,107,109,107,109,107,109,107,109,107,107,107,107,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,202,202,202,202,202,203,203,204,203,204,203,204,204,202,202,203,203,204,203,204,204,205,206,205,206,207,206,207,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,150,150,149,146,144,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,157,156,157,157,157,157,157,156,157,155,156,155,155,156,156,155,155,157,202,202,203,202,203,203,204,203,204,204,202,202,203,202,203,203,204,203,204,204,204,203,204,203,204,204,204,203,204,204,156,155,155,202,203,202,202,202,203,202,203,203,204,203,204,199,192,192,193,192,193,192,193,193,192,192,193,192,193,192,194,194,193,194,192,192,193,193,193,194,195,193,194,192,192,194,193,193,192,192,193,192,193,192,193,193,194,193,194,193,194,194,195,195,195,195,199,192,199,192,193,193,194,192,193,192,193,193,194,192,193,192,193,193,193 +,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,252,108,252,107,107,107,107,252,109,109,107,109,107,109,107,109,106,106,107,107,107,107,107,107,106,106,106,107,106,107,106,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,108,108,252,108,252,252,252,252,109,109,107,107,107,107,107,107,107,109,107,107,107,109,107,107,107,107,107,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,202,202,203,202,203,203,204,204,203,203,204,203,204,202,203,203,203,203,204,204,205,205,207,205,206,207,206,207,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,150,150,150,149,146,147,144,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,157,157,156,157,156,156,157,157,157,156,156,156,155,155,155,157,156,156,155,202,202,202,202,203,203,203,203,204,204,204,202,202,202,203,203,203,203,203,203,204,204,204,204,204,204,204,204,204,204,204,155,155,155,202,202,202,202,202,202,203,203,203,203,204,199,199,192,192,192,192,192,193,193,192,192,193,193,193,193,195,195,194,194,192,192,193,193,193,194,194,193,195,194,192,192,193,193,192,192,193,193,193,193,193,193,194,194,194,193,193,194,195,195,195,195,195,199,192,192,193,193,193,193,192,192,193,193,194,194,192,192,193,193,194,192 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,252,252,109,252,109,252,109,252,252,252,108,252,107,107,107,107,107,109,109,109,107,109,107,109,106,106,107,107,107,107,107,107,106,107,106,106,106,107,106,106,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,108,108,252,252,252,252,252,252,252,109,252,109,109,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,202,202,202,202,202,204,204,204,203,204,204,204,204,203,203,204,203,204,203,204,204,205,206,205,205,206,206,207,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,150,150,150,150,149,146,147,144,144,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,157,157,157,156,157,156,156,156,157,157,157,156,156,156,156,155,155,156,156,155,155,202,202,202,203,202,203,203,204,203,204,204,202,203,203,202,203,203,204,203,204,204,204,203,204,203,204,204,204,204,204,155,156,155,155,202,202,202,203,202,203,202,203,203,204,203,199,192,192,192,193,192,193,193,194,192,193,192,193,193,195,195,194,194,192,192,193,193,193,193,194,195,195,195,194,192,193,192,193,192,193,193,194,193,194,194,194,193,193,193,194,193,195,194,195,194,195,195,199,192,192,192,193,193,194,192,193,192,193,193,192,192,194,193,193,193,192 +,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,107,109,109,109,109,109,109,252,252,252,252,108,252,107,107,107,107,107,107,109,107,109,107,109,107,106,107,107,107,107,106,107,106,106,107,107,106,107,106,107,106,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,108,108,252,108,252,252,252,252,252,252,252,109,109,107,109,107,107,107,107,109,107,107,107,109,107,107,107,107,107,107,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,202,202,202,202,202,203,204,204,203,203,204,204,203,204,202,203,203,204,204,204,204,205,205,206,205,205,206,206,207,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,150,148,148,148,146,146,147,147,147,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,157,157,157,157,157,156,156,156,157,157,156,155,157,156,156,155,155,155,156,156,155,156,202,202,202,202,203,203,203,203,204,204,204,202,202,203,203,203,203,203,204,204,204,204,204,204,204,204,204,204,204,204,156,155,155,155,202,202,202,202,203,203,203,203,203,203,199,199,192,192,192,192,193,193,193,199,193,194,194,194,195,195,194,194,192,192,194,193,193,193,194,195,195,193,195,195,194,192,193,193,194,192,192,192,193,193,193,193,193,193,193,193,194,195,195,195,195,194,195,199,192,199,193,193,193,192,192,192,193,193,192,192,193,193,193,194,194,192 +,252,252,252,252,252,252,252,109,252,252,252,252,252,252,107,109,107,252,109,252,109,252,109,252,109,252,252,107,107,107,107,252,107,107,107,109,107,109,107,106,107,106,107,252,107,107,106,106,106,107,107,107,106,107,106,106,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,252,108,108,252,252,252,252,252,252,252,252,109,109,109,107,109,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,202,202,202,202,203,202,204,204,203,203,204,204,204,204,203,202,204,203,204,204,205,204,205,206,207,205,205,206,207,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,150,150,149,149,149,149,149,144,147,4,5,4,5,4,5,4,5,4,5,4,5,4,5,150,145,145,145,145,145,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,157,157,157,157,156,157,156,157,156,156,155,157,156,157,155,156,155,155,156,156,155,202,202,202,202,203,202,203,203,204,203,204,204,202,202,203,203,204,203,204,203,204,204,204,204,204,203,204,204,204,204,204,155,156,155,155,202,202,202,203,202,203,202,203,203,204,199,192,192,192,192,193,192,193,199,193,193,194,193,195,194,195,195,192,193,192,193,194,193,194,193,195,195,195,193,195,194,192,194,193,192,193,192,193,192,193,192,193,193,194,193,194,194,195,195,195,195,194,195,199,192,192,192,193,193,192,192,193,193,194,192,193,193,194,193,194,192,192 +,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,107,109,107,109,109,252,109,252,109,252,252,252,107,107,107,107,107,107,107,107,107,109,107,109,106,107,106,107,107,107,107,106,106,107,107,107,107,107,106,107,106,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,108,108,108,252,108,252,252,252,252,252,252,252,252,109,109,109,107,109,109,109,107,109,109,107,107,107,109,107,107,107,107,107,107,107,107,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,202,202,202,203,203,202,204,204,203,203,203,204,204,202,202,203,202,204,204,204,204,205,205,206,205,205,205,206,206,207,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,150,150,150,150,150,150,150,145,144,147,144,144,4,4,4,4,4,4,4,4,4,4,4,4,4,150,149,144,146,147,147,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,157,157,157,157,157,156,157,156,156,155,155,156,156,156,156,155,155,155,156,155,156,202,202,202,202,202,203,203,203,203,204,204,204,202,203,203,204,203,204,203,204,204,204,204,204,204,204,204,204,204,204,204,155,155,155,155,202,202,202,202,203,203,203,203,204,199,199,192,192,192,193,193,193,192,193,193,193,193,195,195,195,195,195,192,192,193,194,194,193,193,195,195,195,195,195,195,194,192,193,192,192,192,193,193,193,193,194,193,194,194,194,194,194,195,195,194,195,194,195,199,192,199,193,193,193,192,193,193,193,193,192,192,193,193,193,192,192,192 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,109,252,109,252,109,252,109,252,109,107,107,252,107,107,107,107,107,109,107,109,106,107,107,109,107,252,107,107,107,107,106,107,106,107,107,107,106,106,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,109,109,109,109,109,109,107,109,107,109,107,109,107,107,107,107,107,107,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,202,202,202,202,202,203,204,204,203,203,204,202,203,204,203,203,202,203,204,204,205,205,213,205,207,205,213,206,214,207,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,150,232,150,232,149,149,232,149,144,232,147,232,144,232,4,4,4,4,4,4,4,4,4,4,4,4,150,148,148,148,148,148,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,157,157,157,157,157,156,157,157,157,156,156,155,157,156,156,155,156,155,155,156,155,202,202,202,203,202,203,203,203,203,204,203,204,204,202,202,203,203,204,203,204,203,204,204,204,203,204,203,204,204,204,204,204,155,155,155,203,202,202,202,203,202,203,203,204,203,199,192,192,192,193,192,193,192,199,192,193,193,194,195,195,194,195,192,192,192,194,193,194,193,195,193,195,193,195,193,195,194,193,193,192,192,193,193,194,194,193,192,193,193,194,193,194,194,195,195,195,194,195,195,199,192,192,192,193,193,192,192,193,192,192,192,193,193,194,192,192,192,192 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,109,109,109,252,109,252,252,252,107,107,107,107,107,107,107,107,107,109,107,106,106,107,107,252,107,252,107,107,107,106,106,107,107,107,107,107,106,106,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,108,108,108,252,108,252,108,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,107,109,109,107,107,107,109,107,109,107,107,107,107,107,107,107,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,202,202,202,202,203,202,203,204,203,203,203,202,203,204,204,204,202,202,204,204,204,204,205,205,206,205,205,205,206,206,206,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,150,150,145,145,145,145,145,145,145,4,4,4,4,150,150,150,150,149,150,149,149,144,144,144,144,147,147,144,144,4,4,4,4,150,145,145,145,145,145,4,4,150,149,146,147,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,157,157,157,157,156,156,157,157,156,156,155,155,156,156,156,156,155,155,155,156,155,202,202,202,202,203,203,203,203,203,203,204,204,204,202,203,203,204,203,204,204,204,204,204,203,204,204,204,204,204,204,204,204,155,155,155,202,202,202,203,203,203,203,203,203,199,199,192,192,192,192,193,193,192,199,193,193,194,195,195,195,195,195,192,192,193,193,194,194,193,193,193,193,195,195,195,195,194,192,193,193,194,193,193,192,192,192,193,193,193,193,194,194,194,194,195,195,195,195,195,199,192,199,193,193,193,192,192,192,193,192,193,193,194,192,192,192,193,193 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,109,252,109,252,109,252,109,252,109,107,107,107,107,252,107,252,107,252,107,107,106,107,107,109,107,252,107,107,107,107,106,107,106,107,107,107,106,106,106,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,108,252,108,108,252,108,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,107,109,109,109,107,109,107,109,107,107,107,107,107,107,107,107,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,202,202,202,202,202,202,202,204,204,203,202,203,203,204,204,204,203,204,203,204,204,205,205,205,205,213,206,205,205,206,206,207,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,150,150,150,149,144,146,146,147,147,4,3,4,150,150,150,150,150,150,145,145,145,146,146,146,146,146,146,147,147,147,3,4,3,150,149,232,146,232,147,4,3,150,149,146,150,150,150,145,145,145,145,145,145,4,3,4,3,4,3,4,3,4,3,4,3,157,157,157,157,156,156,157,156,156,155,155,156,157,156,156,155,156,155,155,156,155,202,203,202,203,202,203,202,203,202,204,203,204,202,203,202,203,204,204,203,204,204,204,203,204,203,204,203,204,204,204,204,204,155,155,155,202,202,203,202,203,203,204,203,204,199,192,192,192,192,193,192,199,199,193,193,194,193,195,194,195,195,193,192,193,193,194,194,195,195,195,193,195,193,195,195,195,195,194,194,193,193,193,192,193,192,193,192,193,193,194,193,194,193,194,194,195,195,195,195,199,192,193,192,193,193,194,192,193,192,192,192,192,192,193,192,193,192,193 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,109,252,109,109,109,252,252,252,107,107,107,107,107,107,107,107,107,107,107,107,106,107,107,109,107,252,107,107,107,107,106,107,107,107,107,107,106,106,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,108,108,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,107,107,109,109,107,109,109,107,107,107,107,107,107,107,107,107,107,107,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,202,202,202,202,203,202,203,203,204,202,203,203,204,202,204,204,204,204,204,204,204,204,205,205,205,205,213,205,213,206,206,206,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,3,150,150,150,149,144,146,146,147,147,4,4,3,150,150,232,149,232,149,232,149,232,144,232,146,232,146,232,147,232,147,150,145,145,145,145,145,145,145,145,3,4,150,149,146,150,149,149,149,144,146,146,147,147,4,4,3,4,4,4,3,4,4,4,3,4,157,157,157,157,156,157,157,157,156,155,155,157,156,156,156,156,155,155,155,155,202,202,202,202,202,203,203,203,202,204,203,204,204,202,202,203,203,204,203,204,204,204,203,204,204,204,204,204,204,204,204,204,155,155,155,155,202,202,202,203,203,203,203,204,199,199,192,192,199,199,199,199,192,193,193,193,193,194,195,195,195,195,192,193,193,193,193,195,195,193,193,195,195,195,195,195,195,195,194,194,193,193,192,192,192,192,192,193,193,193,193,194,194,194,194,195,195,195,195,195,199,192,192,193,193,193,193,192,192,192,192,192,192,192,192,193,192,193,192 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,109,252,109,252,109,252,109,252,109,107,107,107,107,107,107,252,107,252,107,107,106,107,107,109,107,252,107,107,107,107,106,107,106,107,106,107,106,107,106,106,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,108,108,252,108,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,109,252,109,109,109,109,107,107,107,109,107,109,109,109,107,109,107,107,107,107,107,107,107,107,107,107,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,202,203,202,202,202,202,202,203,203,202,202,204,204,204,203,204,203,204,203,204,204,215,205,205,205,215,205,213,205,213,206,214,206,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,149,149,148,148,148,148,148,3,4,3,4,150,150,232,149,232,149,232,149,232,144,232,146,232,146,232,147,232,147,149,144,144,144,149,149,149,149,149,145,145,150,149,146,150,149,149,149,144,146,146,147,147,4,3,4,3,4,3,4,3,4,3,4,157,157,157,157,157,157,156,157,156,156,155,155,156,157,156,156,155,156,155,157,155,203,202,202,202,203,202,203,202,204,203,204,204,204,202,203,203,204,204,204,203,204,204,204,203,204,204,204,203,204,203,204,155,155,155,155,155,202,202,203,203,204,203,204,203,199,199,193,199,192,192,192,192,193,192,193,193,194,193,195,195,195,192,193,193,195,193,195,195,193,192,193,193,195,193,195,195,195,193,194,193,193,192,192,192,192,192,193,193,194,193,194,193,194,194,195,195,195,195,195,199,199,192,199,192,193,193,194,192,193,192,193,192,193,192,193,192,193,193,193 +,108,252,252,252,252,252,252,252,109,252,252,252,252,252,252,107,109,107,109,109,109,109,252,109,252,252,252,107,107,107,107,107,107,107,252,107,107,107,107,107,107,107,252,107,252,107,107,106,106,106,107,106,107,107,107,107,106,106,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,108,252,108,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,107,107,107,107,109,109,109,107,109,107,109,107,107,107,107,107,107,107,107,107,107,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,202,202,202,202,202,202,202,202,203,203,202,203,203,204,203,204,204,204,204,204,204,205,204,205,205,205,205,205,213,205,205,213,206,206,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,3,4,3,4,3,4,3,3,150,150,149,144,146,146,147,148,148,150,150,150,150,150,150,150,150,150,149,149,144,144,144,146,146,146,147,147,147,149,146,146,144,146,144,144,144,149,149,149,150,149,146,232,150,148,148,148,148,148,148,4,3,4,3,3,3,4,3,4,3,4,157,157,157,157,157,157,157,157,157,157,156,156,155,157,156,156,156,156,155,155,157,155,202,202,202,202,202,203,202,203,204,204,204,203,203,202,202,203,204,204,204,204,204,203,203,204,204,204,204,204,204,156,156,155,155,155,155,155,202,202,202,203,203,204,204,199,199,199,199,192,192,193,192,192,192,193,193,193,193,195,195,195,195,192,193,193,193,195,195,193,193,193,193,195,195,195,195,195,195,194,194,193,192,192,192,192,192,192,192,193,193,194,194,194,194,195,195,195,195,195,199,199,192,192,192,192,192,193,193,194,192,192,192,192,192,193,193,193,193,193,193 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,109,252,109,252,109,252,109,252,109,107,107,107,107,252,107,252,107,252,107,107,106,107,107,252,107,252,107,107,107,106,106,107,106,107,106,107,107,107,106,106,106,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,108,108,252,108,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,107,109,107,109,107,109,109,109,107,109,107,107,107,107,107,107,107,107,107,107,107,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,202,202,203,202,203,202,202,202,203,203,202,202,204,204,204,203,204,203,204,203,204,204,215,205,215,205,215,205,213,206,215,206,214,206,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,150,150,149,144,146,146,147,144,144,144,144,144,144,144,144,144,144,144,147,149,144,144,144,146,146,146,147,147,147,149,146,232,146,232,146,232,146,232,144,144,150,149,146,147,150,149,149,144,146,146,147,3,4,3,4,3,4,3,4,3,4,157,157,157,157,157,157,157,156,157,157,156,156,155,155,156,157,156,156,155,156,155,157,202,202,202,203,202,203,202,203,204,204,204,203,202,203,202,203,203,204,203,204,204,204,203,204,203,204,204,204,203,157,155,156,155,155,155,155,155,202,202,203,203,204,203,199,199,199,199,193,192,193,192,192,192,193,193,194,193,194,195,195,195,195,192,193,193,195,193,195,195,193,192,193,193,195,193,195,195,195,194,193,192,193,192,193,192,193,192,193,192,193,193,194,195,195,195,195,195,195,199,199,192,193,199,193,192,193,193,194,193,194,194,192,192,193,192,193,192,193,193,193 +,108,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,109,107,109,109,252,109,252,109,252,252,252,107,107,107,107,107,107,107,107,107,107,107,107,106,107,107,252,107,107,107,106,106,106,106,107,106,107,107,107,106,106,106,106,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,108,108,108,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,107,107,107,107,107,107,109,109,109,107,109,107,107,107,107,107,107,107,107,107,107,107,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,202,202,202,202,202,202,202,202,203,202,203,203,204,204,204,203,203,204,204,204,204,205,205,205,205,213,205,205,205,214,206,205,205,214,206,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,150,150,145,145,145,145,145,146,150,150,149,144,146,232,147,144,144,144,144,144,144,144,144,144,144,144,144,147,149,144,144,144,146,146,147,147,147,149,147,147,147,147,147,147,147,147,147,147,150,149,146,147,150,149,149,144,146,232,147,3,3,3,3,3,3,3,3,3,3,157,157,157,157,157,157,157,156,157,156,156,156,155,155,157,156,156,156,156,155,155,156,202,202,202,202,202,202,203,203,204,202,202,202,203,203,202,203,204,203,204,204,203,203,203,203,204,204,204,204,204,156,156,155,155,155,155,155,155,202,203,203,204,204,204,199,199,192,192,192,193,193,192,192,193,193,193,193,194,194,195,195,195,195,192,193,193,195,195,192,192,192,193,193,193,193,195,195,195,194,193,192,192,192,192,192,193,193,192,192,193,193,194,195,195,195,195,195,199,199,192,192,193,193,193,193,193,192,193,193,194,194,192,192,193,192,193,193,193,193,193,193 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,109,252,109,252,109,252,109,252,109,107,107,252,107,107,107,252,107,252,107,107,106,107,107,107,107,107,107,107,106,106,106,107,106,107,107,107,106,107,106,106,106,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,108,108,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,252,107,109,107,252,107,109,107,109,107,109,107,107,107,107,107,107,107,107,107,107,107,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,202,202,202,203,202,203,202,202,202,203,202,203,203,204,204,204,203,204,203,204,203,215,204,215,205,215,205,215,205,213,213,214,206,214,206,206,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,150,150,150,149,144,144,146,147,150,150,149,144,146,146,147,144,144,232,144,232,144,232,144,232,144,144,144,144,147,147,144,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,150,150,149,149,144,146,146,147,3,4,3,3,3,4,4,4,4,4,157,157,157,157,157,157,156,156,156,157,156,156,155,155,156,157,156,156,155,156,155,157,202,203,202,202,202,203,203,204,202,202,202,203,203,204,203,204,204,204,204,203,203,204,203,204,203,204,203,204,156,157,155,156,155,155,155,155,202,203,202,203,203,204,199,199,199,193,192,193,192,193,192,193,192,193,193,194,193,194,195,195,195,192,192,193,193,195,195,192,192,193,192,193,193,195,195,195,194,193,192,192,192,193,192,193,192,193,193,192,194,194,193,195,195,195,195,199,199,192,199,193,199,193,192,193,192,193,194,194,192,193,192,193,192,193,192,193,193,194,193,193 +,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,109,109,109,109,109,252,109,252,252,252,107,107,107,107,107,107,107,107,107,107,107,107,106,107,107,252,107,107,107,106,106,107,106,107,107,107,106,107,106,106,106,106,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,108,252,108,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,107,107,107,107,109,109,109,107,109,107,109,107,107,107,107,107,107,107,107,107,107,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,202,202,202,202,203,202,202,202,203,203,202,203,203,204,203,203,204,203,204,204,204,204,205,205,215,205,205,205,213,205,213,213,213,213,214,206,206,206,3,3,215,206,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,150,150,150,149,149,144,146,147,150,150,232,144,146,146,147,144,144,144,144,232,144,232,144,144,144,144,144,144,144,144,147,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,149,232,144,146,152,152,153,153,153,153,153,153,154,153,154,154,157,157,157,157,157,156,156,157,157,156,156,155,155,155,157,156,156,156,156,155,155,202,202,202,202,202,203,203,204,202,202,202,202,202,203,203,204,204,204,204,204,203,204,203,204,204,204,204,204,204,157,156,156,155,155,155,155,155,202,202,203,203,204,199,199,199,192,192,193,192,193,193,192,192,193,193,193,193,194,194,195,194,195,192,192,193,193,193,195,195,192,193,193,193,195,195,195,194,193,192,192,192,192,192,193,193,193,194,194,193,194,195,195,195,195,195,199,192,192,192,193,193,193,193,193,192,193,193,192,192,192,192,193,193,193,193,193,193,193,193,193,193 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,109,252,108,252,107,107,107,252,107,252,107,252,107,107,107,107,107,107,107,107,107,107,106,106,106,107,107,107,106,106,106,106,106,106,106,106,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,108,108,108,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,109,107,107,107,252,109,109,107,109,107,109,107,109,107,107,107,107,107,107,107,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,202,202,202,203,202,204,202,202,202,203,202,203,204,204,203,204,203,204,203,204,204,215,204,215,205,215,205,215,205,215,205,213,206,214,206,206,206,215,205,213,206,214,206,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,148,148,148,148,148,148,148,150,150,149,144,146,146,147,144,144,144,144,144,144,144,144,144,144,144,232,144,144,144,144,147,146,146,232,146,146,146,232,146,146,146,232,146,146,146,146,146,232,146,146,146,146,149,149,152,152,157,156,157,157,156,152,152,153,153,153,153,154,157,157,157,157,157,157,156,157,156,157,156,156,155,157,155,157,156,156,155,156,155,202,202,203,202,203,203,204,204,203,202,202,202,203,203,204,204,204,203,204,204,204,203,204,203,204,203,204,204,204,156,156,155,156,155,155,155,155,202,203,203,204,204,199,199,193,192,193,192,193,192,192,192,193,192,193,193,194,193,194,195,195,192,192,192,193,192,193,193,195,195,193,193,195,195,195,195,194,192,193,192,192,192,193,192,193,194,194,194,194,193,195,195,195,195,199,199,192,192,193,192,193,192,193,192,193,192,192,192,193,192,193,192,193,192,193,193,194,193,194,194,193 +,108,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,252,252,108,252,107,107,107,107,107,107,107,107,107,107,107,106,107,106,107,107,107,106,106,106,107,107,107,106,106,106,107,106,106,106,106,106,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,108,108,108,108,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,107,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,202,202,202,202,202,204,202,203,202,202,203,203,204,202,203,203,203,203,204,204,204,204,215,205,205,205,213,205,205,205,215,205,205,205,213,205,205,205,213,213,214,206,206,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,2,3,3,150,150,149,149,149,149,149,150,150,149,144,146,232,147,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,147,147,147,147,147,147,147,147,147,147,147,146,146,146,232,146,232,146,232,146,146,149,157,157,156,156,157,157,157,156,155,156,155,155,152,152,157,157,157,157,157,157,156,156,157,156,156,156,155,157,156,155,156,156,156,156,155,202,202,202,202,202,202,204,204,203,202,203,203,204,204,204,204,203,203,204,204,204,203,204,204,204,204,204,204,204,204,157,156,156,155,155,155,155,155,203,203,204,204,199,199,192,192,192,192,192,192,193,192,192,192,193,193,193,193,194,194,195,195,192,192,192,192,193,193,193,193,195,195,193,193,195,195,194,194,192,192,192,192,192,192,193,193,194,194,194,195,195,195,195,195,199,199,192,192,193,192,193,193,193,193,192,192,192,192,192,192,193,193,193,193,193,193,193,193,193,193,193,193 +,252,252,108,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,109,109,109,252,109,252,252,252,108,252,107,107,107,107,107,252,107,252,107,107,107,107,106,107,107,107,107,106,106,107,106,107,107,106,106,107,106,106,106,106,106,106,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,108,252,108,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,107,109,252,107,109,107,109,107,109,107,109,107,109,107,107,107,107,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,202,202,202,203,202,203,202,202,202,202,203,204,204,204,203,204,203,204,203,204,203,215,204,215,205,215,205,215,205,215,205,213,205,213,205,215,205,213,205,213,205,214,206,206,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,150,232,149,149,149,149,149,150,150,149,144,146,146,147,144,144,113,114,114,114,114,114,114,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,147,147,146,146,146,146,146,146,146,146,157,157,156,156,155,157,157,157,156,155,156,156,155,156,156,157,157,157,157,157,156,156,157,157,156,156,155,156,157,156,155,157,156,156,155,156,202,202,202,203,202,203,203,202,202,203,203,204,203,204,203,204,203,204,204,204,203,204,203,204,203,204,204,204,204,204,156,157,155,156,155,155,155,155,203,203,203,204,199,199,192,193,192,193,192,193,193,192,192,193,192,193,193,194,194,194,194,195,192,192,192,193,193,195,193,195,193,195,193,195,193,194,194,192,192,193,192,192,192,193,192,194,194,194,194,195,194,195,194,195,199,199,192,193,192,193,192,193,193,193,192,193,192,193,192,193,192,193,192,193,193,194,193,194,193,194,193,194 +,252,252,108,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,109,109,109,109,252,252,252,252,108,252,107,107,107,107,107,107,252,107,107,107,107,107,107,106,107,107,107,106,106,106,107,107,106,106,107,106,107,106,106,106,106,106,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,108,108,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,109,107,109,109,107,109,107,109,107,109,109,109,109,109,107,107,107,107,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,202,202,202,202,202,204,203,202,202,202,203,203,204,203,203,203,204,204,204,204,215,204,215,205,215,205,213,205,215,205,215,205,215,205,215,205,215,205,213,206,215,214,206,206,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,150,150,149,149,149,149,149,150,150,232,144,146,146,147,144,113,113,113,113,113,113,113,114,114,114,114,114,114,114,114,113,113,114,114,114,114,114,144,144,144,144,144,144,144,147,146,146,146,146,146,157,157,157,157,156,156,155,157,157,157,156,155,156,155,155,156,156,157,157,157,157,157,157,156,157,157,156,156,156,155,157,156,156,155,156,156,156,155,202,202,203,203,204,204,203,202,202,203,203,203,204,204,203,203,204,204,204,203,204,203,204,204,204,204,204,204,204,157,157,156,156,155,155,155,155,202,203,203,204,199,199,192,192,192,192,192,193,193,193,192,192,192,193,193,193,193,194,194,195,195,192,192,192,192,193,193,195,195,195,193,195,193,195,194,194,192,192,192,192,193,192,192,193,193,194,194,195,195,195,194,195,195,199,192,192,192,193,192,193,193,193,193,192,192,192,192,192,192,193,192,193,193,193,193,193,193,193,193,193,193 +,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,108,109,252,109,252,108,252,107,107,107,252,107,252,107,252,107,252,107,106,107,107,107,107,107,106,106,107,106,107,106,106,106,107,106,106,106,106,106,106,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,108,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,107,109,107,109,252,107,109,107,252,107,109,107,109,107,109,107,107,107,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,202,202,202,203,202,203,204,202,202,203,203,204,204,204,203,204,204,204,205,215,205,215,205,215,205,213,205,215,205,215,205,213,205,213,205,213,205,213,205,213,206,214,214,206,206,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,150,150,149,232,149,149,149,150,150,149,144,146,146,147,144,115,115,115,115,116,115,115,115,116,115,113,113,113,113,113,113,113,113,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,157,157,157,157,156,156,155,157,157,157,156,155,155,156,155,156,156,157,157,157,157,157,156,156,157,157,156,156,155,157,156,156,155,155,156,156,155,202,202,203,202,203,203,204,202,202,202,203,203,204,204,203,203,204,203,204,199,192,193,194,203,204,203,204,203,204,204,157,156,156,155,156,155,155,202,203,203,204,202,199,199,192,192,193,192,193,192,193,192,192,192,193,192,193,193,194,193,194,195,195,192,192,192,193,192,195,193,195,195,195,193,195,194,194,192,192,192,193,192,193,192,193,192,193,194,195,194,195,195,195,193,195,199,192,192,193,192,193,192,193,193,193,192,193,192,192,192,193,192,193,192,193,193,194,193,192,193,194,194,193 +,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,109,109,252,107,252,252,252,252,108,252,107,107,107,107,107,107,107,107,252,107,252,107,106,107,106,107,106,106,107,106,107,107,106,106,107,106,107,106,106,106,106,106,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,108,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,107,107,107,109,109,107,107,107,109,109,109,107,109,107,107,107,107,107,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,202,202,202,202,203,202,203,202,204,202,203,203,204,203,204,204,215,205,215,215,215,205,213,215,215,205,215,215,215,205,215,215,215,205,215,215,215,205,213,213,213,205,206,214,206,206,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,150,145,147,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,150,150,149,149,149,149,149,150,150,113,113,113,113,113,116,115,116,115,116,116,116,116,116,116,116,116,117,117,117,117,117,117,116,116,113,113,113,113,113,114,114,114,114,114,114,114,114,114,114,114,157,156,157,156,156,156,155,157,155,157,156,155,156,156,155,156,156,157,157,157,157,157,156,155,155,157,156,156,156,157,157,156,156,155,156,155,156,202,202,202,203,203,203,203,202,202,203,203,204,204,204,204,204,204,203,199,192,192,193,193,194,204,204,204,204,204,204,157,157,156,156,155,155,203,203,203,204,202,199,199,192,192,192,192,193,193,193,193,192,192,192,192,193,193,193,193,194,194,195,195,192,192,192,192,193,193,193,195,195,193,195,195,194,194,192,192,192,192,192,193,192,192,192,192,193,194,195,195,195,195,195,199,199,192,192,192,193,193,193,193,193,193,192,192,192,192,192,192,193,193,193,192,193,193,193,193,194,194,194,193 +,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,252,252,252,108,252,107,252,107,107,107,252,107,252,107,252,107,252,107,106,107,106,106,106,106,107,107,107,106,107,106,107,106,106,106,106,106,106,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,108,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,252,109,107,107,252,109,109,109,252,109,252,107,109,107,109,107,109,107,107,107,107,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,202,202,203,202,203,202,203,203,202,202,202,202,204,204,204,204,215,204,215,205,215,205,215,205,213,205,215,205,215,205,215,214,214,205,2,205,213,205,215,205,213,206,214,205,206,214,206,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,150,144,147,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,113,113,113,113,113,113,113,113,115,116,115,116,115,116,116,116,116,116,116,117,116,117,116,117,116,117,117,117,116,117,116,117,116,117,116,117,116,117,116,113,113,113,113,113,113,113,113,113,113,157,157,156,157,157,156,156,155,157,157,157,155,155,156,156,155,155,156,157,157,157,157,157,156,156,155,157,156,156,155,157,156,156,155,156,155,202,202,202,202,203,203,204,203,202,202,203,202,203,203,204,204,204,204,199,199,192,192,193,193,194,193,194,203,204,204,204,204,204,156,157,155,156,192,194,194,204,204,203,199,192,199,193,192,193,192,193,192,193,192,193,192,193,193,194,193,194,194,194,195,192,192,193,192,193,193,195,193,195,195,195,193,194,194,192,192,192,192,192,192,192,192,193,192,193,193,195,195,195,194,195,195,199,192,193,192,193,192,193,192,193,193,194,192,193,192,193,192,193,192,192,192,193,193,194,193,194,193,194,193,193 +,252,252,252,252,252,252,252,108,109,252,252,252,252,252,252,252,252,252,109,109,109,108,252,252,252,252,252,252,107,107,107,107,107,107,252,107,252,107,252,107,252,107,106,107,106,106,107,106,107,107,106,106,107,106,107,106,106,106,106,106,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,252,108,252,252,252,252,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,252,109,252,107,107,252,107,109,107,109,252,109,252,107,252,252,109,109,107,107,107,107,107,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,202,202,202,202,202,203,202,202,204,202,203,202,204,204,204,215,204,215,215,215,205,213,215,213,215,215,215,215,213,215,213,214,214,215,2,2,205,215,215,215,215,213,213,215,213,206,214,206,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,150,144,147,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,113,113,115,115,115,115,115,115,115,115,115,116,115,116,116,116,116,116,116,116,116,116,116,117,117,117,117,117,117,116,116,116,116,116,116,117,116,117,116,117,117,117,117,117,117,117,117,117,117,117,117,117,157,157,156,157,156,156,156,157,157,156,155,155,156,156,155,155,155,157,157,157,157,157,156,156,155,155,156,157,155,156,157,157,156,156,155,202,202,202,202,202,202,203,203,204,202,202,202,203,203,203,204,204,199,199,192,192,192,193,193,193,193,194,194,204,204,204,204,204,204,157,156,192,192,193,193,194,194,194,199,199,192,192,192,193,193,194,192,193,193,192,192,193,193,193,193,194,194,194,195,195,192,192,192,193,193,193,193,195,195,195,193,194,194,194,192,192,192,192,192,193,192,192,193,193,195,195,194,195,195,195,195,195,199,192,192,193,192,193,193,193,193,193,193,192,192,192,192,192,192,192,192,193,193,193,193,194,194,194,193,194,194 +,252,252,252,252,252,252,108,109,252,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,109,252,252,252,252,107,107,252,107,252,107,252,107,252,107,252,107,252,107,106,107,106,107,107,107,107,106,106,106,107,106,106,106,106,106,106,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,108,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,107,107,252,109,252,109,107,109,252,109,252,252,252,252,252,107,109,107,107,107,107,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,202,202,203,202,203,202,202,203,204,203,204,203,204,203,204,204,215,215,215,205,215,205,213,205,215,205,215,205,213,213,214,214,2,2,2,205,213,205,213,205,213,205,213,213,215,214,206,206,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2,150,144,147,2,1,2,2,2,1,2,1,2,1,2,2,2,1,2,1,2,113,113,113,116,113,113,113,115,115,117,117,117,117,117,116,117,116,117,117,116,115,116,116,117,116,117,116,117,116,117,116,116,116,117,116,117,116,117,116,117,116,117,116,117,116,117,116,117,116,117,116,117,116,117,117,117,117,117,117,157,157,156,157,157,156,156,157,157,156,156,155,156,155,156,155,155,157,157,157,157,157,157,156,156,155,157,156,155,157,157,156,156,155,202,202,202,202,202,202,203,202,203,202,202,202,203,202,203,203,204,199,199,192,192,192,193,193,193,193,194,193,194,194,204,204,204,204,204,192,192,192,193,193,194,193,194,193,199,192,199,192,193,192,194,194,193,192,193,192,193,192,193,193,194,193,194,194,195,195,193,192,193,192,193,193,195,195,195,193,195,193,194,192,193,192,192,192,193,192,192,192,193,193,195,195,195,194,195,194,195,193,199,192,193,192,193,192,193,193,194,193,194,192,193,192,192,192,192,192,193,192,193,193,194,193,194,194,194,194,194 +,252,252,252,252,252,252,108,108,252,252,252,252,252,252,252,252,252,252,109,109,108,108,252,109,252,252,252,252,252,107,107,107,107,107,107,107,252,107,252,107,252,107,252,107,106,107,252,107,107,107,106,106,107,106,107,106,106,106,106,106,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,252,108,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,252,252,107,109,109,109,109,252,109,252,109,252,252,252,252,252,252,107,107,107,107,107,107,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,202,202,202,202,203,203,203,202,202,204,203,202,204,204,204,204,215,204,215,215,215,215,213,215,215,215,213,205,213,213,213,213,2,2,2,1,215,215,215,215,213,213,213,205,213,213,214,214,206,214,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,150,144,147,2,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,115,115,116,117,115,115,115,115,116,116,117,117,117,116,117,117,117,117,116,116,117,117,117,116,117,117,116,116,117,117,117,116,116,116,116,116,117,116,116,116,117,116,116,116,117,117,117,116,117,117,117,117,117,117,117,117,117,117,117,157,157,156,157,156,156,155,157,156,156,155,155,156,156,155,156,155,157,157,157,157,157,156,156,155,155,156,156,155,157,157,156,156,156,202,202,202,202,202,202,202,203,202,202,202,203,203,203,203,204,199,192,192,192,192,193,193,193,193,193,193,194,194,194,194,204,204,192,192,193,193,193,193,193,194,194,194,199,199,192,192,193,192,193,193,194,193,193,192,192,192,193,193,193,193,194,194,194,194,195,192,192,192,193,193,195,195,193,193,195,194,194,192,192,192,193,192,192,192,192,192,193,194,193,194,195,194,195,195,195,195,199,199,192,192,192,192,193,193,193,193,194,194,192,192,192,192,192,192,192,192,193,193,194,194,194,194,193,194,194,193 +,252,252,252,252,252,252,108,109,252,252,252,252,252,252,252,252,252,252,109,109,108,252,108,252,252,252,252,252,252,107,107,107,107,252,107,252,107,252,107,252,107,252,107,252,107,106,107,252,107,252,106,106,106,107,106,107,106,106,106,106,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,108,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,107,107,107,252,109,252,109,252,109,252,109,252,109,252,252,252,107,107,107,109,107,107,107,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,202,203,202,203,202,203,202,202,202,203,204,204,203,204,203,204,204,215,215,215,215,215,205,215,205,215,205,213,213,214,213,214,1,2,1,2,215,215,205,215,205,213,205,213,213,214,205,206,214,206,214,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,150,149,149,144,147,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,115,115,116,117,115,115,115,116,116,117,117,117,116,117,116,117,117,117,116,116,116,117,116,117,117,117,116,117,117,116,117,116,116,117,116,117,116,117,116,117,113,113,113,114,113,114,114,114,114,114,114,114,114,114,114,114,114,114,157,157,156,156,157,157,156,156,157,157,156,156,155,156,156,156,156,155,157,157,157,157,157,157,155,155,156,156,155,155,156,157,156,156,155,203,202,202,202,203,202,202,202,202,202,202,202,203,203,204,199,192,192,192,192,193,192,193,193,194,193,194,193,194,194,194,192,192,192,193,193,193,193,194,193,194,193,194,199,192,192,192,192,193,193,194,194,193,192,192,192,193,192,193,193,194,193,194,194,194,195,193,193,192,193,195,192,195,193,195,193,194,194,192,192,193,192,192,192,193,192,193,192,195,193,195,195,195,194,195,195,195,192,192,192,193,192,193,193,194,193,194,192,194,192,193,192,193,192,193,192,193,192,193,193,194,193,194,194,194,193,193 +,252,252,252,252,252,252,108,108,109,252,252,252,252,252,252,252,252,252,109,109,108,108,252,109,252,252,252,252,252,252,252,107,107,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,107,107,106,106,106,106,107,106,106,106,106,106,1,2,1,2,1,2,1,2,1,2,1,2,1,2,108,252,108,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,107,252,109,109,109,109,109,252,109,252,252,252,252,252,252,252,107,107,107,107,107,107,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,202,202,202,202,203,203,202,203,204,202,204,203,204,204,204,204,204,215,215,215,215,215,213,215,215,215,215,213,213,213,214,214,2,1,2,1,2,215,215,215,215,215,215,215,213,213,215,214,214,206,214,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,150,149,149,149,144,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,115,115,115,116,117,115,115,116,115,116,116,117,117,116,116,117,117,117,116,116,116,116,116,117,117,117,117,117,117,117,115,116,117,113,113,113,113,113,113,113,113,113,116,116,116,116,116,116,116,116,116,116,116,116,116,117,117,117,117,157,157,156,156,157,156,156,157,157,156,156,155,155,156,156,155,156,157,157,157,157,157,157,156,155,156,156,156,156,155,157,156,156,156,156,202,202,202,202,202,202,202,202,202,203,202,202,202,203,203,199,192,192,192,193,193,193,193,193,193,194,194,194,194,194,192,192,192,193,193,193,193,193,193,194,194,194,199,192,199,192,192,193,193,193,194,194,193,192,192,193,192,193,193,193,193,194,194,194,194,195,192,193,192,195,193,193,193,195,195,194,194,192,192,192,192,192,192,192,192,193,193,194,194,195,195,194,194,195,195,195,195,192,192,192,192,193,193,193,193,194,192,193,193,194,192,192,192,192,192,193,193,193,193,193,193,194,194,194,193,194,193 +,252,252,252,252,252,108,108,252,108,252,252,252,252,252,252,252,252,252,109,252,107,252,108,252,108,252,252,252,252,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,106,107,106,106,107,106,106,106,106,2,1,2,1,2,1,2,1,2,1,2,1,2,1,252,108,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,107,107,107,107,252,109,252,109,252,109,252,252,252,252,252,107,107,107,109,107,109,107,107,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,202,202,203,202,203,202,203,203,202,204,202,203,204,203,204,203,204,204,204,215,215,215,213,215,215,215,213,215,213,213,214,213,214,1,2,1,2,1,215,215,215,215,213,215,213,215,213,205,214,213,214,206,214,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,115,115,112,113,113,113,2,1,2,1,2,1,2,1,2,1,2,1,2,1,115,115,115,117,115,115,115,115,116,116,117,117,116,116,117,117,117,117,116,116,117,116,117,117,117,116,117,117,115,115,116,116,115,117,115,115,116,115,116,116,117,116,117,116,117,157,151,152,152,115,116,115,116,116,116,116,117,116,117,157,157,156,155,157,157,156,157,156,156,155,156,155,156,156,157,157,157,157,157,157,157,156,155,156,157,156,156,155,156,155,157,156,156,202,202,202,202,202,202,202,202,202,203,202,202,202,204,204,199,192,193,192,193,192,193,193,193,193,194,193,194,193,194,194,192,192,193,192,193,192,193,193,194,193,194,194,199,192,192,192,193,192,193,193,194,194,193,192,193,192,193,193,194,193,194,193,194,194,194,194,193,192,193,192,193,193,195,193,194,193,194,192,193,192,193,192,192,192,193,192,194,194,195,194,195,194,195,194,195,195,193,192,193,192,193,192,193,193,192,192,193,193,194,193,194,192,192,192,193,192,193,193,193,193,194,193,194,193,194,193,193 +,252,252,252,252,252,108,108,108,252,252,252,252,252,252,252,252,252,252,109,109,108,108,108,108,252,252,252,252,252,252,252,107,252,107,107,107,252,252,252,252,109,107,252,107,252,107,252,107,252,107,107,106,107,107,106,106,107,106,106,106,1,1,1,1,1,1,1,1,1,1,1,1,1,1,108,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,107,107,107,109,109,252,109,252,109,252,252,252,252,252,252,252,107,107,107,107,107,109,107,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,202,202,202,202,202,203,203,204,204,203,202,203,203,204,203,204,203,204,204,204,215,215,215,215,215,215,215,213,213,214,214,214,214,1,1,1,1,1,215,215,215,215,213,213,213,215,213,214,214,214,214,214,214,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,115,115,115,117,112,113,113,1,1,1,1,1,1,1,1,1,1,1,1,1,1,115,115,115,117,115,116,115,116,116,116,117,117,116,117,117,116,116,117,116,117,116,117,117,117,117,117,117,117,115,115,116,116,117,116,116,116,116,117,117,115,115,116,116,117,157,157,156,151,152,115,115,115,115,116,116,116,116,117,117,157,156,156,155,157,157,157,157,156,155,156,155,155,157,157,157,157,157,157,157,157,156,156,155,157,156,156,156,156,155,155,156,156,155,202,202,202,202,202,202,203,202,202,203,202,204,203,203,199,192,192,192,192,192,193,193,193,193,193,193,193,193,194,194,194,192,193,192,193,193,193,193,193,193,194,194,199,192,192,192,193,192,193,193,193,193,194,193,192,192,193,193,193,193,194,192,193,193,194,194,194,192,193,193,193,193,195,193,195,194,194,192,192,192,193,193,192,192,193,194,194,194,194,195,195,194,195,195,195,195,195,192,199,192,193,193,193,193,192,192,193,193,193,193,194,194,194,192,192,192,193,193,193,193,194,194,197,193,193,193,194,193 +,252,252,252,252,252,108,108,252,108,252,252,252,252,252,252,252,252,252,109,252,107,252,108,252,108,252,108,252,252,252,252,252,107,252,107,252,107,252,107,109,109,252,107,252,107,252,107,252,107,252,107,107,107,107,106,106,106,106,106,106,1,1,2,1,1,1,2,1,1,1,2,1,1,1,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,107,107,107,252,107,252,109,252,109,252,109,252,109,252,252,252,107,252,107,109,107,107,107,107,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,202,202,203,202,202,202,203,203,204,203,202,203,204,203,204,203,204,203,204,203,204,215,215,215,215,215,213,215,213,213,214,214,214,1,2,1,1,1,215,215,215,215,213,215,213,215,213,214,213,214,214,213,214,214,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,115,116,115,116,112,112,113,113,1,1,1,2,1,1,1,2,149,112,112,112,1,115,115,116,115,116,115,116,115,116,116,117,117,116,116,117,116,117,117,117,116,117,116,117,116,117,117,117,115,116,116,117,116,117,116,115,116,117,116,117,116,117,117,115,157,157,157,156,151,151,152,115,115,117,117,116,115,116,116,117,157,157,155,155,157,157,157,157,156,155,155,155,157,157,157,157,157,157,157,157,157,157,155,155,156,157,156,156,155,155,155,156,155,156,202,203,202,202,202,203,202,203,202,203,202,203,203,199,199,192,192,193,192,193,192,193,192,193,193,194,193,194,193,194,194,192,192,193,192,193,193,194,193,194,194,194,199,192,192,192,192,193,192,193,193,194,194,193,192,193,192,193,192,193,192,193,192,194,193,194,193,195,192,193,192,193,193,195,193,194,192,193,192,193,192,192,192,193,192,194,194,194,194,195,195,195,194,195,195,195,195,192,192,193,192,193,193,192,192,193,192,193,193,194,193,194,194,194,192,193,192,193,193,194,196,193,196,193,193,193,193,194 +,252,252,252,252,109,108,108,108,252,252,252,252,252,252,252,252,252,109,109,252,252,107,108,108,252,108,252,252,252,252,252,107,252,107,252,107,107,107,109,109,109,109,252,107,252,107,252,107,109,107,252,107,107,107,107,106,106,106,106,106,1,1,1,1,1,1,1,1,1,1,1,1,1,1,108,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,109,109,109,109,252,109,252,109,252,252,252,252,252,107,107,107,107,107,107,107,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,202,202,202,202,202,203,203,204,204,203,202,203,203,203,203,204,203,204,204,204,215,204,215,215,215,215,215,213,213,213,214,214,1,1,1,1,1,1,215,215,215,215,215,213,213,215,213,214,215,213,214,214,214,214,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,115,115,115,115,116,112,116,112,113,1,1,1,1,1,1,149,149,149,149,149,112,115,115,115,115,115,115,116,116,116,116,116,116,117,116,117,116,116,116,117,116,117,117,117,117,117,117,115,115,116,116,116,117,117,116,115,116,117,117,117,116,117,117,117,157,157,157,157,156,156,151,152,115,116,115,116,116,116,116,116,157,157,156,156,157,157,157,157,157,156,155,155,157,157,157,157,156,157,157,157,157,156,156,155,157,157,156,156,156,156,155,155,156,156,155,202,202,202,202,202,202,202,202,203,202,203,203,199,199,192,192,192,192,193,192,193,193,193,193,193,193,194,194,194,194,194,192,192,192,193,193,193,193,194,194,194,199,192,192,192,192,193,192,193,193,194,194,194,193,193,192,192,192,193,193,192,192,193,193,194,194,195,195,193,192,193,193,193,193,194,192,192,192,193,192,192,192,193,193,193,193,194,194,195,195,195,195,195,195,195,195,194,192,192,192,193,193,192,192,192,192,193,193,193,193,194,194,194,194,193,193,193,193,196,196,193,193,193,193,194,193,194,194 +,252,252,252,252,252,108,108,252,108,252,252,252,252,252,252,252,252,109,109,252,252,108,107,252,108,252,108,252,108,252,252,252,107,252,107,252,252,109,109,252,109,107,107,252,107,252,107,109,107,107,107,252,107,107,107,107,106,107,106,106,19,19,19,19,19,19,19,19,19,19,19,19,19,19,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,252,107,252,107,252,109,252,109,252,109,252,109,252,109,252,252,252,107,107,107,109,107,109,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,202,202,202,203,202,202,202,203,203,204,203,202,202,203,202,203,203,204,203,204,204,204,215,215,215,215,215,213,215,214,213,214,213,19,19,19,19,19,215,215,215,212,215,215,215,213,215,213,213,214,213,214,213,215,214,214,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,115,115,115,117,117,112,117,116,112,112,19,19,19,19,149,149,149,149,115,115,112,112,112,115,115,115,116,115,116,116,116,116,117,116,117,117,117,116,117,116,117,116,117,117,117,115,115,115,116,116,117,116,117,115,116,115,116,116,117,116,115,117,117,157,157,157,157,157,156,155,151,152,116,115,116,115,116,115,116,115,157,156,156,157,155,157,157,157,156,155,155,157,157,157,157,156,156,157,157,156,157,155,157,157,157,156,157,156,156,155,156,155,156,155,202,202,203,202,203,202,203,202,203,202,202,203,204,199,192,192,192,192,192,192,193,192,193,192,194,192,194,193,194,193,194,192,193,192,193,193,192,192,193,193,194,194,192,192,192,192,193,192,193,192,193,193,194,194,194,193,194,192,193,193,193,192,193,192,194,193,194,195,195,192,193,193,195,193,194,193,192,192,193,192,192,192,193,192,193,193,193,194,194,194,195,195,195,194,195,194,195,194,192,192,193,192,192,192,193,192,193,192,193,193,194,193,194,193,194,192,193,192,193,196,193,196,193,193,194,193,194,194,194 +,252,252,252,252,109,108,108,108,252,252,252,252,252,252,252,252,252,252,109,109,109,107,108,108,252,108,252,107,252,252,252,252,252,107,252,107,109,107,109,109,252,109,252,107,252,107,252,107,109,107,107,107,252,109,109,107,107,106,107,106,106,20,20,20,20,20,20,20,20,20,20,20,20,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,109,107,109,109,252,109,109,109,252,252,252,252,252,252,252,107,252,107,107,107,107,107,107,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,202,202,202,202,202,202,203,203,204,204,202,202,202,202,203,203,203,203,204,204,204,215,204,215,215,215,215,215,213,213,214,214,214,20,20,20,20,215,215,215,215,215,215,215,213,213,215,213,213,215,213,213,214,205,214,214,214,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,115,115,115,115,117,115,117,112,117,112,112,112,112,112,116,115,116,116,117,116,115,115,116,116,115,115,115,115,116,116,116,116,117,116,117,117,117,117,117,117,117,117,117,117,115,115,115,115,116,116,116,116,117,115,116,117,116,116,116,116,115,117,117,157,157,157,157,157,157,156,156,151,151,155,115,115,116,116,116,116,117,157,156,157,157,156,155,157,157,155,155,157,157,157,157,157,157,156,157,156,157,155,157,157,157,157,157,156,156,156,156,155,155,155,155,202,202,202,202,202,203,203,202,202,203,202,204,199,192,192,192,192,192,192,192,192,192,192,192,192,194,194,194,194,194,192,192,192,192,192,193,193,193,193,194,194,199,192,192,192,192,192,193,192,193,193,194,194,194,192,193,192,193,192,193,192,193,192,194,193,194,194,195,195,193,193,193,193,194,194,192,192,193,192,193,192,192,192,193,193,193,193,194,194,195,195,195,195,195,195,195,195,199,192,192,192,193,192,192,192,193,193,193,193,193,193,194,193,194,194,192,192,193,192,193,193,193,193,194,193,194,193,194,194 +,252,252,252,252,252,108,108,252,108,252,252,252,252,252,109,252,252,252,109,109,109,252,107,108,108,252,108,252,107,252,109,252,252,252,107,252,107,109,107,109,109,252,109,107,107,252,107,252,107,107,107,252,109,109,107,109,107,107,106,106,106,106,20,20,20,20,20,20,20,20,20,20,20,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,107,107,107,107,107,109,107,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,202,202,202,203,202,203,202,203,203,204,202,203,202,203,203,204,203,204,204,204,204,204,215,204,215,215,213,215,214,215,215,214,214,20,20,20,215,215,215,212,215,213,215,215,215,215,215,215,215,215,214,214,214,215,213,214,214,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,115,115,116,115,116,117,115,116,112,116,117,112,116,115,115,115,116,116,117,115,117,115,116,115,117,115,116,115,116,116,117,116,117,116,117,116,117,115,117,115,116,116,117,115,115,115,115,115,116,115,115,115,117,115,116,116,117,115,116,116,117,115,117,157,157,157,157,155,151,157,156,155,156,151,152,116,117,116,117,116,117,117,157,155,157,156,156,155,157,156,155,155,157,157,157,157,157,156,157,156,157,155,157,156,157,157,157,156,157,156,156,155,156,155,155,155,202,202,203,202,203,202,203,202,203,202,202,199,199,192,192,192,193,193,192,192,194,192,193,192,193,193,194,193,194,193,192,192,192,192,193,192,193,193,194,193,194,192,192,192,192,192,193,192,193,193,194,194,194,192,192,192,193,192,193,192,193,192,194,193,194,194,194,195,195,192,193,193,194,193,192,192,193,192,193,192,192,192,193,192,193,193,194,193,194,194,195,194,195,195,195,195,194,193,193,192,193,192,197,192,193,192,193,192,193,193,198,193,194,194,198,192,193,193,197,192,193,193,194,193,194,193,194,193,194 +,252,252,252,252,109,108,108,108,109,252,252,252,252,252,252,252,252,252,109,109,109,109,109,107,108,108,252,252,252,252,252,252,252,107,252,107,252,107,109,109,109,109,109,107,107,107,252,107,109,109,107,107,107,109,109,107,107,107,107,106,106,106,106,20,20,20,20,20,20,20,20,20,20,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,107,107,107,107,107,107,107,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,202,202,202,203,203,204,203,204,203,202,204,202,202,203,203,203,203,204,204,204,204,204,204,204,215,215,215,215,215,213,214,215,213,214,20,20,20,215,215,215,215,212,215,215,215,215,215,213,215,213,215,214,213,214,215,213,213,214,213,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,115,115,115,115,115,115,116,116,115,117,112,117,112,116,115,115,115,116,116,116,115,117,117,116,116,117,115,115,115,116,116,116,117,117,117,116,116,117,115,116,116,117,115,115,115,115,115,116,115,115,115,115,115,116,115,117,116,117,117,117,116,116,115,116,157,157,157,157,156,156,155,151,156,156,156,155,151,155,116,117,117,117,157,156,156,157,156,156,155,155,157,155,156,157,157,157,157,157,156,157,157,156,156,155,156,157,157,157,157,157,156,155,156,157,156,156,155,155,202,202,202,202,202,203,203,202,202,203,199,199,192,192,192,192,192,193,193,193,192,192,192,193,193,192,193,194,194,194,192,192,192,193,193,193,193,193,193,194,192,192,192,193,192,193,193,193,193,193,194,194,192,192,192,192,192,193,192,194,193,193,193,194,194,194,195,195,195,195,193,193,194,192,192,193,192,192,192,193,192,193,193,193,193,193,194,194,194,195,195,195,195,195,195,195,194,192,192,193,192,192,192,193,192,193,193,193,193,193,193,194,194,192,192,192,193,193,193,193,193,193,193,194,193,194,194,194,194 +,252,252,252,252,252,108,108,252,108,252,252,252,252,252,109,252,252,252,252,109,109,109,109,252,107,252,109,252,109,252,252,252,109,252,252,252,107,252,107,109,109,252,109,108,107,252,107,252,109,252,107,107,107,252,107,107,107,107,107,107,106,106,106,20,21,20,20,20,21,20,21,20,21,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,109,107,252,107,252,107,252,109,252,109,252,109,252,109,252,109,252,107,109,107,107,107,107,107,107,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,202,202,202,203,202,203,203,204,204,202,203,202,202,203,202,203,203,204,204,204,203,204,204,204,204,204,215,215,202,215,213,214,215,215,214,21,20,215,215,212,215,212,215,215,215,213,213,213,213,212,205,213,211,213,213,215,205,214,213,214,211,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,115,115,115,115,116,115,115,115,116,116,117,116,112,117,116,115,116,115,116,116,117,115,116,117,117,116,117,115,116,115,115,115,116,116,117,117,116,115,117,115,115,115,116,115,116,115,116,115,116,115,115,115,117,115,116,115,116,116,117,116,117,117,117,117,117,117,157,157,157,156,156,157,155,151,156,155,156,155,155,151,117,117,117,156,157,156,157,156,157,155,156,155,157,156,157,157,157,156,157,157,157,156,157,156,156,155,157,157,157,156,156,155,156,155,155,156,156,155,155,202,202,202,203,202,203,203,204,203,202,196,199,192,192,192,192,192,193,192,193,193,192,192,193,192,192,194,194,193,194,192,192,192,193,192,193,193,194,193,194,193,192,192,193,192,193,193,193,193,193,194,194,192,192,192,192,193,192,192,193,193,194,194,194,194,194,195,195,195,195,195,193,193,192,192,193,192,193,192,192,192,193,193,193,193,193,194,195,194,195,194,195,194,195,197,195,194,194,192,197,192,197,192,193,192,196,192,197,193,197,193,194,193,198,192,197,192,197,193,193,193,197,193,197,193,194,193,197,194,194 +,252,252,252,252,109,108,108,108,252,252,109,252,252,252,252,252,252,252,252,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,108,108,252,107,109,109,109,109,107,107,109,109,252,109,252,107,107,109,107,107,107,107,107,107,107,107,106,106,20,20,20,20,20,20,20,20,20,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,109,107,252,109,109,109,252,252,252,109,252,252,252,252,252,107,109,107,107,107,107,107,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,202,202,202,202,202,203,203,203,203,204,204,203,202,202,204,203,202,203,203,203,203,204,204,204,204,204,204,202,204,204,204,215,214,214,215,215,20,20,215,215,215,215,215,215,215,215,215,215,215,213,212,215,215,211,214,213,215,212,213,213,213,213,211,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,80,83,86,89,92,95,115,115,115,116,116,117,116,117,112,116,115,115,115,116,116,116,116,117,117,116,116,117,115,115,116,116,115,116,117,116,116,117,115,116,115,115,115,115,115,115,115,116,116,116,115,115,115,115,115,116,115,115,116,116,117,117,116,117,117,117,117,157,157,156,155,155,157,156,151,155,151,156,155,155,151,151,155,157,157,156,156,156,157,157,156,156,155,155,157,157,157,157,157,157,157,157,155,157,157,156,155,155,157,157,156,156,156,156,155,155,155,156,155,156,155,202,202,202,202,202,203,203,204,204,203,199,192,192,192,192,192,192,192,193,193,193,192,192,192,192,194,193,193,193,192,192,192,193,192,193,193,193,193,194,194,192,192,193,192,193,192,193,193,193,194,194,193,192,192,193,192,193,192,193,192,194,193,194,194,194,195,195,195,195,193,195,193,192,192,193,192,193,192,192,192,193,192,193,193,193,194,195,194,195,195,195,195,195,193,195,195,194,196,193,193,193,192,193,192,193,192,193,193,193,193,194,193,194,194,192,192,193,192,193,193,193,193,193,193,194,193,194,194,193,194 +,252,252,252,252,252,109,108,108,108,252,108,252,252,252,109,252,252,252,252,252,109,252,109,109,109,252,109,252,109,252,109,252,252,252,252,252,107,108,108,109,109,252,109,108,107,252,107,252,107,252,109,109,109,252,107,107,107,107,107,107,107,107,107,106,106,20,21,20,21,20,21,20,21,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,252,107,252,107,252,107,252,109,252,109,252,109,252,109,252,252,109,107,107,107,107,107,107,107,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,202,203,202,203,202,203,203,204,203,204,204,202,202,204,204,203,202,203,203,204,209,202,203,204,209,204,202,202,203,203,203,204,203,213,214,204,215,215,20,215,215,215,215,212,215,212,215,215,215,215,215,213,212,215,212,211,213,215,205,212,212,213,211,213,211,21,20,20,20,20,20,20,35,38,41,44,46,32,34,37,38,41,42,45,46,32,33,48,51,54,57,60,62,44,45,47,32,33,34,36,48,50,51,54,55,58,59,62,62,48,53,58,62,37,38,41,41,44,48,50,51,53,54,57,57,60,61,63,115,115,115,116,115,116,115,116,115,115,115,115,115,116,115,116,115,116,116,117,117,117,117,117,157,157,157,157,156,156,157,157,156,156,155,151,155,156,155,155,155,151,156,157,199,199,199,193,156,156,155,156,157,157,157,157,156,157,157,157,156,155,157,157,156,156,155,157,156,157,156,156,155,156,155,155,155,156,155,155,202,202,202,203,202,203,203,204,202,199,192,193,192,193,192,193,192,193,193,193,193,192,192,192,193,194,193,194,192,192,192,193,192,193,193,194,194,194,193,192,192,193,192,193,192,193,192,194,194,194,194,192,192,193,192,193,192,193,193,193,193,194,194,194,194,195,195,195,195,195,194,194,192,192,193,192,192,192,193,192,193,193,193,193,194,195,194,195,194,192,192,195,193,195,194,195,193,196,192,197,192,197,193,197,192,197,193,197,193,197,194,198,194,198,192,197,193,197,193,197,193,197,193,197,193,197,194,193,194,194 +,252,252,252,252,252,252,108,108,108,108,109,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,108,107,109,109,109,109,107,107,109,107,109,109,252,109,109,109,109,107,107,107,107,107,107,107,107,106,106,20,20,21,20,20,20,20,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,109,107,109,109,252,109,252,109,252,252,252,252,252,252,109,107,109,107,107,107,107,107,107,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,20,21,20,20,20,20,20,20,202,202,202,202,202,203,203,210,208,208,208,208,210,209,209,203,209,203,203,203,203,209,204,209,209,204,203,202,203,203,203,204,204,208,204,211,214,204,215,20,215,215,212,212,215,212,215,215,215,215,215,215,215,213,211,212,215,211,213,215,215,212,212,213,211,213,211,211,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,33,34,35,37,38,39,40,41,42,44,45,46,47,32,34,35,37,39,40,42,44,45,47,32,33,33,34,35,35,36,37,38,38,39,39,40,41,42,42,43,44,44,45,46,48,50,52,55,56,59,61,63,157,157,157,157,157,157,156,156,157,155,156,156,156,151,151,151,151,156,155,155,151,157,192,199,193,197,193,198,156,156,155,157,157,157,157,156,156,155,157,156,155,157,156,155,157,155,156,157,156,156,156,156,155,155,155,156,155,155,155,203,202,203,202,203,203,204,202,199,192,196,192,193,192,196,192,193,192,193,193,192,192,192,193,194,193,193,193,193,192,193,193,193,192,193,194,194,194,192,192,193,192,193,192,193,193,196,193,194,194,197,192,193,192,193,192,193,193,197,193,194,193,194,194,195,195,195,195,197,194,193,192,192,193,192,193,192,192,192,193,193,193,193,194,198,194,195,194,192,192,193,193,193,193,195,194,197,196,193,193,193,193,192,193,193,193,193,193,193,194,194,193,194,192,192,193,193,193,193,193,193,193,193,193,194,194,193,194,198,194 +,252,252,252,252,252,252,107,109,108,252,108,252,108,252,252,252,109,252,252,252,252,109,109,252,109,252,109,252,109,252,109,108,109,252,252,252,252,252,252,108,252,109,109,109,109,108,107,252,107,252,109,252,109,109,109,109,109,107,107,107,107,107,107,107,107,107,21,20,21,20,21,20,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,252,107,252,107,252,109,252,109,252,109,252,109,252,252,252,107,109,107,109,107,107,107,107,107,107,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,202,202,208,202,202,202,209,210,208,203,208,203,208,208,209,202,209,203,203,203,208,208,211,209,208,209,202,210,203,209,203,209,208,209,208,208,211,214,215,20,212,212,212,212,212,215,212,215,215,212,215,215,215,205,213,205,211,212,211,213,215,205,212,212,213,211,213,212,211,211,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,21,36,37,40,32,34,35,37,38,40,41,43,44,46,47,45,45,46,46,47,46,47,157,157,157,157,156,157,156,156,157,157,156,156,155,156,155,156,155,155,151,151,155,155,151,199,193,196,193,193,198,198,198,198,156,156,155,156,155,155,155,157,156,156,155,155,157,156,155,157,156,156,155,156,155,156,155,155,155,156,155,203,202,203,202,203,203,204,202,199,192,196,192,196,193,193,196,196,193,194,193,194,192,193,193,194,192,193,192,193,192,193,192,193,193,193,193,194,194,195,192,192,192,193,192,193,193,194,194,194,194,194,192,192,192,192,193,193,193,193,193,193,193,194,194,194,195,195,195,198,194,193,192,192,193,192,193,192,192,192,193,192,193,193,194,198,194,195,194,192,192,193,192,193,193,195,194,195,195,196,193,197,192,197,193,196,192,197,193,197,194,198,194,198,193,198,192,197,193,197,193,197,193,197,193,197,193,198,194,198,194,194 +,252,252,252,252,252,252,108,108,108,108,109,108,252,252,252,109,252,252,252,252,108,107,108,107,109,107,109,107,252,109,252,109,252,252,252,252,252,252,252,109,108,252,252,252,109,107,108,107,107,107,107,107,107,107,107,107,109,109,107,107,107,107,107,107,107,107,107,20,20,21,20,21,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,107,252,109,109,109,252,252,252,252,252,252,252,107,109,107,109,107,109,107,107,107,107,107,107,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,21,20,20,20,21,20,21,20,202,210,210,210,208,210,210,209,209,208,208,203,203,203,208,208,208,203,203,209,208,208,208,208,211,209,210,209,210,208,203,209,208,208,209,209,208,208,211,214,215,212,212,212,215,212,215,212,212,212,215,212,212,215,212,215,215,212,211,211,211,213,212,215,212,212,211,211,211,211,211,211,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,41,42,43,44,45,46,47,43,43,45,45,46,47,156,156,156,156,156,156,156,155,155,156,156,155,155,156,155,155,155,155,155,151,151,155,155,155,155,199,196,193,196,193,193,198,198,198,156,156,156,156,156,155,155,155,156,155,155,156,156,155,155,156,156,156,156,156,156,155,155,155,155,155,155,202,203,202,203,203,204,202,199,192,196,192,196,193,196,193,196,193,193,194,194,192,193,193,194,194,193,192,193,192,193,193,193,193,194,194,194,194,194,192,192,192,193,192,193,193,196,194,197,193,196,193,192,192,193,192,193,193,197,193,197,193,197,193,194,195,195,195,198,198,193,194,192,193,193,194,194,192,192,193,193,193,193,193,198,198,197,194,192,192,192,192,193,193,193,194,195,194,196,196,197,193,193,193,196,193,193,193,197,194,194,194,198,194,194,192,197,192,193,193,197,193,193,193,197,194,194,194,194,194,194,194 +,252,252,252,252,252,252,107,108,108,252,108,252,108,252,252,252,252,252,252,108,107,252,107,108,107,252,107,252,107,252,107,252,109,252,107,252,252,252,109,252,109,252,109,252,107,252,107,108,107,252,107,107,107,252,107,109,107,252,107,252,107,107,107,107,107,107,107,106,107,20,21,20,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,252,107,252,107,252,107,252,109,252,109,252,252,252,109,109,107,109,107,109,107,107,107,107,107,107,107,107,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,210,210,209,209,208,209,210,210,209,209,208,210,203,203,208,209,208,208,203,203,208,209,208,209,208,211,208,209,209,209,210,210,208,209,208,209,208,209,208,215,211,214,212,212,212,212,212,212,212,212,212,212,212,212,212,212,215,215,212,212,211,211,211,212,211,215,215,205,211,211,211,211,211,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,21,21,45,46,46,47,32,38,37,38,38,39,38,39,40,156,156,156,156,156,156,156,155,156,155,156,156,156,155,155,155,155,155,155,155,155,155,155,155,151,151,151,192,196,193,196,197,193,193,198,198,198,198,156,155,156,155,156,155,156,155,156,155,156,155,156,155,157,156,156,155,156,155,156,155,155,155,155,155,203,203,203,202,203,203,203,199,196,193,196,193,196,196,196,196,193,193,194,193,193,193,194,194,192,192,193,196,193,193,193,193,194,193,194,194,195,192,192,192,193,192,193,193,193,194,197,193,196,194,192,192,192,192,193,193,193,193,197,193,193,193,194,194,195,195,198,195,193,193,192,193,192,193,193,194,192,193,192,193,193,193,194,194,193,194,192,192,193,192,193,193,195,193,195,194,197,196,196,193,197,193,196,193,197,193,197,194,198,194,198,194,198,193,197,193,197,193,197,193,197,193,197,193,197,193,198,194,198,194,198 +,252,252,252,252,252,252,108,107,108,108,109,252,109,252,252,252,252,252,108,107,108,107,108,107,108,107,109,108,109,107,109,109,109,109,252,252,252,252,252,252,252,109,252,107,252,107,252,107,252,107,107,107,107,107,107,107,107,107,109,107,252,107,107,107,107,107,107,107,106,107,21,21,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,107,252,109,252,252,252,252,252,252,109,107,109,107,109,107,109,107,107,107,107,107,107,107,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,202,202,209,209,209,209,208,210,209,209,208,210,210,210,209,209,208,208,208,203,209,209,208,209,208,208,211,208,209,209,208,210,209,209,208,208,209,209,208,208,208,215,211,211,212,212,212,212,212,212,212,212,212,215,212,215,215,212,212,212,212,212,211,211,212,212,211,212,212,212,212,211,211,211,211,20,21,20,21,20,21,21,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,20,21,20,44,20,45,20,32,34,36,37,40,41,43,45,32,33,34,35,37,38,39,40,41,47,47,53,54,56,57,59,60,62,63,48,49,51,52,54,55,57,58,60,61,63,48,50,52,58,60,61,63,48,50,52,54,55,199,193,196,193,193,193,197,198,198,197,198,198,155,155,155,155,155,155,155,155,155,155,155,155,155,156,156,156,156,155,155,155,155,155,155,155,155,202,203,202,203,203,203,199,196,193,196,196,196,197,196,196,197,197,194,194,193,193,193,193,196,192,193,196,193,193,193,193,193,193,194,195,195,193,192,192,193,192,193,193,196,196,197,194,197,196,193,194,192,193,193,193,192,193,197,193,197,193,196,194,195,194,198,195,197,193,193,192,192,192,192,193,192,193,193,193,193,193,194,194,198,194,192,192,193,192,193,193,193,193,195,195,197,197,196,196,196,193,196,193,193,193,197,193,197,194,198,194,194,194,197,193,197,192,197,193,193,193,197,193,197,193,198,194,198,194,198,194 +,252,252,252,252,252,252,252,108,107,109,108,252,108,252,252,252,252,252,108,108,107,108,107,109,107,252,107,109,108,109,108,252,107,109,109,252,109,252,252,252,252,252,252,252,107,252,107,252,252,252,109,252,107,107,107,252,107,252,107,109,107,252,107,107,107,107,107,107,107,106,107,107,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,252,107,252,107,252,109,252,109,252,109,252,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,21,20,21,20,21,21,21,20,21,20,21,20,210,210,209,210,209,209,208,208,208,208,209,210,209,209,208,208,209,210,203,203,209,209,209,209,208,209,208,209,211,209,208,209,208,209,209,208,208,209,208,209,208,208,208,215,211,212,212,212,212,212,212,212,212,212,212,215,211,215,215,212,212,212,212,212,211,211,211,212,212,212,212,212,211,212,211,212,211,211,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,47,32,34,35,38,39,42,43,45,32,35,37,40,42,45,47,62,63,48,49,52,53,56,57,60,61,63,48,50,51,54,55,58,59,61,63,48,49,52,53,56,57,60,61,63,199,196,193,196,193,197,197,198,197,198,197,198,198,156,155,155,155,155,155,156,156,156,155,155,155,156,155,155,155,155,155,155,155,155,155,155,203,203,203,203,203,203,196,192,196,196,196,196,196,196,196,197,196,193,197,194,194,193,193,192,192,193,196,193,196,193,193,194,193,194,194,195,195,192,192,193,192,193,193,197,193,196,194,197,196,196,194,192,193,192,193,194,194,196,193,197,193,197,194,194,194,195,195,197,193,193,192,193,193,192,193,193,193,193,193,193,194,194,194,198,194,193,194,193,192,193,193,195,193,195,194,195,194,197,196,197,193,197,193,197,193,198,193,196,194,197,194,198,194,198,193,197,193,197,193,197,193,197,193,197,193,198,193,198,194,198,194,198 +,252,252,252,252,252,252,252,252,108,107,108,108,109,252,109,252,252,252,252,108,108,107,108,107,108,107,108,108,109,108,109,108,252,109,109,109,252,252,252,252,252,252,252,252,252,252,252,107,252,107,252,109,252,107,107,107,107,107,107,107,252,107,252,107,252,252,107,107,108,107,106,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,252,109,252,109,252,252,252,252,252,252,109,107,109,107,109,107,109,107,107,107,107,107,107,107,107,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,210,210,209,209,209,209,208,208,209,209,208,210,209,209,208,210,209,209,209,209,209,209,209,209,209,209,209,209,208,208,208,209,208,208,211,209,208,209,209,209,208,208,208,211,211,208,211,212,212,212,212,212,212,212,212,212,212,212,212,211,212,212,212,212,212,212,211,211,212,212,212,212,211,211,211,211,211,211,211,211,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,41,20,42,43,20,44,45,45,47,47,32,33,34,35,36,37,38,32,33,34,35,36,37,38,40,41,21,42,44,45,46,47,58,58,59,59,60,60,61,61,62,62,63,63,196,196,196,196,197,197,197,197,198,198,198,198,198,198,75,75,76,77,78,78,79,53,53,53,54,156,156,155,156,155,155,155,155,155,155,155,203,202,203,203,203,196,192,196,196,196,196,196,198,198,193,193,193,193,198,194,194,197,192,196,193,196,193,196,193,193,193,193,194,195,195,195,192,192,193,192,193,193,197,193,196,193,196,193,196,193,192,193,194,193,196,193,197,193,197,193,194,193,194,195,195,198,198,193,193,192,193,192,192,193,193,193,193,193,193,198,193,198,198,194,193,192,192,194,193,193,193,193,195,195,195,194,197,196,196,193,197,193,197,193,197,193,197,194,198,194,198,194,197,194,197,193,197,193,197,193,197,193,196,193,197,194,198,194,198,194,198,194 +,252,252,252,252,252,252,252,252,252,108,107,109,108,252,108,252,252,252,252,108,108,109,107,108,107,109,107,109,108,252,108,252,108,252,108,252,109,252,107,252,109,252,109,252,252,252,252,252,107,252,107,252,109,252,107,107,107,252,107,252,107,252,107,252,107,252,107,107,252,108,107,107,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,252,107,252,107,252,107,252,109,252,109,252,252,252,107,109,107,109,107,109,107,107,107,109,107,107,107,107,107,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,210,209,210,209,209,208,208,210,210,208,209,208,210,209,210,209,210,210,210,210,210,210,210,209,209,208,209,208,209,208,208,209,209,208,209,211,209,208,209,208,209,208,209,208,211,211,208,211,212,212,212,212,212,212,212,212,212,212,212,211,211,212,212,212,212,211,212,211,211,211,212,212,212,211,211,211,211,211,212,211,211,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,33,20,34,20,35,35,37,37,38,38,39,39,40,40,42,42,43,43,44,44,45,45,47,47,32,33,35,35,37,37,39,40,42,42,44,44,46,47,63,48,50,51,54,55,58,59,62,62,59,199,196,196,196,196,197,197,198,197,198,197,198,198,198,198,198,69,71,71,72,73,74,74,76,76,78,78,79,52,53,52,54,53,55,54,55,203,203,203,203,196,199,196,196,196,196,196,196,197,198,198,197,193,198,197,194,194,196,196,193,196,193,196,193,196,194,193,194,193,195,195,196,192,193,193,193,193,197,193,196,196,196,194,196,196,197,193,197,193,196,193,197,197,197,193,197,194,194,194,194,195,198,197,193,192,193,193,193,193,193,193,193,193,193,198,194,198,198,194,193,194,196,194,193,196,193,197,195,193,195,194,197,196,196,193,197,193,197,193,197,193,198,193,198,194,198,194,198,194,197,193,197,193,197,193,197,193,197,193,197,193,198,193,198,194,198,194,194 +,252,252,252,252,109,252,252,252,252,252,108,107,109,108,109,252,109,252,252,108,108,107,108,107,108,107,108,108,109,108,109,108,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,107,252,107,252,109,109,109,108,107,107,107,107,107,252,107,252,252,107,107,252,252,108,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,109,107,252,252,252,252,252,252,252,252,109,109,109,107,109,107,109,107,107,107,107,107,107,107,107,107,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,140,141,209,209,209,208,208,208,210,208,209,208,208,209,210,210,210,210,210,209,210,209,209,208,208,208,209,209,209,209,209,208,209,209,209,208,211,209,209,208,208,208,209,208,208,211,211,208,208,211,212,212,212,212,212,212,212,212,212,212,212,211,211,212,212,212,212,212,212,211,211,212,212,212,212,212,211,211,211,211,211,211,211,21,21,21,21,21,21,21,21,32,34,37,39,42,44,47,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,32,34,36,38,41,42,45,47,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,42,42,43,43,44,44,45,46,46,47,47,32,33,35,36,37,38,40,41,42,43,45,46,47,53,54,54,196,196,196,196,197,197,197,197,198,198,198,198,198,198,198,198,198,62,63,63,64,65,67,68,69,70,72,73,74,75,77,78,79,51,52,52,203,203,203,203,199,196,196,196,196,196,197,193,193,193,198,198,193,197,195,198,194,196,196,196,196,196,193,196,193,197,194,195,195,195,195,192,193,196,193,196,193,193,197,193,198,194,197,196,197,193,197,193,196,193,197,194,197,193,194,193,194,194,195,195,198,197,193,196,193,193,193,193,193,193,193,193,193,198,194,198,198,198,198,193,193,196,192,196,193,197,193,193,195,195,196,196,196,193,197,193,197,193,197,193,197,193,198,193,198,194,198,194,197,194,197,193,197,193,197,193,196,193,197,193,197,193,198,194,198,194,198,194 +,252,252,252,252,252,252,252,252,252,252,107,108,108,109,252,252,108,252,108,252,108,252,109,252,107,109,108,109,108,252,108,252,108,252,108,252,108,252,107,252,108,252,109,252,252,252,252,252,109,252,107,252,107,252,107,252,108,252,252,252,108,252,108,252,108,252,108,252,252,108,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,252,107,252,107,252,107,252,109,252,252,252,252,109,109,109,107,109,107,107,107,109,107,109,107,107,107,107,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,21,21,20,21,21,21,20,21,20,21,21,21,20,21,21,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,21,21,21,21,20,21,20,21,21,21,21,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,21,21,20,21,21,21,20,21,20,21,21,21,20,21,21,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,20,21,20,21,21,21,21,21,20,21,21,21,20,21,21,21,21,21,20,21,139,203,140,209,209,208,208,209,209,208,209,208,208,209,210,210,210,209,210,209,210,209,209,208,209,208,209,211,208,211,209,208,209,209,209,208,209,211,209,211,209,208,208,208,209,208,208,211,211,211,211,211,211,48,49,50,51,52,53,54,55,56,57,32,34,37,38,41,42,45,47,211,211,211,32,34,34,36,37,39,40,42,42,45,45,47,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,21,21,21,20,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,49,49,50,50,196,196,196,196,197,196,197,197,198,197,198,198,198,198,198,198,198,198,198,60,199,192,196,62,63,64,65,65,67,67,69,69,71,199,196,72,203,203,203,203,199,196,196,196,196,196,193,193,198,197,198,197,198,197,195,197,198,194,196,196,196,196,193,196,194,197,194,197,195,195,195,192,193,196,193,193,193,193,197,197,196,194,198,196,196,193,197,197,196,193,197,194,197,193,197,197,194,194,195,195,198,198,194,197,196,197,193,197,193,197,193,197,193,198,194,198,198,194,198,198,193,194,193,196,193,197,193,197,195,197,195,196,197,193,197,193,197,193,197,193,197,193,198,193,198,194,198,194,198,193,197,193,197,193,197,193,197,193,197,193,198,193,198,193,198,194,198,198,198 +,252,252,252,252,109,252,252,252,252,252,252,108,108,108,109,108,252,252,252,252,252,252,252,252,108,107,108,108,108,108,108,108,252,108,109,108,252,252,252,107,252,252,252,252,252,252,252,252,252,252,252,107,252,107,108,107,252,252,252,252,252,252,108,108,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,109,107,109,107,252,252,252,252,252,252,252,252,109,107,109,107,109,107,107,107,107,107,109,107,107,107,21,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,20,21,21,21,21,21,21,20,21,21,21,40,20,48,50,51,54,55,57,59,61,63,63,139,61,62,208,48,209,209,208,208,209,50,51,210,210,210,210,210,209,209,209,209,208,208,208,209,208,208,208,211,211,209,209,209,209,208,208,208,208,211,211,209,208,208,208,208,208,208,208,211,211,205,211,205,32,34,36,37,40,41,43,45,47,32,33,34,35,36,37,38,40,41,42,42,211,211,211,211,211,211,211,211,21,21,21,21,21,21,21,32,37,42,47,21,21,21,21,21,21,21,32,35,38,41,44,47,21,21,21,21,32,46,21,21,21,21,21,21,32,34,37,39,42,44,47,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,48,49,49,49,196,196,196,196,196,197,197,197,197,198,197,198,198,197,198,198,198,198,198,192,196,196,197,197,61,62,63,63,64,65,66,66,199,196,196,196,196,196,196,196,196,196,196,198,198,197,193,193,197,198,198,198,198,198,197,195,195,196,196,196,196,197,197,197,197,195,195,195,197,195,195,193,196,193,196,193,196,193,193,196,193,197,198,196,196,197,193,196,193,197,193,197,197,197,193,198,194,195,195,194,195,194,197,196,196,193,197,193,197,193,197,197,197,194,198,194,197,198,198,198,193,196,196,193,197,197,197,195,195,195,196,196,193,197,196,197,193,197,197,197,193,197,197,197,193,198,198,198,194,197,197,197,193,197,196,196,193,197,197,197,193,198,198,198,194,198,198,194,198 +,252,252,252,252,252,252,252,252,252,108,252,108,108,109,108,109,108,252,108,252,252,252,108,252,107,109,107,109,108,252,108,109,108,252,108,252,108,252,108,252,108,252,108,252,252,252,107,252,107,252,109,108,107,252,107,252,107,252,108,252,108,252,108,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,252,107,252,107,252,107,252,107,252,252,252,109,252,252,109,107,109,107,109,107,107,107,109,107,109,107,109,107,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,21,32,21,34,21,36,20,38,21,41,43,43,20,36,47,36,57,58,59,60,62,63,63,63,209,49,130,130,130,48,210,210,210,210,209,210,209,210,209,209,208,209,208,209,208,208,211,211,208,209,211,209,208,209,208,209,208,209,208,209,209,209,208,208,208,209,208,209,208,211,211,208,211,211,21,215,215,215,215,213,212,215,215,211,214,213,215,212,213,213,213,213,211,211,211,211,212,211,211,211,21,211,21,39,47,21,21,20,21,21,21,21,21,21,21,20,21,21,21,21,21,21,21,20,21,21,21,21,21,21,21,20,21,21,21,21,21,21,21,20,21,21,21,21,21,21,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,49,196,196,196,196,196,197,197,197,196,197,197,198,197,198,197,198,198,198,196,196,196,197,197,198,60,62,61,62,62,199,199,196,192,198,197,198,198,196,196,196,197,196,197,198,193,198,193,198,197,198,198,197,197,195,197,195,196,197,196,197,196,194,196,194,197,195,197,195,195,193,196,193,196,193,196,193,193,196,193,197,197,198,196,197,197,197,193,196,196,197,194,197,197,197,194,198,198,198,195,195,197,194,197,196,197,193,197,193,197,193,198,194,198,194,198,198,197,198,194,197,196,193,196,197,197,198,197,195,197,196,193,197,193,197,193,197,193,197,193,197,193,198,194,198,194,198,194,198,194,197,193,197,193,197,193,197,193,197,193,198,193,198,193,198,198,194,198,198 +,109,252,109,252,252,252,252,252,252,252,108,252,108,108,108,108,109,108,109,252,252,252,252,252,252,108,108,108,108,107,108,107,108,107,252,108,252,107,252,252,252,252,252,252,252,252,252,107,252,107,252,107,108,107,108,107,252,108,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,109,107,252,109,252,252,252,252,252,252,252,252,109,107,109,107,109,107,107,107,109,107,109,107,107,21,21,21,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,20,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,21,21,21,20,21,21,20,21,21,20,21,21,21,21,21,21,21,21,45,21,36,20,37,21,38,38,59,60,62,63,62,32,36,40,43,47,210,210,54,210,210,209,210,209,209,209,209,208,208,208,208,208,208,211,211,211,211,208,211,211,32,33,34,35,35,37,37,38,39,40,41,42,42,44,44,45,46,47,212,215,215,215,213,21,212,21,32,39,46,21,213,213,215,205,214,213,214,21,211,211,213,32,211,39,43,47,47,21,21,21,21,21,21,21,21,21,32,35,38,41,44,47,21,32,37,42,47,44,44,44,44,44,44,44,44,44,44,44,32,36,39,43,47,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,32,32,32,32,33,33,33,34,34,34,35,35,36,36,37,37,37,38,38,39,39,39,40,40,41,41,42,42,43,43,43,44,44,44,45,45,46,46,47,47,48,48,49,49,196,196,196,196,197,196,196,197,197,198,197,197,198,198,198,197,198,198,197,196,196,196,197,197,198,60,61,61,199,192,196,192,197,197,197,197,198,198,198,198,196,197,198,198,198,197,197,197,198,198,198,197,195,197,195,195,194,197,198,198,197,197,197,197,195,197,195,195,195,196,193,196,193,193,193,196,193,196,197,194,198,196,197,196,197,193,196,193,197,194,197,197,198,194,198,194,198,195,195,195,197,196,193,197,196,197,193,197,197,197,194,198,198,198,198,198,198,198,198,197,196,196,193,197,197,198,198,197,196,196,196,196,196,196,197,197,197,197,197,197,197,197,198,197,198,196,198,198,198,197,197,196,196,196,197,197,197,197,197,197,198,198,198,194,198,198,198,194 +,252,109,252,252,252,252,252,252,252,252,252,108,252,252,252,109,108,252,108,252,108,252,109,252,109,108,108,109,108,109,108,252,108,252,108,252,108,252,108,252,108,252,108,109,108,252,252,252,252,252,108,108,108,108,107,252,107,252,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,252,107,252,107,252,107,252,109,252,109,252,252,252,252,252,252,109,107,109,107,107,107,109,107,109,107,109,107,107,21,40,21,41,21,21,21,43,21,44,21,45,21,21,21,32,21,34,21,36,21,21,21,39,21,32,21,35,21,21,21,39,21,41,21,43,21,21,21,47,21,46,21,34,21,21,21,35,21,38,21,41,21,21,21,46,21,32,21,20,21,21,21,32,21,35,21,38,21,21,21,44,21,47,21,36,21,21,21,37,21,38,21,38,21,21,21,39,21,40,21,41,21,21,21,47,21,42,21,34,21,21,21,38,21,40,21,43,21,21,21,47,21,33,21,35,21,21,21,39,21,41,21,43,21,21,21,46,21,37,21,37,21,21,21,38,21,38,21,20,21,21,21,39,21,42,21,45,32,34,35,37,38,40,41,43,44,46,47,210,210,52,52,209,55,57,210,209,210,209,209,208,209,208,208,208,208,208,208,211,211,211,211,208,211,208,208,21,209,215,208,215,213,214,215,21,214,215,212,211,211,211,211,211,37,40,41,44,45,47,213,215,213,215,32,34,35,37,38,40,41,213,211,211,213,211,211,21,211,21,21,21,21,21,32,37,41,47,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,45,45,45,45,45,45,45,45,45,32,35,40,43,47,32,33,32,33,32,32,32,33,33,34,33,34,34,35,35,36,35,36,36,37,37,38,37,39,38,39,39,40,39,41,40,41,41,42,42,43,42,43,43,44,44,45,44,45,45,46,46,47,46,47,48,49,48,49,49,50,50,196,196,196,196,196,196,197,197,198,198,198,197,198,198,198,197,198,198,197,196,197,197,198,197,198,60,192,192,196,192,197,196,197,197,198,197,198,198,198,196,197,197,198,198,198,197,198,197,198,197,198,197,195,195,195,196,198,197,198,196,197,197,195,197,195,195,195,193,193,196,193,197,193,197,193,196,197,197,198,198,196,196,198,197,198,196,196,196,197,197,197,197,198,198,198,198,195,195,194,196,194,197,193,197,193,197,197,198,197,198,194,198,198,197,198,197,198,198,197,196,193,196,197,197,198,198,197,196,196,193,197,193,197,193,197,193,197,193,198,194,198,194,198,193,198,194,198,198,197,193,196,193,197,193,197,193,197,193,198,193,198,194,198,198,198,198,198 +,109,252,109,252,252,252,252,252,252,252,108,252,108,252,108,108,109,108,109,108,252,252,252,252,252,108,108,108,108,108,108,108,109,108,108,108,252,108,252,108,252,252,108,108,252,109,252,252,252,252,109,108,108,108,108,108,252,252,252,252,252,252,108,108,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,252,109,252,109,252,252,252,252,252,252,252,252,109,107,109,107,109,107,107,107,109,109,109,109,109,107,21,21,41,20,21,21,43,21,21,20,45,21,21,21,35,20,21,21,39,21,21,21,34,21,21,21,42,21,21,21,45,21,21,21,39,21,21,21,32,20,21,21,41,21,21,20,33,21,21,21,36,21,21,21,39,21,21,21,33,21,21,21,33,20,21,21,36,21,21,20,38,21,21,21,41,21,21,21,44,21,21,20,47,21,21,21,47,21,21,21,46,21,20,21,45,21,21,21,43,20,21,21,43,21,21,20,44,21,21,21,34,20,21,21,38,21,21,21,41,21,21,21,45,20,21,21,32,21,21,20,32,21,21,21,36,21,21,21,40,21,21,20,33,21,21,34,36,36,37,38,39,39,40,41,42,43,44,44,48,49,50,51,53,54,55,56,57,58,60,60,62,63,48,49,51,51,53,54,55,56,32,33,34,35,215,215,215,215,211,211,215,215,215,215,215,215,215,215,215,215,215,212,215,213,46,46,46,46,46,46,46,46,32,212,21,215,213,214,46,46,46,46,46,46,46,46,46,46,47,21,21,21,21,21,21,47,47,47,46,46,46,46,46,46,46,46,46,46,47,47,47,47,47,32,32,32,32,32,33,33,33,33,33,33,33,32,33,33,33,33,34,34,34,34,35,35,35,35,36,36,36,36,37,37,38,38,38,38,39,39,40,40,40,40,41,41,41,41,42,42,42,42,43,43,44,44,44,44,45,45,45,46,46,46,47,47,47,48,49,49,49,49,50,50,51,51,52,196,196,196,197,196,196,196,197,197,198,197,198,198,197,197,198,197,198,193,197,197,197,197,198,198,198,192,196,192,196,196,197,197,197,197,198,198,198,196,197,197,198,198,198,197,197,197,195,195,197,197,196,197,197,197,198,198,198,198,197,197,197,197,195,197,195,197,196,196,196,193,197,197,196,196,197,194,198,197,198,196,196,197,198,193,197,194,197,196,197,197,198,197,198,195,198,198,198,197,196,196,196,197,196,197,197,197,197,198,197,198,198,197,198,197,198,198,198,197,193,196,193,197,198,198,197,196,196,196,196,196,197,197,197,197,197,197,197,197,197,197,197,197,196,198,198,198,198,197,196,196,197,196,197,197,197,197,197,197,198,198,198,194,198,194,198,198 +,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,108,109,108,109,108,252,108,252,252,108,108,108,108,109,108,109,108,252,108,252,108,252,108,252,108,108,108,108,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,107,107,107,252,107,252,107,252,107,252,109,252,109,252,252,252,252,252,252,109,107,109,107,109,107,107,107,109,107,109,107,109,107,37,21,41,21,44,21,32,21,42,21,46,21,32,21,37,21,42,21,32,21,33,21,35,21,35,21,37,21,37,21,39,21,40,21,41,21,42,21,43,21,44,21,45,21,46,21,47,21,39,21,41,21,42,21,44,21,45,21,32,21,42,21,43,21,33,21,32,21,32,21,47,21,36,21,38,21,39,21,41,21,42,21,43,21,45,21,46,21,47,21,32,21,33,21,34,21,35,21,36,21,37,21,38,21,38,21,39,21,40,21,41,21,42,21,47,21,43,21,44,21,32,21,35,21,37,21,47,21,41,21,40,21,45,21,47,21,41,21,42,21,44,21,45,21,47,21,40,21,32,21,41,203,203,202,42,39,40,40,41,41,42,42,43,42,44,44,45,44,45,45,47,209,41,209,21,209,32,46,21,209,21,208,21,209,215,215,215,215,47,208,32,34,37,39,42,44,47,212,21,211,21,47,21,215,215,213,213,215,47,47,47,47,47,47,47,47,47,47,45,46,21,211,21,211,21,21,47,47,47,47,47,47,47,47,33,32,33,32,33,32,33,32,33,32,33,33,34,33,34,33,34,33,34,34,34,32,33,32,33,33,34,33,35,34,35,35,36,35,36,36,37,36,37,37,38,37,38,38,39,39,40,39,40,40,41,41,42,41,42,42,43,42,43,43,44,43,44,44,45,45,46,45,46,46,47,46,47,100,101,101,102,102,48,48,49,49,50,49,51,50,51,51,199,196,53,52,53,196,196,196,197,196,197,197,198,198,198,198,197,196,197,197,198,197,198,197,198,196,197,197,198,198,197,193,192,196,197,196,197,196,197,197,198,197,198,196,197,197,198,195,195,197,195,195,197,197,197,197,198,197,198,197,198,197,198,197,198,197,198,195,197,195,197,196,196,196,197,197,196,196,197,197,197,197,198,196,196,198,198,198,196,196,197,197,197,197,197,197,198,198,198,195,195,195,198,196,196,197,193,197,196,197,197,198,194,198,194,197,198,197,198,198,198,198,197,197,196,196,197,197,198,196,196,196,197,193,197,196,197,193,197,197,197,194,197,197,198,194,196,197,198,197,196,198,197,193,196,196,197,193,197,197,197,193,198,197,198,193,198,194,198,197,197 +,252,252,109,252,252,252,252,252,252,252,108,252,108,252,108,252,252,108,109,252,109,252,252,252,252,252,108,108,108,108,108,108,108,108,108,108,109,108,252,108,108,108,108,108,108,108,252,108,252,108,252,252,108,108,252,108,252,108,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,107,252,109,252,252,252,252,252,252,252,252,252,252,109,107,109,107,109,107,107,109,109,107,109,107,107,36,37,37,39,39,32,21,34,34,35,36,37,38,39,21,40,41,42,43,44,44,45,21,35,37,40,42,45,32,33,21,36,37,38,39,41,42,43,21,46,47,40,32,34,35,37,21,40,41,32,34,36,38,41,21,45,47,40,41,41,41,42,21,43,43,43,43,44,44,45,21,32,34,41,37,45,40,44,21,32,47,36,37,40,38,43,21,47,41,38,32,40,33,43,21,46,34,38,35,40,36,42,21,44,38,45,39,47,40,37,21,39,41,40,33,41,32,43,21,44,44,45,32,47,37,33,21,34,47,35,34,36,32,37,21,38,42,39,47,32,47,33,21,35,39,36,40,37,40,38,21,39,210,34,203,202,203,202,203,203,210,202,203,202,203,202,203,36,203,37,204,203,202,203,203,21,203,203,204,203,204,204,204,215,215,21,209,21,213,215,214,21,215,213,215,215,212,215,215,215,32,32,32,32,32,32,32,33,32,33,214,33,33,33,215,214,214,213,214,33,33,33,33,34,33,34,34,34,34,34,34,34,34,34,34,34,34,35,34,35,35,35,35,35,35,35,35,32,32,33,33,33,33,34,34,34,34,35,196,197,197,36,36,37,37,37,37,38,38,38,38,39,39,40,40,40,40,41,41,41,41,42,42,43,43,43,43,44,44,44,44,45,45,45,45,46,46,47,47,47,97,98,98,99,99,100,100,101,48,48,49,49,49,50,50,51,51,51,52,52,52,53,192,196,196,196,198,196,196,197,196,196,196,197,197,198,198,197,197,198,198,196,198,197,197,197,197,198,198,198,198,198,198,192,196,192,196,196,196,196,197,198,197,197,197,198,197,198,195,195,197,195,195,197,197,197,197,197,197,197,197,198,198,198,198,198,198,198,196,196,196,197,196,196,196,196,196,196,196,197,196,198,197,198,198,197,196,198,198,196,196,197,196,197,196,197,197,198,197,198,198,198,198,198,198,197,196,196,197,197,197,197,197,197,198,197,197,197,197,198,197,198,198,198,198,197,196,197,197,198,196,196,196,196,196,197,196,197,197,197,197,197,197,197,197,197,197,198,196,197,197,198,196,198,197,196,196,196,196,197,197,197,197,197,197,198,197,198,194,198,198,198,197 +,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,108,109,108,252,108,252,109,252,109,108,109,108,108,109,108,252,108,109,108,252,108,108,108,108,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,108,107,109,107,252,107,252,107,252,107,252,109,252,109,252,252,252,252,252,252,109,107,109,107,109,107,109,107,109,107,109,107,36,21,37,21,39,21,40,21,42,21,43,21,45,21,32,21,36,21,39,21,42,21,46,21,38,21,32,21,34,21,36,21,39,21,42,21,32,21,34,21,36,21,38,21,33,21,35,21,36,21,43,21,40,21,42,21,44,21,46,21,47,21,42,21,43,21,32,21,37,21,42,21,47,21,32,21,34,21,35,21,36,21,37,21,38,21,40,21,46,21,35,21,32,21,33,21,36,21,43,21,36,21,37,21,38,21,39,21,40,21,41,21,42,21,42,21,43,21,44,21,45,21,46,21,47,21,32,21,32,21,32,21,34,21,35,21,37,21,38,21,40,21,41,21,43,21,44,21,46,21,47,21,32,21,32,21,32,38,32,39,32,40,32,42,32,43,32,44,32,45,32,46,32,38,32,34,32,37,32,41,32,45,32,46,32,40,32,41,32,41,32,42,32,35,36,35,36,35,36,35,36,35,36,36,36,36,36,36,36,36,36,36,37,36,37,36,37,36,37,36,37,36,37,36,37,36,37,36,37,36,37,36,37,32,33,32,33,33,34,33,34,34,35,34,35,35,36,35,36,36,37,36,37,37,38,37,196,196,197,197,198,197,197,197,198,40,41,40,41,41,42,41,42,42,43,42,43,43,44,43,44,44,45,44,45,45,46,45,46,46,47,46,47,47,101,101,102,102,96,96,97,97,48,48,49,49,50,50,51,51,52,51,199,199,196,196,196,196,198,198,56,199,196,196,197,197,198,196,197,196,197,196,197,197,198,198,197,197,198,198,198,193,199,199,197,196,197,197,198,197,198,198,198,196,196,196,196,196,196,197,198,197,197,197,198,197,198,197,195,195,195,197,197,197,197,197,198,197,198,197,198,197,198,198,198,197,198,196,196,196,197,197,198,197,198,197,198,196,196,197,197,197,198,198,196,196,196,198,198,197,196,196,196,196,197,197,197,197,198,198,198,198,198,197,198,197,196,196,197,196,197,197,197,196,197,197,198,197,198,197,198,197,198,198,198,197,196,196,198,198,196,196,197,193,197,196,197,193,197,196,197,193,197,197,198,194,198,196,197,194,198,198,196,198,197,196,197,193,197,196,197,193,197,197,198,193,198,197,198,197,198,197,197 +,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,108,109,252,109,108,252,252,252,252,108,252,108,109,108,108,108,108,252,108,108,108,108,108,108,108,108,108,108,108,252,108,252,108,252,252,108,108,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,107,109,107,252,109,252,109,252,252,252,252,252,252,252,107,109,107,109,107,109,107,109,107,109,107,107,35,33,36,35,37,37,39,39,40,41,41,43,42,45,44,47,45,32,33,34,34,35,36,37,37,38,39,40,40,41,42,43,43,44,45,46,46,47,34,40,35,41,41,42,47,44,36,45,37,46,37,47,32,39,36,41,39,43,43,45,47,47,32,38,33,32,35,34,36,37,38,40,34,42,39,44,44,47,34,36,35,37,33,39,36,40,39,41,41,43,44,44,47,45,44,46,45,34,46,35,36,36,32,37,38,38,44,39,34,41,38,42,41,43,45,44,44,45,45,46,46,47,32,35,40,36,41,36,32,36,39,40,38,40,39,42,40,32,41,37,32,42,44,47,33,44,36,42,39,42,42,47,45,46,44,46,44,46,45,46,32,46,33,46,33,32,34,32,34,32,35,32,32,32,35,32,204,203,41,32,209,203,204,215,215,40,35,35,213,36,213,36,35,214,214,215,215,36,212,215,212,36,36,36,36,36,212,36,213,214,213,214,214,37,36,36,36,37,32,32,211,33,211,33,214,34,34,34,34,35,35,35,35,36,36,36,36,37,37,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,197,197,197,197,197,198,198,198,198,198,198,198,198,198,43,44,44,44,44,45,45,45,45,46,46,46,46,47,47,47,47,97,97,98,98,99,99,100,100,101,48,48,49,49,50,50,50,51,51,52,52,53,53,54,54,55,199,192,196,196,196,196,197,198,198,198,199,196,196,196,196,198,198,198,196,197,196,196,197,197,198,198,197,198,198,198,197,199,199,196,196,198,198,197,197,198,198,198,197,196,196,196,196,196,197,198,198,198,197,197,197,198,198,198,198,197,197,197,197,197,198,197,197,198,197,198,197,198,198,198,198,198,196,196,196,197,197,197,197,198,198,198,197,196,196,197,198,197,197,196,196,197,196,198,198,198,196,197,196,197,196,197,197,198,197,198,198,198,198,198,198,197,196,196,196,197,196,197,196,197,197,197,197,197,197,198,197,198,198,198,198,198,197,197,197,196,196,196,196,197,196,197,196,197,197,197,197,197,197,197,197,198,196,196,197,197,198,198,197,198,197,196,196,197,196,197,197,197,197,197,197,198,198,198,198,198,198,197,197 +,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,108,109,108,109,252,252,252,252,252,108,109,108,109,252,108,252,108,252,108,108,108,109,108,108,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,252,252,252,109,252,252,252,252,252,252,252,252,252,109,107,107,107,107,252,107,252,107,252,107,252,109,252,109,252,252,252,252,252,107,109,107,109,107,109,107,109,107,107,107,107,21,41,21,41,21,41,21,33,21,35,21,36,21,38,21,39,21,41,21,43,21,44,21,46,21,47,21,34,21,37,21,39,21,42,21,45,21,47,21,41,21,41,21,41,21,41,21,41,21,41,21,41,21,41,21,41,21,41,21,41,21,41,21,41,21,36,21,43,21,41,21,41,21,33,21,34,21,35,21,36,21,37,21,38,21,39,21,40,21,41,21,41,21,43,21,43,21,45,21,45,21,47,21,47,21,47,21,32,21,37,21,41,21,45,21,47,21,36,21,36,21,36,21,36,21,37,21,37,21,37,21,42,21,47,21,47,21,35,21,41,21,47,21,47,21,47,21,47,42,32,43,32,44,32,44,32,45,32,45,32,46,32,47,32,47,40,37,40,38,47,39,47,32,47,33,32,34,47,35,32,36,32,37,32,38,35,35,35,34,35,34,35,34,35,35,35,36,37,36,36,36,37,36,32,32,33,32,33,33,34,33,34,34,35,34,35,34,35,35,36,35,36,36,37,36,37,36,37,37,38,37,38,38,39,38,39,39,40,39,40,40,41,40,41,41,42,41,42,41,42,42,197,196,197,196,197,197,198,197,198,197,198,197,198,198,198,197,198,46,47,46,47,47,47,102,103,96,97,98,99,100,101,102,96,96,48,48,49,49,50,50,51,51,52,52,53,53,54,53,55,55,56,55,56,56,58,196,192,196,196,196,196,197,198,197,198,198,198,192,196,196,196,196,197,197,198,197,198,196,196,196,197,197,198,198,198,197,198,198,199,196,196,196,197,197,198,198,198,197,197,198,197,196,197,196,196,197,197,197,198,197,198,197,197,197,198,197,198,197,197,197,197,198,198,197,198,197,198,197,198,198,198,198,198,198,196,196,197,197,198,197,198,197,198,197,196,196,197,198,198,197,196,196,197,197,198,197,198,198,198,196,197,197,197,197,198,198,198,198,198,198,198,197,198,196,197,196,197,196,197,196,197,197,197,197,197,197,198,197,198,197,198,197,198,198,198,197,196,196,197,196,197,196,197,196,197,196,197,193,197,197,198,197,198,197,196,193,197,197,198,198,197,198,197,193,196,196,197,196,197,197,198,193,198,197,198,197,198,197,197,197,197 +,252,252,109,252,252,252,108,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,109,252,252,109,252,252,108,252,108,252,108,252,108,108,108,108,108,108,108,108,108,108,108,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,107,109,109,252,109,252,252,252,252,252,252,252,252,252,107,109,107,109,107,109,107,109,107,107,107,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,32,21,36,21,40,21,43,21,47,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,32,21,42,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,44,21,32,33,34,21,36,21,37,21,39,21,41,21,43,21,44,21,46,21,47,21,32,21,32,21,32,21,32,21,32,21,32,21,32,44,32,46,36,44,36,45,36,45,36,46,36,47,34,203,46,46,47,47,47,40,47,203,47,203,47,34,34,34,35,34,35,34,35,34,35,34,35,32,32,32,33,33,33,33,33,33,34,34,34,34,35,35,35,35,35,35,36,36,36,36,36,36,37,37,37,37,38,38,38,38,38,38,39,39,39,39,39,39,40,40,40,40,41,41,41,41,41,41,42,42,42,42,43,42,43,43,43,43,44,44,44,196,197,197,197,197,197,197,197,197,198,197,198,198,198,198,198,197,198,198,198,101,101,102,102,102,103,103,96,48,49,49,50,50,51,51,52,52,53,53,53,54,54,55,55,56,56,57,57,58,58,59,59,59,196,196,196,192,196,196,197,197,197,197,197,197,198,198,196,196,196,196,196,197,198,198,197,197,198,198,198,198,197,197,197,198,198,198,198,198,196,196,196,196,197,197,197,198,198,197,198,197,196,196,197,197,198,197,197,198,198,198,198,198,197,197,197,198,198,197,198,197,197,197,198,198,197,197,197,197,198,198,198,198,198,198,196,196,197,197,197,198,198,196,196,196,196,197,198,198,198,197,196,196,197,197,197,197,198,197,198,197,198,198,197,197,197,197,198,197,198,198,198,198,198,197,196,196,196,196,197,196,197,197,197,197,197,197,197,197,198,198,198,198,198,197,197,197,198,196,196,196,196,196,197,196,197,197,197,197,197,197,197,197,197,197,197,196,197,197,197,197,198,197,198,197,196,196,196,196,197,197,197,197,197,197,198,198,198,198,197,197,197,198 +,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,108,252,108,252,252,252,108,108,108,108,252,108,109,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,252,107,252,107,252,107,252,107,252,109,252,109,252,252,252,252,109,107,109,107,109,107,109,107,109,107,107,34,32,35,32,37,32,38,32,39,32,41,32,42,32,32,32,33,32,34,32,36,32,37,32,38,32,39,32,40,32,41,32,32,32,34,32,35,32,37,32,38,32,40,32,41,32,43,32,44,32,46,32,36,32,38,32,40,32,42,32,44,32,47,32,39,32,42,32,45,32,32,32,46,32,35,32,36,32,37,32,38,32,39,32,35,32,41,32,46,32,35,32,36,32,32,32,33,32,34,32,32,32,32,32,33,34,34,36,35,39,35,42,36,45,37,47,38,32,38,32,21,32,21,32,21,32,21,32,21,32,21,32,21,47,21,46,21,47,21,46,21,40,21,40,21,40,46,40,37,42,38,40,39,40,32,40,32,40,39,40,46,35,35,35,35,35,35,35,35,35,35,35,35,32,32,33,32,33,33,34,33,34,33,34,34,35,34,35,34,35,35,36,35,36,36,37,36,37,36,37,215,38,37,38,37,38,38,212,38,39,39,215,39,212,39,40,211,41,40,41,40,41,42,42,42,42,42,43,42,43,42,43,43,44,43,44,43,44,44,45,44,45,45,46,45,46,45,197,196,197,196,197,197,197,197,198,197,198,197,198,197,198,198,198,197,198,197,198,198,198,48,49,49,50,50,51,51,52,52,53,53,54,54,55,55,56,56,57,57,58,58,59,59,60,60,61,61,62,196,196,196,196,196,196,196,196,196,197,196,198,197,198,198,196,196,196,196,196,196,198,197,198,197,198,197,198,197,198,197,198,198,197,197,198,198,198,198,196,196,197,196,196,196,197,197,198,197,198,197,198,197,198,196,197,197,198,198,198,197,198,197,198,197,197,197,198,198,198,197,197,197,197,198,198,197,198,197,198,197,198,197,198,198,196,196,197,197,198,197,196,196,196,196,197,197,198,197,198,197,196,196,197,196,197,197,197,197,198,197,198,198,197,196,197,197,198,197,198,197,198,198,198,197,196,196,197,196,197,196,196,196,197,197,198,198,198,197,198,198,198,197,198,197,198,196,196,196,197,196,197,196,197,196,197,196,197,196,197,197,197,197,198,197,198,197,196,196,197,197,198,198,198,198,197,196,197,196,197,196,197,197,198,197,198,197,198,198,197,198,197,197,197 +,109,252,109,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,252,108,252,108,109,108,108,108,108,108,108,108,108,108,108,252,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,107,107,252,109,252,109,252,252,252,252,252,252,252,252,252,252,109,107,109,107,109,107,109,107,107,107,107,34,35,34,35,35,35,36,35,36,35,37,35,38,35,38,35,39,35,40,35,40,35,41,35,42,35,42,35,43,35,44,35,45,35,45,35,46,35,46,35,41,36,41,36,42,36,42,36,43,36,43,36,44,36,44,36,32,36,36,36,40,36,45,36,40,36,43,36,46,36,36,36,37,36,37,36,38,36,39,36,40,36,46,36,32,36,32,36,33,36,33,36,34,36,34,36,35,36,35,36,32,36,34,36,37,36,32,36,33,36,34,36,35,45,36,40,37,40,38,40,39,40,32,40,34,40,35,40,21,40,21,32,39,32,41,32,42,32,43,47,45,47,46,47,33,47,34,47,35,43,37,43,33,43,35,43,37,43,39,33,35,32,32,33,33,33,33,33,33,34,33,34,34,34,34,35,35,35,35,36,36,36,203,36,36,37,36,204,37,37,37,38,215,38,215,39,39,39,39,39,39,40,39,40,40,40,40,41,41,41,41,42,42,42,42,42,42,43,43,43,43,43,43,44,44,44,44,45,45,45,197,45,45,46,46,46,46,46,46,47,47,47,99,197,196,197,196,197,197,197,197,197,197,197,197,198,197,198,197,198,198,198,198,198,198,198,198,198,198,198,53,54,54,55,55,56,57,57,57,58,59,59,60,61,61,61,62,63,63,64,64,66,66,196,196,196,196,196,196,196,196,196,197,198,196,197,197,198,198,197,197,196,196,196,196,197,196,197,197,198,197,198,198,198,197,197,197,198,198,198,198,198,198,198,198,198,196,196,196,197,197,197,197,198,197,198,198,198,198,198,198,198,196,197,198,198,197,197,197,199,196,197,197,198,197,197,197,198,198,198,198,198,197,197,197,198,198,198,198,198,198,198,196,196,197,197,197,196,196,197,196,197,197,198,198,198,197,197,196,196,196,197,197,197,197,197,197,198,198,198,197,197,197,197,197,198,198,198,198,198,198,196,196,197,197,197,197,197,197,198,197,198,198,198,197,198,197,197,196,196,196,196,196,196,198,196,196,196,196,196,196,197,197,197,197,197,197,197,197,197,197,197,197,198,196,196,197,197,198,198,197,198,197,196,196,197,196,197,197,197,197,197,197,198,198,198,198,196,197,198,197 +,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,108,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,109,108,108,252,108,108,108,252,108,109,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,252,107,252,107,252,107,252,107,252,107,252,252,252,109,252,252,252,107,109,107,109,107,109,107,109,107,107,107,38,34,38,35,38,35,38,36,38,37,38,38,38,38,38,39,38,40,38,40,38,41,38,42,38,42,38,43,38,44,38,45,38,45,38,46,38,47,38,39,40,39,40,39,40,39,40,40,40,40,40,41,40,32,40,33,40,34,40,36,40,37,40,38,40,39,40,41,40,42,40,43,40,45,40,46,40,44,40,46,40,43,40,45,40,32,40,33,40,33,40,34,40,35,40,32,40,32,40,33,40,34,40,35,40,32,40,33,40,34,40,36,40,32,40,33,44,35,44,37,44,33,44,36,45,39,45,42,45,45,40,37,40,38,40,40,40,41,40,42,32,43,32,44,32,45,32,47,32,32,47,34,47,35,47,36,47,37,47,39,34,34,35,36,38,38,40,40,42,42,44,45,46,47,35,35,32,35,38,41,44,46,37,37,37,37,38,37,38,38,39,38,39,39,40,39,40,39,40,40,41,40,41,41,42,41,42,42,43,42,43,43,44,43,44,44,45,44,45,45,46,45,46,46,47,46,47,47,197,197,198,198,97,96,98,97,98,98,99,197,198,197,198,198,198,196,197,197,197,197,197,197,198,197,198,197,198,197,198,198,198,198,198,197,198,197,198,198,198,198,59,59,60,60,61,61,62,62,63,89,90,89,90,90,91,64,66,66,69,69,196,196,196,196,196,196,196,196,198,197,198,197,198,197,196,197,198,197,198,197,196,196,197,196,197,196,197,197,198,197,198,197,198,198,198,197,198,197,198,197,198,198,198,198,198,196,196,196,197,196,197,197,197,198,197,197,198,198,198,197,198,198,198,197,198,197,198,199,199,196,193,197,197,197,198,197,197,197,198,197,198,198,198,197,198,197,198,197,198,198,198,196,196,196,197,197,196,196,197,196,197,197,198,197,198,198,198,196,196,196,197,196,197,197,198,197,198,198,198,196,197,197,198,197,198,197,198,197,198,198,198,196,197,196,197,197,198,197,198,197,198,197,198,196,196,196,196,196,196,196,196,196,198,198,196,196,197,197,198,196,197,196,197,196,197,196,197,196,197,197,198,197,198,197,196,196,197,197,198,198,198,198,198,196,196,196,197,196,197,197,198,197,198,197,198,198,196,197,198,197,198 +,109,252,108,252,108,252,108,252,108,252,108,252,252,252,252,108,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,108,108,108,108,108,108,108,108,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,252,109,252,109,252,252,252,252,252,252,252,252,107,107,109,107,109,107,109,107,109,107,107,107,41,35,41,35,41,36,41,37,41,38,41,39,41,39,41,40,41,41,41,42,41,43,41,43,41,44,41,45,41,46,41,46,41,39,41,40,41,42,41,43,43,45,43,46,43,39,43,39,43,39,43,32,43,33,43,33,43,34,43,35,43,36,43,37,43,38,43,38,43,39,43,40,43,41,43,42,43,42,43,43,43,44,43,45,43,46,43,46,43,45,43,45,43,45,43,45,43,46,43,46,43,46,43,47,43,47,43,32,43,34,43,35,43,36,32,32,34,33,35,34,37,35,39,36,40,37,42,37,44,38,45,39,47,40,47,41,47,32,46,35,46,38,32,41,32,44,32,47,32,34,32,35,32,36,32,37,32,38,32,38,32,39,32,40,32,41,32,42,32,43,32,32,33,33,33,33,34,34,35,32,33,34,35,35,37,37,38,39,40,41,42,42,44,44,45,46,47,42,43,213,44,44,44,44,45,45,46,46,47,47,98,98,99,99,214,99,100,214,100,100,101,101,101,101,101,196,197,197,197,197,198,198,103,103,197,197,197,197,197,197,197,197,197,197,198,197,198,197,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,128,128,129,130,130,88,88,89,89,89,89,89,89,90,64,66,68,70,72,75,77,79,50,196,196,196,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,197,198,198,198,198,198,197,198,198,198,198,198,198,198,198,196,196,197,198,196,197,197,197,197,198,197,198,197,198,198,198,198,196,196,196,199,199,196,196,197,196,197,197,198,194,198,198,197,197,198,198,198,197,197,197,198,198,198,198,198,196,196,196,197,197,197,196,196,196,196,197,197,197,198,198,198,196,196,196,197,197,197,197,197,197,198,198,198,197,197,197,197,197,198,197,198,198,198,198,198,198,197,197,197,197,198,197,198,198,198,196,196,196,196,196,196,196,196,196,197,197,198,196,196,197,197,197,198,198,196,196,196,196,197,197,197,197,197,197,197,197,197,197,196,196,197,197,197,198,198,197,198,197,196,196,196,196,197,197,197,197,198,198,198,198,196,197,197,197,198,198 +,252,109,252,108,252,108,252,252,252,252,252,252,252,252,252,108,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,108,108,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,252,107,252,107,252,107,252,107,252,109,252,252,252,252,252,107,109,107,109,107,109,107,107,107,107,107,107,32,44,33,44,34,44,35,44,36,44,37,44,38,44,39,44,41,44,42,44,43,44,44,44,45,44,46,44,44,44,46,44,37,44,38,44,39,44,40,47,41,47,42,47,43,47,44,47,45,47,46,47,32,47,32,47,33,47,34,47,35,47,35,47,36,47,37,47,37,47,38,47,39,47,39,47,40,47,41,47,42,47,42,47,43,47,44,47,45,47,45,47,46,47,47,47,36,47,37,47,38,47,38,47,39,47,40,47,34,47,39,47,44,47,32,47,33,47,34,47,35,47,35,32,36,32,37,32,38,32,39,32,40,32,41,32,32,32,33,32,35,36,36,36,38,36,39,36,41,36,42,36,44,36,45,36,47,36,37,36,38,36,38,36,39,36,40,36,41,36,41,32,42,32,43,32,44,32,45,32,32,33,33,34,34,35,34,36,35,37,36,38,37,39,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,99,99,100,99,100,100,101,100,101,196,197,196,197,196,197,197,198,197,198,197,198,197,198,197,197,197,198,197,198,197,198,197,198,197,198,197,198,197,198,197,198,198,198,198,134,134,136,136,138,139,141,143,143,198,128,129,129,130,64,66,68,69,72,73,76,77,79,64,67,69,72,74,77,79,79,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,198,198,198,198,198,198,198,198,198,198,198,198,198,197,198,197,198,198,196,198,198,198,198,198,197,196,197,197,197,198,197,197,197,197,197,197,198,197,198,198,198,198,197,197,199,196,196,196,196,196,197,197,198,197,198,197,198,197,198,197,198,198,197,197,198,197,198,198,198,198,196,196,197,196,197,196,197,196,196,197,198,197,198,197,198,197,196,196,197,196,197,197,198,197,198,197,198,196,197,197,197,197,198,197,198,197,198,198,198,197,198,196,197,197,198,197,198,198,198,196,196,196,196,196,196,196,197,196,197,197,198,196,197,196,197,197,198,197,198,196,197,196,197,196,197,196,197,196,197,197,197,197,198,196,197,196,197,197,198,198,198,198,196,196,197,196,197,196,197,197,198,197,198,197,196,197,197,197,198,198,198 +,109,252,108,252,108,252,108,252,252,252,108,252,252,252,252,252,108,108,108,108,109,252,109,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,108,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,107,107,107,107,252,252,252,252,252,252,252,252,252,107,107,107,109,107,109,107,109,107,109,107,107,107,107,32,47,33,47,33,47,33,47,33,47,34,47,32,47,34,47,35,47,36,47,37,47,39,47,40,47,41,47,42,47,44,47,45,47,46,47,39,47,40,32,40,32,41,32,42,32,43,32,43,32,44,32,45,32,46,32,32,32,33,32,34,32,35,32,36,32,37,32,37,32,39,32,39,32,40,32,41,32,42,32,43,32,44,32,45,32,46,32,47,32,32,32,34,32,35,32,37,32,39,32,41,32,43,32,44,32,46,32,43,32,45,32,46,32,33,32,33,32,35,32,35,36,37,36,37,36,39,36,40,36,41,36,42,37,43,37,32,37,33,37,34,40,35,40,36,40,37,39,38,40,39,40,40,40,42,39,43,40,44,40,45,40,46,39,47,40,39,40,39,40,40,37,41,37,42,37,42,37,43,32,44,32,45,32,45,32,46,32,38,32,32,33,33,34,35,35,36,36,37,37,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,197,196,196,196,196,197,196,134,135,136,136,138,138,32,33,35,36,37,38,40,41,42,43,45,46,47,136,40,139,140,141,142,143,128,129,130,131,132,133,135,135,137,138,139,140,142,143,143,143,128,129,129,128,64,64,65,65,66,66,67,67,67,68,68,69,69,69,70,70,71,71,72,72,72,73,73,74,74,74,75,75,76,76,77,77,77,78,78,79,79,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,197,196,196,197,197,197,197,198,197,197,197,197,198,197,198,198,196,192,196,196,197,196,196,196,197,197,197,197,198,198,198,198,198,198,198,198,197,197,197,197,198,198,198,198,196,196,196,196,197,197,196,196,197,196,197,197,198,198,198,198,198,196,196,196,197,197,197,197,198,198,198,197,197,197,197,197,198,197,198,197,198,198,198,198,198,197,197,197,198,198,198,197,198,198,196,196,196,196,196,196,197,197,197,197,196,196,196,196,197,197,198,198,198,197,197,196,197,197,197,196,198,198,197,197,197,197,197,196,196,197,197,197,198,198,198,197,198,196,196,196,197,197,197,197,198,198,198,198,196,196,197,197,198,197,198,198 +,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,109,108,252,108,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,108,108,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,109,107,252,107,252,107,252,107,252,109,252,107,252,252,107,107,109,107,109,107,109,107,109,107,107,107,107,107,32,32,32,32,32,33,32,33,32,33,32,33,32,33,32,33,32,32,32,32,32,33,32,33,32,36,32,38,32,41,32,44,32,47,32,38,32,39,35,39,35,40,35,41,35,41,35,42,35,43,35,43,35,44,35,45,35,46,35,32,35,33,35,33,35,34,35,35,35,36,35,37,35,38,35,38,35,39,35,40,35,41,35,42,35,43,35,44,35,45,36,45,36,46,36,41,36,42,36,42,36,42,36,42,36,42,36,42,36,43,36,43,37,43,37,43,37,32,37,33,37,35,40,36,40,38,40,39,40,40,40,41,40,43,42,44,42,45,42,47,44,32,43,33,44,34,43,35,44,36,43,33,44,37,43,41,44,45,43,41,44,42,43,43,44,44,43,45,44,46,42,47,32,46,34,46,35,32,37,34,38,37,40,40,41,43,43,45,44,32,46,46,47,38,39,38,39,38,39,38,39,38,39,32,33,33,35,35,36,36,38,38,39,39,41,41,42,42,44,44,44,32,33,33,34,34,35,35,37,36,38,38,39,39,40,40,41,41,43,42,44,44,45,45,46,46,47,59,60,61,63,63,48,49,50,50,52,52,54,54,55,56,57,57,59,59,61,61,62,63,64,64,64,65,65,66,66,66,67,67,67,68,68,68,69,69,70,70,70,70,71,71,72,72,70,69,70,70,71,70,72,71,72,72,73,72,74,73,74,74,75,74,75,75,76,75,76,76,77,76,77,77,78,78,79,78,79,219,219,219,196,196,196,196,196,196,196,196,196,197,197,198,198,197,198,198,198,198,196,198,197,196,197,196,196,196,197,196,197,197,198,198,198,197,198,198,198,197,198,198,197,197,198,197,198,197,198,196,196,196,197,197,198,196,196,196,197,196,197,197,198,197,198,196,197,196,197,197,197,197,198,197,198,198,197,197,197,197,197,197,198,197,198,198,198,198,198,198,197,196,197,197,198,198,198,197,196,196,196,196,197,196,197,197,198,197,198,196,197,196,197,197,198,197,198,198,198,197,198,197,198,197,196,197,198,197,198,196,197,198,196,196,197,197,198,197,198,198,198,198,196,196,197,196,197,197,198,197,198,198,196,196,197,197,198,197,198,198,198 +,252,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,108,108,108,108,109,252,109,108,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,108,108,108,108,108,108,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,109,107,252,107,252,252,252,252,252,252,252,107,107,107,109,109,109,109,109,107,109,107,109,107,107,107,35,33,35,34,35,39,35,44,35,33,35,34,35,34,35,34,35,34,35,32,35,33,35,34,35,34,35,35,35,36,35,37,35,37,35,38,35,39,37,40,37,41,37,41,37,32,37,35,37,37,37,40,37,43,37,45,37,47,38,32,38,33,38,34,38,34,38,35,38,36,38,37,38,37,38,38,38,39,38,40,38,41,38,41,38,42,38,43,39,44,40,44,39,45,40,46,39,47,40,42,39,42,40,43,39,43,40,43,39,43,42,43,42,44,42,44,42,44,42,44,43,44,43,33,43,35,43,37,43,39,43,42,47,44,47,46,47,46,47,46,47,32,47,33,47,34,47,35,47,35,47,36,47,37,47,38,47,38,47,39,47,40,47,41,47,41,47,42,47,43,47,44,47,45,47,45,47,46,47,47,47,45,47,40,40,40,41,40,32,32,33,33,34,34,34,35,35,35,36,36,37,37,37,38,38,38,39,35,36,39,40,40,41,41,42,42,43,43,43,44,43,44,44,44,45,44,45,46,44,45,46,46,46,46,46,47,102,47,103,96,103,98,96,98,98,97,97,54,98,55,99,56,57,58,58,58,102,100,54,55,55,56,56,57,57,58,58,58,62,62,62,62,63,63,65,64,63,66,63,65,65,64,65,66,65,66,67,67,68,66,68,69,70,70,71,71,72,72,70,70,70,70,71,71,72,72,72,72,73,73,74,74,74,74,75,75,76,76,76,77,77,77,78,78,78,79,79,196,196,196,196,196,197,197,197,197,197,197,198,198,198,198,198,197,198,196,196,196,196,196,196,196,197,196,197,196,197,197,198,197,198,197,198,198,198,198,219,219,219,219,219,219,219,219,219,196,196,196,197,197,197,196,196,196,196,197,197,197,197,197,198,198,196,196,197,197,197,197,197,197,198,198,197,197,197,197,197,197,198,197,198,198,198,198,198,198,198,197,197,197,198,198,198,198,196,196,196,196,197,197,197,197,198,198,198,196,196,196,197,197,197,197,198,198,198,197,197,197,197,197,196,197,197,198,197,196,197,197,197,198,198,197,197,197,198,198,198,198,198,196,196,196,197,197,197,197,198,198,196,196,197,197,198,197,198,198,198,198 +,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,109,108,252,108,252,252,252,108,252,108,252,252,252,252,252,252,252,252,108,252,252,108,252,252,108,108,252,108,109,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,252,107,252,107,252,107,252,107,252,107,252,107,252,252,252,107,109,107,109,107,109,109,109,107,109,107,107,107,107,34,37,35,37,37,37,38,37,40,37,41,37,43,37,44,37,46,37,34,37,34,38,35,38,35,38,32,38,33,38,35,38,36,38,37,38,38,40,39,40,40,40,41,40,32,40,33,40,34,40,35,40,36,40,36,40,37,40,38,41,39,41,40,41,41,41,42,41,43,41,44,41,44,41,45,41,46,41,38,41,39,41,40,41,40,41,41,41,42,44,43,43,43,44,44,43,45,44,45,43,46,44,47,43,43,44,44,43,44,44,44,47,44,47,44,47,45,47,45,47,45,47,45,47,45,47,46,47,46,47,46,47,39,39,39,39,39,39,39,47,42,47,32,47,33,47,34,47,34,47,35,47,36,47,37,47,37,47,38,47,39,33,32,33,32,33,33,34,33,34,34,35,34,35,35,36,35,36,35,36,36,37,36,37,37,38,37,38,37,38,38,39,38,39,39,40,39,40,40,41,40,41,40,41,41,42,38,39,41,42,36,42,43,40,42,41,43,43,44,43,44,45,44,45,44,46,46,45,45,45,46,45,47,46,45,47,45,96,46,46,46,47,98,99,101,99,100,101,50,52,50,53,53,53,54,55,55,57,102,100,54,55,55,56,56,57,57,58,58,58,58,58,61,62,61,61,62,62,62,62,62,64,62,63,65,66,65,65,66,67,67,67,68,67,68,70,70,70,70,71,71,72,72,69,69,70,70,71,71,72,72,73,73,74,74,75,75,76,76,77,77,78,78,79,79,79,196,196,196,197,196,197,196,197,197,198,197,198,197,198,198,198,197,198,198,196,196,197,196,197,196,197,197,197,197,197,197,197,197,197,197,198,197,198,198,198,198,197,219,219,219,219,219,219,196,196,196,196,196,197,197,196,196,196,196,197,197,198,197,198,198,198,196,197,196,197,196,197,197,198,197,198,196,197,197,197,197,198,197,198,197,198,198,198,197,198,198,197,197,198,198,198,196,197,196,196,197,198,197,196,196,197,197,198,198,196,196,197,196,197,197,198,197,198,198,198,197,198,197,196,196,198,198,198,196,197,196,197,197,198,198,197,197,198,197,198,198,198,197,198,196,197,196,197,197,198,197,198,196,197,196,198,197,198,198,198,198,198 +,252,252,109,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,108,108,108,108,109,252,109,108,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,252,252,252,108,108,108,108,108,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,107,107,107,252,107,252,107,252,252,252,252,252,252,107,107,109,109,109,109,109,107,109,107,109,107,107,107,40,34,40,35,40,36,40,36,40,37,40,38,40,39,40,39,40,40,40,41,41,42,41,42,41,43,41,44,41,45,41,46,41,47,41,37,41,32,42,33,42,33,42,34,42,35,42,35,42,32,42,33,42,34,42,34,42,35,44,36,44,37,44,38,44,39,44,39,44,40,44,41,44,42,44,42,44,43,44,44,44,45,44,45,44,46,44,47,47,43,47,43,47,44,47,44,47,45,47,46,47,47,47,46,47,46,47,46,47,47,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,34,33,34,34,34,34,34,34,35,35,35,35,36,35,36,36,36,36,36,36,37,37,37,37,37,37,38,38,38,38,38,38,39,39,39,39,39,39,40,40,40,40,40,40,41,41,41,41,41,41,42,42,42,42,42,41,42,39,42,43,40,43,40,43,43,43,42,44,44,44,44,44,45,44,45,45,45,45,45,45,45,45,46,45,46,46,46,47,99,99,100,101,100,101,101,101,47,100,101,101,101,101,101,101,101,102,100,54,55,102,100,54,55,55,56,55,56,57,57,58,58,58,58,58,61,61,61,61,61,62,62,62,63,63,63,63,63,63,64,63,65,63,65,66,68,68,69,69,70,64,70,70,71,71,72,72,64,65,66,67,68,69,70,70,72,72,73,74,75,76,77,78,79,196,196,196,197,197,197,197,197,197,197,197,198,198,198,198,198,198,198,198,198,198,198,198,196,196,196,197,197,197,197,197,198,197,198,198,198,198,198,198,198,198,198,198,198,196,196,196,196,219,219,219,219,198,198,198,196,196,196,196,197,197,197,197,198,198,198,198,196,196,196,196,197,197,197,197,198,198,197,197,197,197,197,197,198,198,198,198,198,198,198,196,197,197,198,198,198,198,196,196,196,196,198,197,196,196,197,197,198,198,198,196,196,196,197,197,197,197,198,198,198,197,197,197,196,197,198,197,198,197,196,196,197,197,197,197,198,197,197,197,198,198,198,197,198,198,196,196,197,197,197,198,198,196,196,196,197,197,198,197,198,197,198,198 +,252,252,252,109,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,108,252,252,109,108,252,108,252,252,252,108,252,252,252,252,252,252,252,108,252,252,252,252,108,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,107,107,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,109,252,107,107,107,252,107,252,107,252,107,252,107,252,107,252,252,252,107,107,107,109,107,109,109,109,107,109,107,109,107,109,33,42,34,42,34,42,35,42,36,42,36,42,37,42,38,42,38,42,39,42,40,44,40,44,41,44,42,44,42,44,43,44,44,44,44,44,45,45,32,45,33,45,33,45,34,45,35,45,35,45,36,45,37,45,37,45,38,45,39,47,39,47,32,47,34,47,35,47,37,47,39,47,41,47,43,47,45,47,47,47,46,47,47,47,41,47,42,47,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,33,34,33,34,33,34,33,34,33,34,34,34,34,34,34,34,33,34,34,34,34,33,34,33,34,33,34,33,34,34,35,34,35,35,35,35,35,35,36,35,36,36,36,36,37,36,37,36,37,37,37,37,38,37,38,37,38,38,39,38,39,38,39,38,39,39,40,39,40,39,40,39,40,40,41,40,41,40,41,40,41,41,42,41,42,41,42,41,42,42,43,42,42,43,42,42,42,43,42,43,43,42,44,43,43,43,44,43,44,44,43,44,45,44,45,44,45,45,45,46,45,45,46,45,46,46,46,46,46,47,100,101,101,47,101,100,47,100,100,101,47,101,100,47,100,100,100,101,100,102,101,47,102,102,101,101,99,99,54,102,99,56,56,102,56,102,57,57,61,58,58,58,61,61,61,61,61,61,61,63,63,63,63,63,63,64,61,64,61,65,67,68,67,68,69,69,70,70,70,70,71,71,72,72,75,73,72,76,64,78,76,77,196,196,196,196,197,196,197,196,197,197,198,197,198,197,198,197,198,198,198,197,198,196,197,196,197,196,197,196,197,197,197,197,198,197,197,197,197,198,198,198,198,198,198,197,198,198,198,197,197,197,196,219,219,219,219,219,219,219,219,219,198,196,197,197,198,198,198,197,198,196,197,196,197,197,198,197,198,196,197,196,197,197,198,197,198,197,198,197,198,198,198,196,197,197,198,198,198,198,196,196,196,196,196,197,196,196,197,197,198,197,198,196,196,196,197,196,197,197,198,197,198,197,198,197,196,197,198,197,198,196,197,196,197,197,198,197,198,198,198,197,198,197,198,198,198,198,198,196,197,197,198,197,198,197,196,196,197,196,198,197,197,197,198,198,198 +,252,252,252,252,108,252,108,252,108,252,108,108,108,252,252,252,252,252,252,252,252,252,108,252,252,252,252,108,109,108,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,252,252,252,107,107,109,252,107,252,107,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,107,107,252,107,252,252,252,252,252,252,252,252,107,107,107,107,109,109,109,109,109,107,109,107,107,107,44,33,45,34,44,35,45,35,44,36,45,37,44,37,45,38,44,39,45,39,47,40,47,41,47,41,47,42,47,43,47,44,47,44,47,45,47,46,47,46,47,32,47,33,47,34,47,35,47,35,47,36,47,37,47,38,47,39,32,32,32,32,32,32,32,32,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,37,42,47,35,36,35,36,35,36,35,36,36,36,36,37,36,37,37,37,37,37,37,37,37,38,37,38,38,38,38,38,38,38,38,39,39,39,39,39,39,39,39,40,39,40,40,40,40,40,40,40,40,41,40,41,41,41,41,41,41,41,41,42,42,42,42,42,42,42,42,43,42,43,43,43,43,43,43,43,43,43,42,43,42,43,43,43,44,44,44,43,44,44,44,45,44,45,45,45,45,45,45,45,46,46,45,46,46,46,46,46,47,47,47,47,46,100,100,100,46,100,47,47,101,47,101,101,47,101,100,47,100,100,100,101,100,102,101,47,102,102,101,101,99,99,54,102,99,56,56,102,56,56,57,58,57,58,58,60,60,60,61,61,61,61,61,61,61,61,62,63,63,63,63,61,65,61,68,61,69,69,70,70,70,70,71,71,72,72,69,74,68,70,196,196,196,196,196,197,197,197,197,197,197,198,197,198,198,198,198,198,198,198,198,196,196,196,196,197,196,197,197,197,197,197,197,197,197,198,197,198,198,197,197,197,197,196,198,198,198,198,197,198,197,197,197,196,196,196,196,196,196,219,219,219,219,219,219,219,219,219,219,219,219,219,219,197,197,198,198,198,198,196,196,197,196,197,197,197,197,198,198,198,198,198,198,198,196,197,198,198,198,198,196,196,196,196,197,198,196,196,197,197,197,198,198,198,196,196,196,197,197,197,197,198,198,198,197,196,197,198,197,196,196,197,196,197,197,197,197,198,198,198,197,198,197,198,198,198,197,198,198,196,197,197,197,198,198,198,196,196,196,197,197,197,197,198,198,198,198 +,252,252,252,108,252,109,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,252,252,107,109,107,109,107,107,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,109,109,107,107,107,107,252,107,252,107,252,107,252,107,252,107,252,252,109,107,109,107,109,107,109,107,109,107,109,107,109,107,47,38,47,32,47,33,47,34,47,35,47,36,47,37,47,38,47,39,47,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,41,43,41,42,41,42,42,44,45,47,32,32,32,32,32,32,32,32,34,33,34,33,34,32,33,36,37,39,40,42,43,46,47,33,34,33,34,33,34,33,34,33,34,33,34,33,34,34,35,35,35,32,37,42,47,35,35,35,35,35,35,35,36,35,36,35,36,35,32,35,37,40,42,45,47,36,37,36,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,38,38,38,38,39,38,39,38,39,38,39,38,39,39,40,39,40,39,40,39,40,39,40,40,40,40,41,40,41,40,41,40,41,41,41,41,41,41,42,41,42,41,42,41,42,42,42,42,43,42,43,42,43,42,43,42,43,43,44,43,44,44,43,43,44,43,43,44,43,43,43,43,42,43,44,44,44,44,44,45,45,44,45,44,45,45,45,46,45,46,45,46,45,46,46,46,46,47,46,47,46,47,46,100,47,99,99,99,47,100,100,100,100,100,100,101,47,101,100,47,100,100,100,101,100,102,101,47,102,102,101,101,99,99,54,102,99,56,56,102,102,56,56,56,58,58,57,58,57,62,57,57,101,58,61,61,62,61,61,62,62,62,62,63,62,63,63,64,64,64,94,93,64,95,66,92,65,72,196,196,196,196,197,196,197,197,197,197,198,197,198,197,198,197,198,198,198,197,198,130,196,196,197,196,196,196,197,196,197,197,198,197,198,197,198,197,198,198,198,196,197,198,197,197,197,197,197,197,197,197,198,197,198,197,198,197,198,197,198,196,196,196,196,196,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,198,198,198,196,196,197,197,198,198,198,198,198,196,196,196,196,196,196,196,196,196,197,197,198,198,198,197,196,196,197,196,197,197,198,197,198,196,197,197,198,197,196,196,197,196,197,197,198,197,198,197,198,198,198,197,198,197,198,198,198,197,198,196,197,197,198,198,196,196,197,196,197,197,197,197,198,198,198,198,198 +,252,252,252,252,108,252,109,252,252,252,108,252,108,252,108,252,252,252,252,252,108,252,108,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,252,107,107,107,107,109,252,107,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,107,107,107,107,252,107,252,107,252,252,252,252,252,252,252,107,107,107,109,109,109,109,109,107,109,107,109,107,109,32,32,32,32,32,47,44,42,39,37,34,32,32,33,33,35,35,36,37,38,38,39,40,41,41,42,43,44,45,45,46,47,33,33,33,33,34,33,33,34,35,37,38,40,41,42,44,46,47,33,33,33,34,33,34,33,34,34,35,34,35,34,35,34,35,34,35,34,35,35,35,35,35,35,35,35,35,35,35,35,35,32,39,47,35,35,35,36,37,36,37,36,37,36,37,36,47,32,35,38,41,44,47,37,37,37,37,37,37,38,38,38,38,38,38,38,38,38,39,38,47,45,42,40,37,34,32,38,39,38,39,39,39,39,38,39,38,39,38,39,39,39,39,39,39,39,39,39,39,39,39,40,40,40,40,40,40,40,40,41,40,41,40,41,41,41,41,41,41,41,41,42,41,42,41,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43,43,43,43,43,43,44,44,44,44,44,44,44,44,43,44,44,44,45,43,43,44,44,44,45,44,45,45,45,45,46,45,46,45,45,46,46,46,46,46,46,46,46,47,46,47,46,47,47,47,46,99,47,47,47,47,99,99,99,100,100,100,101,101,101,101,47,101,100,47,100,100,100,101,100,102,101,47,102,102,101,101,99,99,54,102,99,56,56,102,55,55,56,56,57,57,58,58,58,60,61,58,61,61,61,62,62,62,63,63,62,63,61,62,62,63,62,90,62,94,91,90,94,91,94,92,93,93,196,196,196,196,197,197,197,197,197,197,198,198,198,198,198,198,198,198,198,198,128,129,196,196,196,196,197,197,197,197,197,197,197,197,198,198,198,198,198,196,196,197,197,197,197,197,197,196,196,197,197,198,198,197,198,197,198,197,198,198,198,198,198,198,198,198,198,197,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,196,196,196,197,197,198,198,198,196,197,197,198,198,198,198,198,196,196,197,197,197,198,198,198,196,197,197,198,198,196,196,196,196,197,197,197,197,198,198,198,198,198,197,198,197,198,198,198,197,198,198,198,196,198,198,198,196,196,196,197,196,197,197,198,197,198,198,198,198 +,252,252,252,108,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,252,109,107,109,107,109,252,252,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,252,107,252,107,109,107,252,107,252,107,252,109,252,109,109,107,109,107,109,109,109,109,109,107,109,107,109,107,33,34,33,34,33,46,45,42,47,42,47,47,33,34,33,34,33,34,33,35,34,35,34,32,35,36,39,40,43,44,47,35,34,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,36,36,37,36,36,36,37,36,36,36,37,36,32,34,35,38,39,42,43,46,46,36,37,36,37,36,37,36,37,37,38,38,38,47,32,35,36,39,40,43,44,47,38,38,39,38,39,39,39,38,39,39,40,39,40,39,40,39,40,39,38,32,35,40,43,47,39,38,39,38,39,38,39,38,39,39,39,39,38,39,38,39,47,43,46,47,47,40,39,40,47,40,32,40,40,41,40,37,42,47,40,41,41,41,35,40,43,47,41,42,41,42,41,42,42,32,34,38,41,44,47,43,42,43,42,43,43,44,43,44,43,44,43,44,44,46,46,46,44,45,45,45,45,46,47,47,44,46,47,44,46,44,45,45,45,45,46,45,46,45,46,45,46,47,47,46,47,47,103,47,96,47,96,97,47,96,97,97,98,97,97,98,98,98,98,99,99,99,99,99,99,99,99,100,100,101,47,101,100,47,100,100,100,101,100,102,101,47,102,102,101,101,99,99,54,102,99,56,56,102,55,55,56,56,57,55,58,57,58,61,58,60,61,62,61,61,62,62,63,63,62,62,62,62,62,63,62,91,91,92,90,92,92,91,92,93,93,94,128,130,130,131,132,134,134,136,136,138,138,140,141,142,143,128,143,142,135,138,140,143,136,196,196,196,196,197,196,197,197,197,197,198,197,198,197,198,196,197,197,197,197,197,197,196,196,197,196,197,196,198,196,197,197,198,197,198,197,198,197,198,197,198,198,198,197,198,198,198,197,220,220,220,220,220,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,196,196,197,196,197,197,198,197,198,196,197,198,198,197,198,197,196,196,198,198,198,196,197,196,197,197,198,197,198,196,197,196,197,196,197,197,198,197,198,197,198,197,198,197,198,198,198,198,198,197,198,197,198,197,198,196,198,196,197,196,197,197,198,197,198,198,198,198,198 +,252,252,252,252,108,252,108,252,109,252,108,252,252,252,252,252,108,252,109,252,109,252,108,252,108,108,252,108,108,252,252,252,252,252,252,252,252,252,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,252,252,252,107,107,109,252,109,252,107,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,109,107,109,107,109,109,252,109,252,109,107,107,109,109,109,109,109,107,109,107,109,107,109,107,34,34,34,34,34,35,34,35,34,35,34,34,34,35,34,35,32,34,35,37,39,40,42,44,46,47,35,36,35,36,35,36,35,36,36,36,36,36,36,36,36,36,36,34,36,37,38,39,41,42,43,44,46,47,36,37,33,34,36,36,38,39,40,41,43,43,45,46,47,38,38,38,38,38,37,38,38,38,38,38,38,38,37,38,38,39,39,40,39,40,39,39,39,40,39,40,39,40,39,39,40,40,40,40,40,40,32,34,36,38,41,43,45,47,40,41,39,41,40,41,40,41,40,41,40,41,40,32,34,36,38,40,43,45,47,40,41,40,40,40,40,40,40,40,41,40,41,41,41,41,41,41,41,41,41,41,42,42,42,42,42,42,42,42,43,42,43,43,43,43,43,43,43,43,44,44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,96,96,99,99,99,46,46,99,47,100,46,100,99,99,100,100,47,100,46,100,100,101,101,101,102,45,102,46,102,102,102,102,102,103,103,103,103,96,96,96,97,97,97,97,98,98,97,97,98,98,98,53,99,101,47,101,100,47,100,100,100,101,100,102,101,47,102,102,101,101,99,99,54,102,99,56,56,102,102,100,54,55,55,56,56,57,57,58,58,58,60,60,60,61,61,61,61,61,62,62,62,196,196,196,196,196,63,60,61,61,62,62,92,62,92,92,93,92,94,94,94,94,128,129,130,130,131,132,133,134,135,135,136,137,138,139,140,141,142,70,71,71,72,72,73,136,196,136,197,196,197,197,197,197,197,197,198,197,198,198,197,197,197,196,197,197,197,197,196,196,196,196,196,196,197,197,197,197,198,198,198,198,198,197,198,197,198,198,198,198,198,198,198,198,198,198,198,222,221,221,221,221,221,221,220,220,220,220,220,220,220,220,220,220,220,220,220,219,219,219,219,219,219,219,219,196,196,196,197,197,197,197,197,197,198,198,198,197,198,197,198,197,198,198,198,197,198,197,198,196,197,197,197,197,198,196,196,196,197,197,197,197,197,197,198,198,198,197,197,197,198,198,198,198,198,197,198,198,198,197,198,197,196,198,196,196,197,197,197,197,198,197,198,198,198,198 +,252,252,252,109,252,108,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,252,107,107,109,107,252,107,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,107,252,107,252,107,109,107,252,107,252,252,109,107,109,107,109,107,109,109,109,107,109,107,109,107,107,36,35,36,35,36,36,36,36,36,36,36,35,36,36,36,36,36,36,37,37,37,37,37,37,37,37,34,36,37,39,39,41,42,44,44,46,47,37,38,37,38,37,38,37,38,37,38,37,38,37,38,38,38,38,38,38,39,39,39,39,39,39,39,39,39,39,39,39,40,39,40,39,40,39,40,39,40,39,40,39,32,34,34,36,36,38,39,40,41,43,43,45,45,47,41,41,41,41,41,41,42,42,42,42,42,42,42,42,43,42,43,42,43,42,43,42,41,42,42,42,34,37,38,41,42,45,47,42,42,42,42,42,42,42,42,42,42,42,40,41,41,42,41,42,41,42,41,42,42,43,32,36,39,44,47,43,43,44,43,45,46,46,43,44,44,45,44,45,44,45,44,45,45,45,45,45,46,45,45,46,46,45,44,46,44,46,47,44,46,47,103,103,97,97,98,98,99,99,97,98,99,100,100,97,98,49,100,101,101,101,102,100,101,102,101,103,101,103,102,103,102,103,51,52,96,96,97,97,52,53,97,98,53,98,98,97,97,98,54,98,98,99,98,56,98,56,55,56,55,56,56,57,56,57,57,99,57,58,57,58,57,58,58,59,58,59,58,59,59,59,59,60,59,60,60,61,60,61,60,61,61,61,60,61,61,63,63,63,196,196,196,196,196,196,197,198,198,198,61,62,62,63,63,63,93,92,93,93,94,94,93,94,94,94,95,95,94,95,64,65,65,66,66,67,67,68,68,69,69,70,70,71,71,72,136,136,136,197,196,136,196,198,197,198,197,198,197,198,197,198,196,196,196,197,196,197,197,197,197,196,197,198,196,197,196,197,197,198,197,198,197,198,197,198,198,198,197,198,197,198,197,198,197,198,198,198,198,198,198,198,222,222,222,222,222,222,221,222,221,221,221,221,220,221,220,221,220,220,220,220,220,220,220,220,219,196,196,197,196,197,197,198,197,198,197,198,198,198,197,198,197,198,197,198,197,198,197,198,197,196,196,197,197,198,198,197,196,197,196,197,197,198,197,198,197,198,198,198,197,198,197,198,197,198,198,198,197,198,198,198,197,196,197,198,196,197,196,197,197,198,197,198,198,198,198,198 +,252,252,108,252,108,252,108,252,252,252,108,252,108,252,109,252,252,252,109,252,109,252,108,252,252,252,108,108,108,252,108,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,107,107,107,107,109,252,107,107,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,107,107,107,252,109,109,109,252,252,252,252,107,107,107,107,109,109,109,107,109,107,109,107,109,107,107,37,37,33,35,36,37,38,40,41,42,43,45,46,47,39,41,43,45,47,38,38,38,38,38,38,38,38,38,38,38,38,38,39,39,39,38,34,36,37,38,39,40,41,42,43,45,46,47,39,39,40,39,40,39,40,40,40,40,40,40,40,40,40,40,40,40,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,42,42,42,43,42,43,42,43,42,43,42,43,42,43,47,44,41,38,35,32,40,47,43,44,44,44,44,44,44,44,44,44,42,44,44,44,43,44,44,44,47,45,43,41,40,37,36,34,32,43,44,43,44,43,42,42,32,33,35,36,37,38,40,41,42,43,45,46,47,44,45,45,45,45,97,98,98,98,98,98,46,32,35,38,41,44,47,47,47,99,99,100,100,100,100,100,100,45,101,46,101,101,46,101,46,102,102,102,96,97,97,96,98,99,50,50,99,99,98,50,51,99,100,51,52,51,101,102,102,102,102,52,53,53,53,53,53,53,53,53,54,54,54,54,54,54,55,55,55,55,55,55,56,56,98,56,56,56,56,98,57,57,57,57,57,57,58,57,58,58,58,58,59,100,59,59,59,59,59,59,60,60,60,60,60,60,61,60,61,61,61,61,61,61,62,62,62,62,62,63,63,63,196,196,196,197,197,198,197,197,198,198,198,198,198,198,92,62,63,92,93,92,93,93,94,94,94,94,64,94,65,64,66,65,67,66,67,67,68,68,68,68,69,69,69,70,71,71,71,135,136,136,136,136,136,198,197,198,198,198,198,198,198,196,196,196,196,196,196,196,197,197,197,197,197,197,198,198,198,197,197,197,198,197,198,198,198,198,198,197,198,197,198,197,198,198,198,197,198,198,198,198,198,198,198,198,198,198,198,222,222,222,222,222,222,222,222,221,221,221,221,221,221,221,221,220,221,220,220,220,196,196,196,196,197,197,197,197,198,198,198,198,198,198,198,197,198,198,198,197,198,198,198,197,198,198,196,196,197,197,198,196,197,197,197,197,197,197,197,197,198,198,198,197,198,197,198,197,198,198,198,197,198,198,198,197,198,196,197,198,196,196,197,197,197,197,198,198,198,198,198,198 +,252,252,252,109,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,109,252,252,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,107,107,109,107,109,107,252,107,252,107,252,107,252,109,252,109,252,107,109,107,109,107,109,109,109,107,109,107,109,107,107,107,38,39,38,39,34,34,37,37,39,40,42,42,45,45,47,39,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,40,41,40,40,40,41,40,41,40,41,40,40,40,41,40,41,40,41,41,41,41,41,41,42,41,42,42,42,41,42,41,42,41,42,42,43,42,43,42,43,42,43,42,43,42,43,42,43,42,43,42,44,43,44,44,44,44,44,44,44,44,44,44,44,44,44,44,46,45,46,45,46,45,46,45,46,45,46,45,47,45,42,40,37,35,32,47,45,45,45,45,46,45,45,45,45,45,45,45,45,46,45,46,46,46,44,45,44,45,45,42,43,43,43,43,43,43,46,47,46,47,47,47,96,97,97,97,98,99,99,99,99,99,99,100,100,99,100,100,100,100,100,101,100,101,101,100,101,100,100,100,101,102,101,102,102,102,102,103,103,51,103,97,97,96,51,52,98,52,99,53,52,53,52,53,53,101,101,54,53,54,53,54,54,55,54,55,54,55,54,55,55,56,55,56,55,56,55,56,56,57,56,57,56,57,57,57,57,58,57,58,57,58,58,58,58,59,58,59,58,59,59,60,59,60,59,60,60,60,60,61,60,61,60,61,61,61,61,61,62,61,62,62,62,63,63,62,62,63,63,63,63,143,143,196,197,198,198,198,198,198,197,198,198,198,198,198,198,198,92,93,93,92,94,94,64,66,65,66,64,66,65,66,67,67,67,68,68,67,67,68,68,68,68,69,69,70,70,70,71,71,71,135,137,138,140,140,141,142,142,143,128,129,196,140,140,140,141,141,142,142,143,198,197,198,198,198,197,198,198,198,197,198,197,198,197,198,198,198,198,197,197,198,197,198,197,198,197,198,198,198,197,198,197,198,197,198,198,198,197,198,198,65,65,66,217,222,222,222,222,222,221,221,221,221,220,221,220,221,220,196,196,197,196,197,196,197,196,197,197,198,197,198,198,198,197,198,197,198,197,198,197,198,197,198,197,198,196,197,197,198,196,197,196,197,196,197,197,198,197,198,197,198,198,198,197,198,197,198,198,198,198,198,197,198,198,198,197,196,197,198,196,197,196,197,197,198,197,198,198,198,198,198 +,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,109,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,252,252,109,107,107,107,107,107,107,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,109,107,252,109,252,109,252,252,252,252,107,107,109,107,109,109,109,109,109,107,109,107,109,107,107,107,39,40,47,39,32,34,37,39,42,44,47,40,39,40,40,40,96,34,36,38,41,43,45,47,40,41,40,41,40,41,40,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,42,43,42,43,42,42,43,43,42,43,32,33,34,34,36,36,37,38,39,40,41,42,43,43,44,45,46,47,43,44,44,44,44,47,46,44,43,41,40,38,37,35,34,32,45,45,45,46,45,46,47,47,46,33,35,36,37,38,40,47,42,43,45,46,47,47,96,96,34,36,38,39,41,43,45,47,97,97,97,33,35,36,37,38,40,41,42,43,45,46,47,99,100,45,45,45,45,45,44,45,45,46,102,103,96,96,97,96,97,41,43,41,44,47,99,99,100,100,100,100,100,100,100,101,50,50,101,50,101,101,51,101,101,101,51,51,101,102,101,103,101,103,103,103,53,53,96,96,53,53,53,53,54,54,54,54,54,54,54,54,55,55,55,55,55,55,55,55,56,56,56,56,56,56,56,56,57,57,57,57,57,57,57,57,58,58,58,58,58,58,58,58,59,59,59,59,59,59,59,59,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61,61,62,62,62,62,62,61,62,62,62,62,62,62,63,48,63,63,63,53,63,197,128,128,143,143,198,143,198,198,198,198,198,198,198,198,198,198,132,132,93,94,94,92,93,64,65,93,68,66,66,68,67,67,68,68,68,68,70,68,68,69,69,69,70,70,70,70,71,71,72,72,73,73,73,73,138,138,138,138,139,139,139,139,140,140,140,140,141,141,141,141,141,142,142,142,143,143,143,143,143,198,198,198,198,198,198,198,198,198,198,198,198,197,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,66,66,217,78,217,217,222,222,222,221,221,221,221,220,221,220,220,198,196,196,196,196,197,197,197,197,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,196,196,197,198,197,197,197,197,197,197,197,197,198,198,198,198,197,197,197,197,198,198,198,198,198,197,198,198,198,198,196,197,197,198,196,196,197,197,197,197,198,197,198,198,198,198 +,252,108,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,107,107,252,107,252,107,252,107,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,107,107,107,107,252,107,252,107,252,107,252,107,109,107,252,109,252,109,107,107,109,107,109,109,109,107,109,107,109,107,107,107,107,41,41,41,41,41,41,41,41,41,41,41,41,41,41,42,41,42,42,42,42,42,42,42,42,42,42,42,42,42,42,32,35,38,41,44,47,43,43,43,43,43,43,103,101,100,101,100,101,100,101,101,103,103,44,45,44,45,44,45,44,45,44,45,44,45,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,96,97,96,98,97,98,98,99,99,101,100,102,101,102,101,103,102,103,96,96,96,96,96,96,96,96,97,96,97,48,48,97,48,46,97,57,48,57,97,48,98,52,98,99,99,100,100,46,100,45,100,100,46,102,101,103,103,97,103,97,97,98,98,98,50,99,50,99,51,99,100,100,101,100,51,52,51,52,52,53,52,53,52,53,102,53,53,102,53,54,53,103,53,96,54,55,54,55,54,55,54,55,55,56,55,56,55,56,55,56,56,57,56,57,56,57,56,57,57,58,57,58,57,58,57,58,58,58,58,59,58,59,58,59,59,59,59,59,59,60,59,60,60,60,60,60,60,61,60,61,60,61,61,61,61,62,61,62,61,62,61,62,62,62,62,63,62,62,62,62,62,62,63,62,63,62,61,62,60,61,63,88,63,63,63,143,143,143,128,128,143,128,131,129,131,129,132,132,132,132,133,133,133,92,65,65,93,66,64,66,92,64,67,64,69,67,69,70,70,70,70,70,69,70,70,69,69,70,70,71,70,72,71,72,72,73,73,74,73,74,74,75,75,76,75,76,76,77,77,78,77,78,78,79,79,79,64,79,64,64,64,65,64,66,65,66,66,67,67,68,132,132,132,132,133,133,134,134,135,135,198,136,198,198,198,198,197,198,198,198,198,198,198,198,198,198,198,198,198,198,77,217,77,217,77,217,222,222,222,221,221,221,220,220,219,219,219,198,196,197,196,197,196,197,197,198,197,198,197,198,197,198,197,198,197,198,197,198,197,196,196,196,197,198,196,197,196,197,197,198,197,198,197,198,198,198,197,198,197,198,197,198,197,198,198,198,197,198,198,198,196,197,197,198,196,197,196,197,197,198,197,197,198,197,198,198 +,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,107,107,107,107,107,107,107,107,107,107,252,107,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,107,109,107,252,109,109,109,252,252,252,252,252,109,107,107,109,109,109,109,109,107,109,107,107,107,107,107,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,44,44,44,44,44,34,36,38,40,43,45,47,34,36,37,38,39,41,42,43,44,46,47,45,46,45,46,45,46,45,46,45,46,45,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,96,96,47,44,41,38,35,32,98,98,47,43,40,36,32,99,99,99,100,100,100,47,43,39,36,32,35,38,41,44,47,102,103,102,102,102,102,102,102,57,97,41,43,41,42,41,42,44,45,47,46,61,46,49,99,61,99,49,102,98,100,98,100,100,100,43,100,46,102,101,102,102,102,102,103,96,96,96,97,98,52,97,52,52,53,53,53,53,53,53,53,53,54,53,54,54,101,54,54,54,54,54,55,54,55,55,55,55,55,55,56,55,56,56,56,56,56,56,56,56,57,57,57,57,57,57,57,57,58,58,58,58,58,58,58,58,59,58,59,59,59,59,59,59,60,59,60,60,59,60,60,60,59,60,60,60,61,61,61,61,61,61,62,61,62,62,62,62,62,62,62,62,63,63,63,63,63,63,60,60,61,61,61,63,61,61,62,62,62,63,62,62,62,61,62,62,59,61,88,88,88,88,89,59,62,89,63,89,89,67,91,65,65,66,92,68,92,65,66,68,65,67,66,68,67,68,65,68,67,68,68,68,70,70,71,70,71,70,70,71,71,70,71,71,71,71,72,72,72,72,73,73,74,74,74,74,75,75,76,76,76,76,77,77,77,77,78,78,78,78,79,79,79,64,79,64,64,64,65,65,65,65,66,66,67,67,68,68,68,68,69,70,70,70,71,71,72,72,73,73,73,73,74,74,75,75,76,76,76,76,76,76,76,77,77,77,217,77,217,217,217,222,222,221,221,221,221,220,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,198,198,198,198,198,198,198,198,196,196,196,196,196,196,198,197,197,197,197,197,197,198,198,198,198,198,198,197,197,198,197,198,197,198,198,198,197,198,198,198,198,196,197,197,198,196,196,197,197,198,198,198,198,198,198,198,198 +,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,252,107,109,107,252,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,107,107,252,107,109,107,252,107,252,107,252,107,252,109,252,109,252,109,109,109,107,107,109,109,109,109,109,107,109,107,107,107,107,107,47,39,32,34,37,38,41,42,45,46,32,33,35,35,37,38,40,40,42,43,45,45,47,45,44,45,44,45,44,45,45,46,46,46,45,46,46,46,45,46,46,46,45,46,46,46,45,47,47,47,47,47,47,47,47,47,47,44,43,40,39,36,34,32,96,97,32,34,37,39,42,44,47,96,97,96,47,39,32,39,47,97,98,97,98,98,99,98,98,99,99,47,44,41,38,35,32,34,37,39,42,44,47,101,102,101,52,102,102,102,34,35,38,39,42,43,46,47,102,102,102,102,97,96,57,97,102,102,102,97,102,102,49,51,49,102,99,49,50,100,100,50,100,45,100,45,43,101,101,101,100,102,102,103,52,96,52,96,53,96,97,52,98,52,53,53,54,53,54,53,54,53,54,100,55,54,55,54,55,54,55,55,55,55,56,55,56,55,56,56,56,56,57,56,57,56,57,57,57,57,58,57,58,57,58,57,58,58,58,58,59,58,59,58,59,59,59,59,60,59,60,59,60,60,60,60,61,60,60,61,60,58,60,61,61,60,59,60,61,61,61,61,63,62,63,62,62,63,62,62,63,62,63,62,62,62,61,63,60,63,63,62,61,61,61,63,61,62,61,63,61,63,63,62,62,61,62,61,61,62,88,63,63,89,62,89,61,90,90,65,64,90,66,67,64,67,67,67,66,68,67,68,69,66,68,69,69,67,68,70,68,69,70,69,71,71,72,72,71,72,72,71,72,71,72,72,73,72,73,73,74,73,74,75,74,74,75,75,76,75,76,76,77,76,77,77,78,78,79,78,79,79,79,79,79,64,79,64,64,64,65,65,66,66,67,66,67,67,68,68,69,69,70,69,70,70,71,71,72,72,73,72,73,73,74,74,75,75,76,76,76,217,217,217,217,217,217,217,217,222,222,221,221,221,221,220,221,220,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,197,196,198,196,197,197,198,197,198,197,198,197,198,198,198,197,198,197,198,197,198,198,198,197,198,198,198,198,196,196,193,196,193,196,197,197,198,199,199,199,193,193,198,198,198 +,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,252,252,107,107,107,107,107,107,107,107,107,252,107,109,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,107,107,109,107,109,109,252,109,252,109,252,252,252,252,252,252,107,107,109,107,109,107,109,107,109,107,107,107,107,44,44,45,44,45,44,45,44,44,44,45,97,97,99,99,100,100,102,102,103,96,45,45,45,97,98,99,101,102,103,46,46,47,47,47,47,47,103,100,101,100,101,101,101,47,32,34,37,39,42,44,47,97,98,98,98,98,99,99,99,100,100,100,101,101,101,101,102,102,102,102,103,103,96,96,96,96,97,97,97,32,35,37,40,42,45,47,47,47,44,47,42,47,47,101,52,100,100,100,100,100,102,101,100,100,102,101,102,102,50,102,102,102,102,102,102,102,102,50,50,102,102,102,57,102,102,102,97,102,57,103,98,98,98,50,99,50,50,50,99,50,50,99,100,51,45,51,45,51,101,100,52,102,102,102,102,52,52,52,53,53,53,53,53,53,53,53,54,54,54,54,54,54,54,54,55,55,55,55,55,55,55,55,56,56,56,56,56,56,56,56,57,57,57,57,57,57,57,57,58,58,58,58,58,58,58,58,59,59,59,59,59,59,59,59,60,60,60,60,60,60,61,60,61,61,61,61,61,60,61,60,61,58,61,61,60,60,59,59,61,61,61,62,62,63,61,61,61,63,63,62,62,63,62,62,62,61,61,60,61,61,61,61,61,62,61,63,61,61,63,63,63,62,58,62,58,61,62,89,88,87,62,86,88,64,90,90,64,66,65,66,67,68,68,67,66,67,68,68,68,68,69,69,70,69,68,69,70,69,70,69,69,70,70,71,73,74,72,72,74,72,73,72,73,73,73,73,73,73,74,75,75,74,75,75,75,75,76,76,76,76,77,77,77,77,78,78,78,78,79,79,79,79,79,79,79,64,64,64,64,64,65,27,31,30,29,28,27,26,26,25,24,23,22,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,221,221,221,221,221,221,221,220,220,220,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,197,197,197,197,197,197,197,197,198,198,198,198,198,198,197,197,197,197,197,197,198,198,198,198,197,197,198,198,199,199,199,199,199,193,199,196,193,199,193,193,193,193,199,199,199,199 +,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,252,107,109,107,252,107,252,107,252,107,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,109,107,107,107,252,107,252,107,252,107,252,107,252,109,252,109,252,109,252,109,252,252,107,109,109,109,109,107,109,107,109,107,107,107,45,46,46,46,46,46,47,32,34,36,39,40,43,45,47,102,103,47,47,47,98,98,100,100,102,103,47,47,47,47,96,96,97,96,97,96,97,32,98,97,98,97,100,100,100,98,99,98,99,99,100,99,100,99,100,100,101,100,47,45,44,41,40,37,36,33,32,102,103,102,103,47,32,34,37,39,42,44,47,97,97,98,98,99,101,51,51,33,47,43,40,35,32,47,47,51,103,100,102,102,102,101,101,102,101,100,45,99,50,103,103,102,102,50,50,57,50,50,50,50,50,57,103,102,102,57,54,57,58,50,54,50,53,50,50,50,49,50,51,50,50,50,100,100,51,100,51,100,52,45,52,52,101,102,101,52,53,52,96,53,54,53,54,53,54,53,54,54,55,54,55,54,55,54,55,55,56,55,56,55,56,56,56,56,57,56,57,57,57,57,58,57,58,57,58,58,59,58,59,58,59,58,59,58,59,60,60,60,59,59,59,60,61,61,60,61,60,61,61,61,62,61,62,62,62,62,62,63,61,61,61,62,61,60,60,61,60,61,59,94,59,62,63,62,63,83,83,82,61,62,63,82,62,63,63,63,61,83,84,84,62,62,62,62,62,62,62,63,62,62,62,63,63,62,62,62,62,62,85,62,61,62,86,87,88,89,65,66,67,68,67,67,69,68,69,68,69,70,69,70,69,70,70,70,71,71,70,71,71,71,71,72,72,71,73,72,73,72,74,74,74,74,74,74,74,74,75,74,75,75,74,76,75,75,75,76,76,76,77,76,77,76,77,77,78,77,78,78,79,78,79,78,79,79,79,64,79,31,64,28,65,26,31,29,28,25,24,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,217,217,217,221,217,221,217,221,217,221,221,221,221,220,221,220,221,220,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,197,196,197,197,198,197,198,198,198,198,198,197,198,198,196,196,197,196,197,197,198,197,198,198,198,198,198,198,199,199,193,196,193,193,193,193,193,193,194,193,199,199,199,193,193,193,193 +,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,107,252,107,107,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,109,107,107,107,252,109,109,109,252,252,252,109,252,252,252,252,252,252,252,109,109,109,109,107,109,107,107,107,107,47,32,35,38,41,44,47,47,47,47,47,47,47,103,102,103,103,32,33,34,35,36,37,39,39,41,41,43,44,45,46,47,98,98,47,45,43,41,38,37,34,32,47,99,99,99,99,32,34,37,39,42,44,47,100,101,101,101,101,101,101,101,101,102,102,102,102,102,47,40,32,47,103,103,96,96,96,97,96,97,97,98,102,98,100,101,99,98,100,99,50,98,103,99,49,100,49,100,102,100,49,101,101,101,102,51,102,102,102,102,50,51,51,50,100,100,100,100,52,102,57,54,50,58,102,54,50,50,61,63,50,56,51,50,49,103,50,50,50,50,50,51,51,100,100,100,51,99,52,46,52,52,101,53,102,53,53,53,53,53,53,54,54,54,54,54,54,55,55,55,55,55,55,56,55,56,56,56,56,56,56,57,57,57,57,57,57,58,58,58,58,58,58,59,58,59,59,59,59,59,59,59,58,60,60,58,60,60,60,60,59,60,61,61,62,60,61,61,62,61,62,62,63,63,63,62,62,63,61,61,61,62,60,60,61,61,61,62,61,60,94,60,61,81,81,64,63,63,82,82,62,82,82,64,62,82,83,82,60,60,84,84,62,62,83,61,62,64,62,63,66,62,64,61,62,85,62,86,63,86,85,86,87,87,64,65,67,68,67,69,68,68,69,69,69,70,70,70,72,70,71,71,71,71,72,72,73,72,73,72,73,72,73,72,74,73,74,74,73,75,75,75,75,74,75,74,74,75,74,76,76,75,76,76,75,76,76,76,76,77,77,77,77,78,78,78,78,79,78,79,79,79,79,79,64,79,29,64,26,65,23,65,29,66,27,31,29,28,26,25,23,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,217,217,221,217,221,221,221,221,221,221,221,221,221,220,220,220,220,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,198,196,196,198,198,198,198,198,198,198,199,196,196,196,196,193,193,193,194,193,194,196,199,199,193,193,193,193,193,193,193 +,252,108,252,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,107,107,107,252,107,252,107,252,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,109,107,252,107,109,107,252,107,252,107,252,107,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,107,109,107,252,107,107,107,102,101,32,33,36,37,39,40,42,43,46,47,103,102,103,103,103,102,96,96,96,96,97,96,97,96,97,97,97,97,98,98,98,97,98,98,99,98,99,98,99,98,98,99,99,100,99,101,100,99,100,100,101,100,101,100,101,34,37,38,41,42,45,47,102,101,102,102,103,102,103,102,102,96,103,96,97,97,97,97,99,51,99,100,51,99,50,51,103,51,97,96,96,96,96,52,103,102,49,100,101,49,45,51,100,51,100,50,102,50,102,52,53,100,45,52,103,50,50,50,50,49,50,54,55,50,50,55,54,59,52,50,50,50,50,53,50,50,51,50,51,51,51,51,52,51,100,52,52,100,53,52,53,53,53,53,54,53,54,53,54,54,55,54,55,55,55,55,56,55,56,55,56,56,57,56,57,56,57,57,58,57,58,57,58,58,59,58,59,58,59,59,60,59,60,59,60,60,60,61,59,60,59,61,59,60,60,60,88,59,60,61,61,61,61,62,62,63,61,62,62,62,62,61,63,63,63,61,63,62,63,62,61,94,61,61,59,62,93,60,60,62,63,64,81,64,81,65,82,82,65,82,64,83,63,65,83,83,66,83,83,83,62,64,84,83,67,65,67,66,63,67,64,64,85,65,86,65,87,65,69,86,69,66,67,69,69,70,70,70,71,70,70,70,71,71,72,71,72,73,72,74,73,74,74,73,73,73,74,73,74,73,74,75,74,74,74,75,75,74,76,75,76,75,76,75,74,75,75,76,77,75,76,76,76,76,77,76,77,77,78,77,78,78,78,78,79,78,79,78,79,79,79,64,79,64,64,64,65,25,65,24,66,22,67,26,67,25,25,23,31,29,28,25,24,22,218,218,218,218,218,218,218,218,218,217,218,217,218,217,217,217,217,221,217,221,217,221,221,221,221,221,221,220,221,220,221,220,221,220,220,220,220,219,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,198,199,196,196,193,196,193,196,193,194,193,194,199,199,196,196,193,193,193,193,194,193,194 +,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,107,107,109,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,107,107,109,107,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,107,107,107,107,102,101,102,102,102,102,102,102,102,102,34,35,37,38,40,41,43,44,46,47,96,96,32,34,36,38,41,43,45,47,99,99,98,98,98,98,98,98,98,98,99,98,99,99,99,102,49,99,100,100,100,100,46,101,101,100,102,101,101,101,101,101,102,101,100,102,102,102,103,103,103,98,101,103,51,97,97,51,52,101,100,51,102,53,102,51,97,51,97,49,98,49,52,102,50,102,50,101,50,50,101,49,102,51,100,100,51,51,100,103,51,51,51,51,97,51,51,51,52,51,51,49,48,48,48,50,55,52,50,50,50,50,50,50,50,50,51,50,51,51,51,51,52,52,52,52,53,52,53,53,53,53,53,53,54,54,54,54,55,55,55,55,55,55,56,56,56,56,56,56,57,57,57,57,58,57,58,58,58,58,58,58,59,59,59,59,60,60,60,60,60,60,61,60,61,61,61,61,61,61,62,60,59,60,62,59,60,58,88,59,60,59,60,63,62,62,62,63,63,63,62,62,61,90,91,92,63,92,63,92,62,93,61,61,95,60,94,94,62,63,62,80,65,65,65,82,65,65,82,82,66,66,67,67,83,68,84,67,66,65,84,83,64,65,69,69,67,68,68,68,68,68,69,70,66,69,67,67,71,70,71,71,71,71,71,72,72,71,71,71,71,71,71,72,73,72,74,75,74,74,74,74,74,75,74,75,74,74,74,74,74,75,75,74,75,74,75,76,75,75,76,75,75,76,75,75,76,75,76,77,76,76,77,77,77,77,77,77,78,77,78,78,78,78,79,78,79,79,79,79,79,64,79,64,64,64,64,64,65,65,65,26,66,25,67,24,67,23,68,22,31,29,27,24,22,31,23,218,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,217,221,217,221,221,221,221,221,221,221,221,220,220,220,220,220,219,220,220,220,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,199,196,196,196,196,193,193,193,193,194,194,199,196,196,196,193,193,194,193,194,193,194,193 +,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,252,107,252,107,252,107,252,107,252,107,252,107,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,109,107,107,107,252,107,252,107,252,107,252,107,252,107,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,107,109,107,107,107,107,101,32,34,37,38,41,42,45,47,102,102,103,103,103,103,103,96,103,103,96,97,96,96,96,97,97,97,97,99,98,99,98,98,97,103,99,98,99,99,99,100,99,99,99,47,99,103,100,102,101,100,103,101,100,100,51,101,102,101,101,102,102,103,102,102,102,102,101,49,49,101,51,101,101,50,102,102,102,100,51,51,98,52,97,52,52,52,52,52,49,49,98,50,51,50,50,102,50,49,50,46,50,50,100,50,51,50,50,50,51,51,102,51,51,51,51,51,102,102,51,102,51,50,51,51,51,50,48,48,54,51,51,50,51,50,50,50,53,51,52,51,52,52,53,52,53,53,54,53,54,53,54,54,54,54,55,54,55,55,56,55,56,56,57,56,57,57,57,57,58,57,58,58,59,58,59,58,59,59,60,59,60,60,61,60,61,61,61,62,61,60,62,60,61,60,62,62,62,61,62,60,59,59,61,59,60,62,60,58,88,59,61,64,62,61,62,63,62,89,89,90,63,91,91,62,91,92,92,92,93,93,94,63,94,62,94,80,80,95,62,95,65,66,65,64,66,66,65,64,65,65,66,68,68,69,68,69,68,68,69,68,67,67,69,71,67,70,70,69,71,70,70,71,72,71,70,69,73,70,71,72,71,72,72,72,72,72,72,72,73,73,73,73,73,74,74,74,74,75,74,74,75,74,75,75,74,75,75,75,75,75,74,75,75,75,75,75,75,75,76,76,75,76,77,76,77,76,76,76,76,76,77,76,77,77,78,77,78,77,78,78,79,78,79,78,79,78,79,79,79,64,79,29,79,64,64,27,65,27,66,30,66,29,67,28,67,27,68,27,69,26,218,25,30,24,27,23,24,22,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,221,217,221,217,221,221,221,221,221,221,220,221,220,221,220,220,220,220,219,220,219,220,219,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,199,196,196,196,196,193,196,193,194,194,194,199,196,196,196,193,196,194,193,194,193,194,194,194 +,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,107,107,107,107,107,252,107,109,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,107,107,107,252,109,109,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,107,109,107,252,107,107,107,107,101,102,102,102,102,102,102,102,102,103,103,102,102,103,103,47,32,36,39,43,47,99,97,98,97,98,97,98,98,100,98,100,99,101,96,100,96,99,101,51,97,96,51,99,47,102,100,103,101,102,102,102,102,51,52,99,51,102,103,103,102,102,103,102,102,52,52,102,101,102,101,51,51,102,50,51,51,102,52,52,52,53,52,53,52,52,97,51,50,51,96,50,50,51,102,50,101,50,50,100,50,50,50,50,50,51,51,51,51,51,52,102,52,53,52,52,52,52,52,52,52,52,51,51,52,51,51,51,51,51,51,54,51,51,52,51,54,52,52,52,52,53,53,53,53,53,53,54,54,54,54,55,55,55,55,56,56,56,56,57,57,57,57,58,58,58,58,58,58,59,59,59,59,60,60,60,60,61,61,61,61,61,62,62,62,62,62,62,62,63,61,63,62,62,62,62,84,62,84,62,63,61,61,62,60,60,60,60,60,59,60,89,69,61,88,63,69,62,90,90,88,90,90,63,91,63,91,92,93,94,63,94,94,94,64,94,95,81,64,66,65,65,66,65,66,66,67,67,68,67,67,68,69,68,68,68,69,68,69,70,71,72,71,71,70,72,70,72,71,73,71,70,71,71,71,72,72,73,72,73,72,72,72,73,72,73,73,73,74,72,73,73,73,74,75,73,74,74,75,75,75,75,75,76,75,75,76,75,75,75,75,75,75,76,76,75,76,75,76,75,76,76,76,77,76,76,77,77,76,77,77,77,77,78,78,78,78,78,78,78,78,79,79,79,30,79,79,79,64,79,64,64,28,64,28,65,27,65,27,66,30,67,29,67,28,68,27,68,26,31,25,27,23,25,22,22,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,217,217,221,221,221,221,221,221,221,221,220,221,220,220,220,220,220,220,220,220,220,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,196,196,193,196,196,196,193,194,193,194,196,196,196,196,193,193,194,193,194,194,194,194,193,194 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,252,107,252,107,252,107,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,109,109,107,109,107,252,107,107,107,102,101,102,101,102,102,102,102,102,103,103,102,103,102,103,96,97,97,97,97,97,97,97,97,98,96,100,99,98,51,102,100,51,100,103,97,97,51,97,96,47,97,96,101,103,51,101,50,51,50,99,98,102,99,99,52,51,51,102,103,101,53,103,52,103,102,54,102,53,102,102,52,102,54,102,52,52,52,52,52,53,52,52,52,52,52,52,52,52,52,52,52,52,52,52,51,50,50,50,51,50,50,51,50,49,51,52,51,52,52,53,52,53,53,54,53,53,53,53,53,53,53,54,54,54,52,52,51,52,54,51,51,54,51,52,51,51,52,52,53,52,53,53,54,53,54,55,54,55,55,56,56,55,56,56,56,57,57,58,57,58,58,59,58,58,59,58,59,58,60,59,61,61,61,62,61,62,62,62,63,62,61,63,61,61,60,60,62,62,62,63,63,63,63,61,82,62,82,63,59,84,62,85,62,61,60,62,62,62,88,88,62,60,64,88,89,64,64,90,69,91,65,91,91,67,92,91,92,93,64,64,65,64,94,64,64,64,65,65,65,66,67,67,66,67,67,67,67,67,67,68,68,68,69,68,69,69,70,69,69,70,72,71,72,72,72,71,72,71,73,72,71,72,72,73,73,74,73,71,74,73,73,73,73,73,73,73,74,73,74,73,74,75,74,74,74,74,74,74,74,75,75,75,75,75,76,75,75,76,76,75,75,76,75,77,76,76,75,76,77,76,76,76,76,77,77,76,77,77,77,78,77,78,78,78,78,78,78,79,78,79,79,79,79,79,64,79,64,79,64,64,64,65,31,65,30,66,29,66,27,67,27,68,26,68,25,69,23,30,23,31,22,31,23,29,30,26,28,24,26,218,25,218,23,218,22,218,218,218,218,218,218,218,218,218,217,218,217,217,221,217,221,217,221,221,221,221,220,221,220,221,220,221,220,221,220,220,220,220,219,220,219,220,219,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,196,196,193,196,194,196,194,194,193,194,194,199,196,196,193,196,194,193,194,193,194,193,194,194,194 +,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,107,107,107,107,107,107,107,107,107,109,107,252,252,252,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,107,109,107,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,109,107,107,107,109,107,107,107,107,107,102,101,102,102,102,102,103,103,103,102,96,103,96,103,97,96,97,98,103,97,99,100,98,53,98,99,98,97,97,99,97,100,99,97,102,52,97,102,51,101,51,101,51,51,103,50,50,98,99,99,51,98,51,102,96,52,53,53,102,53,53,52,102,102,102,102,53,52,53,52,52,52,52,53,52,52,53,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,53,53,53,53,53,53,54,55,55,54,56,55,56,51,58,52,56,56,54,58,51,54,54,52,51,53,52,52,53,53,55,54,55,55,55,56,56,57,57,57,57,55,57,56,58,58,59,59,60,60,60,61,61,59,61,59,61,62,58,62,60,60,60,61,61,62,62,63,63,62,62,63,62,62,62,62,62,62,62,95,63,80,62,82,63,83,84,84,61,59,85,59,60,60,62,59,63,90,60,62,64,61,66,67,65,68,71,68,68,69,65,65,66,69,67,65,65,65,66,66,66,66,66,66,66,65,66,66,66,67,67,67,67,67,67,68,67,67,68,68,68,69,69,69,69,71,69,70,71,70,71,72,71,72,72,72,73,73,72,73,73,73,72,74,72,73,72,73,74,74,74,74,73,73,73,74,74,73,75,74,74,74,74,74,74,74,74,74,75,75,75,75,75,75,75,75,76,76,76,76,76,77,77,76,77,76,76,77,76,78,77,76,77,76,77,78,77,78,78,78,78,78,78,79,79,79,79,79,79,79,79,79,64,64,64,64,64,64,64,65,28,65,28,66,27,66,27,67,26,67,26,68,26,68,25,69,25,79,31,31,29,26,26,24,31,23,29,22,26,218,24,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,217,221,221,221,221,221,221,221,221,221,221,220,220,220,220,220,220,220,220,220,220,219,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,196,196,193,196,194,196,194,193,194,194,194,196,193,196,196,196,194,193,194,194,194,194,194,197,194,194 +,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,108,107,107,107,252,107,252,107,252,107,252,107,252,107,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,252,107,252,107,252,107,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,109,107,109,109,107,109,107,107,107,109,101,102,101,102,101,102,103,103,103,103,96,103,103,96,97,97,97,52,97,98,97,103,53,52,47,101,52,99,97,52,99,52,46,52,46,52,52,52,52,54,53,54,54,51,51,50,51,102,52,53,53,49,52,52,53,53,53,50,103,102,52,102,102,53,102,52,102,52,53,53,52,53,53,53,53,53,53,53,53,53,52,53,52,53,52,53,52,53,52,53,52,53,52,53,52,53,52,53,52,53,52,53,52,53,53,53,52,53,53,53,53,53,53,53,54,54,54,54,54,55,56,55,56,57,56,54,57,54,56,58,56,57,53,56,58,53,52,55,53,54,55,53,55,55,57,58,57,58,58,58,58,57,58,57,59,59,57,60,58,61,59,62,63,63,61,61,61,59,60,63,59,60,63,63,63,60,60,60,63,63,92,62,93,63,63,61,63,81,62,63,95,81,63,63,80,83,82,84,85,84,64,60,64,64,84,62,86,86,64,69,59,86,67,68,67,68,67,70,71,73,75,67,69,70,68,69,66,66,69,66,71,68,67,68,67,66,66,67,67,67,67,67,67,68,68,68,68,68,68,69,69,69,68,69,69,69,70,69,69,70,71,71,71,72,72,72,72,73,73,72,73,73,73,73,74,73,74,73,74,74,74,74,74,73,74,73,74,75,74,75,73,74,75,75,74,74,74,75,74,75,76,75,76,75,75,75,76,76,77,76,77,76,77,77,77,77,76,77,78,77,78,77,77,77,78,78,77,78,78,79,78,79,78,79,79,79,79,79,64,79,64,79,64,79,64,64,64,65,64,65,65,66,27,66,27,67,27,67,30,68,29,68,28,69,27,69,26,70,25,79,24,27,23,25,22,24,23,22,22,218,22,218,31,218,26,218,22,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,221,217,221,217,221,221,221,221,220,221,220,221,220,221,220,221,220,220,220,220,219,220,219,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,196,193,196,194,193,194,193,194,193,194,196,193,196,193,196,194,193,194,193,194,193,194,197,194,197,194 +,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,107,108,107,107,107,107,107,108,107,252,107,109,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,109,107,109,109,109,107,109,107,107,109,101,102,101,52,103,102,52,103,103,102,52,103,96,52,96,52,97,97,52,98,52,96,52,96,52,103,96,52,102,99,52,52,54,54,101,52,53,52,54,101,54,53,52,53,52,53,53,49,52,96,52,52,52,53,53,53,102,53,52,54,102,52,52,53,52,102,53,52,53,52,53,52,53,53,53,53,53,53,53,52,53,53,53,52,53,53,53,52,53,53,53,52,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,54,54,54,54,54,55,55,55,55,55,55,55,56,56,56,56,58,54,52,53,56,59,52,52,56,54,56,55,57,54,56,57,59,60,59,60,58,63,57,63,57,62,58,62,57,89,58,63,58,61,62,61,62,61,62,59,63,62,91,62,60,62,59,61,61,58,92,92,63,92,92,63,63,93,62,81,61,81,62,81,82,82,82,81,82,84,83,84,86,64,65,87,66,87,86,65,65,86,69,66,66,65,64,66,68,69,75,72,73,73,74,68,68,74,73,73,72,69,73,68,72,75,68,68,69,69,69,69,70,68,68,67,67,69,69,70,69,69,70,69,70,69,70,70,70,70,71,71,71,71,70,70,71,72,72,73,72,71,73,72,73,74,73,73,74,73,74,74,74,75,75,74,74,75,74,74,75,74,75,74,75,75,75,75,75,75,75,74,75,76,75,76,76,76,76,76,76,77,76,77,77,77,77,77,77,77,78,77,78,78,78,78,78,78,78,78,78,79,79,79,79,79,79,79,79,79,79,64,64,64,64,64,64,64,64,65,65,65,65,66,66,66,66,66,66,67,23,67,26,68,26,68,25,69,25,69,25,70,24,70,24,27,24,29,23,30,23,218,22,218,30,218,28,218,26,218,24,218,23,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,217,221,217,221,221,221,221,221,221,221,221,221,221,220,221,220,220,220,220,220,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,196,196,196,194,193,194,194,194,194,194,196,193,193,196,196,193,193,194,194,197,197,197,197,197,197,197,197 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,108,107,252,107,109,107,252,107,252,107,252,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,252,107,109,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,107,107,109,107,109,107,109,107,109,109,101,53,102,102,52,102,53,102,53,53,102,103,53,96,103,52,52,97,52,47,53,54,53,54,53,54,102,52,52,102,53,52,53,54,54,53,53,101,54,54,52,53,52,53,54,53,54,53,54,54,52,53,53,52,53,53,53,50,52,52,52,102,52,53,53,53,53,53,53,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,54,54,54,54,54,55,55,55,55,55,55,55,56,56,56,56,56,56,56,56,56,56,58,52,55,57,58,52,55,58,58,60,57,53,56,59,56,58,55,59,56,63,63,85,63,60,86,60,88,62,90,59,90,59,89,60,61,60,89,63,90,63,62,91,63,92,60,60,63,62,61,60,62,60,92,93,92,92,63,93,93,63,94,63,81,80,65,62,65,81,83,83,83,65,65,65,64,65,65,65,65,66,89,65,88,66,66,68,70,66,68,70,71,71,75,72,70,74,75,73,75,74,73,74,72,68,71,73,72,72,73,71,72,69,68,69,71,72,70,70,71,69,71,70,70,71,71,71,71,70,71,72,71,71,72,71,72,72,71,72,71,71,70,72,72,73,73,72,73,73,73,73,74,74,74,74,74,74,74,75,74,75,75,75,75,74,75,75,75,75,75,76,76,75,75,76,75,75,76,76,76,77,76,77,76,77,76,77,77,78,77,78,77,78,77,78,78,79,78,79,78,79,78,79,79,79,64,79,64,79,64,79,64,79,64,64,64,64,64,65,28,65,28,65,65,66,30,66,30,67,29,67,28,68,27,68,27,69,26,69,25,70,24,70,24,71,23,71,30,72,28,27,27,28,26,29,24,31,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,221,217,221,217,221,217,221,217,221,221,221,221,220,221,220,221,220,221,220,221,220,220,219,220,219,220,219,220,219,219,219,220,219,219,219,220,219,219,219,220,219,219,219,220,219,196,196,193,196,194,193,194,193,194,194,196,196,196,196,197,196,194,194,194,194,197,197,198,197,198,197,198,197,198 +,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,108,107,108,107,107,107,109,107,109,107,252,107,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,107,109,107,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,109,107,109,109,109,107,109,107,107,107,109,109,50,52,102,53,102,53,53,102,98,103,53,98,102,53,53,53,54,53,98,53,54,54,54,54,54,54,54,54,54,54,54,54,55,101,55,54,55,55,54,54,54,53,53,53,54,53,54,55,54,55,101,55,55,52,52,53,52,52,52,53,53,53,53,53,53,53,54,53,53,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,54,54,54,54,54,54,54,54,54,54,54,55,54,55,54,55,54,54,55,56,56,56,56,56,56,56,56,56,56,56,57,56,57,57,57,58,58,57,57,57,56,57,55,59,60,59,60,58,63,57,58,62,85,85,86,86,86,62,87,88,89,90,62,90,89,64,60,89,62,89,91,90,62,66,91,92,90,93,91,91,91,92,62,94,63,92,61,92,93,93,95,94,80,94,95,81,81,66,81,67,82,82,65,65,65,68,65,66,66,66,67,66,66,66,66,66,66,66,67,67,67,67,68,70,70,75,72,72,74,75,75,75,73,71,75,72,74,71,71,75,73,73,72,74,73,71,71,72,72,71,71,71,72,71,73,71,71,73,72,72,72,72,72,72,73,72,72,72,72,73,73,71,72,73,71,72,73,72,73,73,73,73,73,74,73,74,74,74,74,74,74,75,74,75,75,75,75,75,75,75,75,76,76,76,76,76,76,76,76,77,77,77,77,77,77,77,77,78,77,78,78,78,78,78,78,79,78,79,79,79,79,79,79,79,30,79,79,79,64,79,29,64,29,64,64,64,64,64,64,65,65,65,65,66,65,66,66,66,66,67,67,67,67,68,68,68,26,69,25,69,25,70,25,70,24,70,24,71,30,71,29,72,27,22,30,218,29,218,27,218,26,218,30,218,28,218,25,218,23,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,217,217,217,221,217,221,221,221,221,221,221,221,221,221,221,220,220,220,220,220,220,220,220,219,220,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,196,196,196,196,194,193,194,193,194,194,196,196,196,196,196,196,197,197,197,197,197,197,197,197,198,197,198,198,198,198 +,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,107,108,107,252,107,252,107,252,107,252,107,107,107,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,107,252,107,252,107,252,107,252,109,252,109,252,109,252,109,252,109,252,252,252,109,109,107,109,107,109,107,109,107,107,107,109,52,52,103,102,53,102,98,53,52,53,53,54,53,54,53,98,53,54,54,54,54,54,54,55,54,54,54,55,54,55,54,55,55,55,54,55,55,55,55,55,55,55,55,55,55,54,54,54,55,54,55,55,55,55,55,55,55,53,56,52,53,54,53,53,53,54,54,54,54,54,54,54,54,54,54,54,54,55,54,55,54,55,54,54,54,55,54,55,54,55,54,55,54,55,54,55,54,55,54,55,54,55,55,55,55,55,55,55,55,56,56,57,56,57,56,57,57,57,57,58,57,58,57,58,57,58,58,59,58,58,56,57,57,58,59,56,63,63,85,63,60,84,83,84,83,84,85,86,87,86,88,91,64,65,62,65,92,65,90,91,65,64,92,91,67,92,65,65,65,66,93,67,67,92,65,64,67,63,65,65,93,64,65,66,67,68,80,68,66,81,66,65,64,66,66,66,69,67,67,67,67,70,69,68,68,68,68,67,69,67,68,69,68,66,69,66,70,69,71,68,73,74,75,75,74,75,75,72,74,74,72,72,75,111,111,111,104,104,74,74,72,71,73,74,72,73,73,72,73,73,73,73,73,72,72,72,72,72,72,74,74,73,73,73,73,74,74,74,73,74,74,74,75,74,75,75,74,75,74,75,74,75,75,76,75,76,75,76,75,76,76,76,76,77,76,77,76,77,76,77,77,78,77,78,77,78,77,78,78,79,78,79,78,79,78,79,79,79,79,79,79,79,64,79,64,79,64,79,64,79,29,64,64,64,64,64,30,65,29,65,27,66,25,66,66,67,66,67,66,67,67,68,67,68,68,69,68,69,69,70,69,70,28,70,28,71,27,71,26,72,25,72,24,73,24,29,23,31,22,218,22,218,30,218,28,218,27,218,25,218,24,218,22,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,221,217,221,217,221,217,221,221,221,221,221,221,220,221,220,221,220,221,220,220,220,221,219,220,219,220,219,220,219,220,219,220,219,220,219,220,219,220,219,196,196,196,196,197,196,194,196,194,194,194,197,196,196,197,196,197,196,197,196,197,197,198,197,198,197,198,197,198,197,198 +,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,107,108,107,108,107,108,107,108,108,252,108,252,108,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,109,109,109,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,109,109,107,109,109,107,109,107,109,107,109,107,109,53,52,53,102,53,52,53,98,53,102,53,54,53,54,54,54,53,54,54,54,54,54,54,55,54,55,54,55,54,55,54,55,55,55,55,55,55,55,56,56,56,56,56,56,55,55,55,55,55,55,55,55,55,55,56,54,54,53,54,56,53,54,54,54,53,55,54,54,54,54,54,55,54,54,54,54,54,55,54,55,54,55,54,55,54,55,54,55,54,55,55,55,55,55,55,55,55,55,55,55,56,56,56,57,57,57,57,57,57,57,57,58,58,58,58,58,58,58,58,59,59,59,59,59,59,59,59,60,63,63,62,62,84,58,62,85,85,86,86,86,83,84,83,84,84,85,85,85,85,88,88,91,91,92,92,64,66,64,65,64,66,65,67,65,66,65,67,66,68,67,67,67,66,65,66,65,92,68,65,66,66,67,68,68,69,66,67,66,68,64,67,66,66,67,69,69,67,69,69,69,69,69,70,69,69,68,69,68,69,70,69,70,71,69,67,67,70,67,71,71,73,75,75,74,105,105,105,105,105,105,111,111,110,110,110,110,110,104,76,72,73,74,74,74,73,75,74,73,74,73,74,73,74,74,74,74,74,74,74,74,74,74,75,74,75,74,75,75,75,75,75,75,75,75,75,75,75,75,75,76,75,76,76,76,76,76,76,76,76,77,77,77,77,77,77,77,77,78,77,78,77,78,78,78,78,78,78,78,78,79,79,79,79,79,79,79,79,79,79,79,64,79,64,64,64,64,64,64,64,64,64,64,64,65,65,65,65,66,66,66,27,67,27,67,27,67,27,68,26,68,26,68,26,69,26,69,25,70,25,70,25,71,24,71,24,71,31,72,30,72,29,72,28,28,31,29,30,30,28,31,27,218,26,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,217,217,217,217,221,217,221,221,221,221,221,221,221,221,221,221,220,220,220,220,220,220,220,220,219,219,219,219,219,219,219,219,219,219,219,219,219,196,196,196,196,197,196,197,197,194,194,194,194,196,196,196,196,197,197,197,197,197,197,197,197,198,197,198,198,198,198,198,198 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,107,252,107,108,107,252,107,252,108,252,108,252,108,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,252,107,252,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,109,107,109,107,109,107,109,107,107,107,109,107,109,101,52,53,53,101,53,53,103,53,54,54,54,54,54,54,55,54,55,54,55,55,55,55,55,55,55,55,55,55,55,55,55,55,56,56,57,56,57,56,57,57,57,57,58,58,56,56,56,56,56,55,55,55,55,57,57,57,58,58,58,56,55,55,55,55,55,54,54,55,55,55,55,54,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,56,57,56,57,56,57,57,58,57,58,57,58,57,58,58,58,58,59,58,59,58,59,59,59,59,59,59,60,59,60,60,60,60,60,60,60,60,61,63,83,83,83,83,63,84,83,84,83,84,85,86,84,83,84,85,84,86,85,86,86,88,88,89,89,89,65,64,66,65,64,65,65,65,66,66,66,67,66,68,68,67,68,68,68,67,69,68,68,68,69,69,66,68,70,69,69,68,70,68,69,69,67,69,68,70,70,69,69,68,70,70,70,70,69,68,70,69,71,69,70,71,72,72,72,72,71,69,105,105,105,105,105,105,105,105,111,110,111,105,105,111,111,110,110,110,111,110,111,110,104,104,74,75,76,74,75,75,75,75,75,74,75,75,74,74,74,74,75,75,76,76,75,75,75,75,75,75,76,76,75,75,75,75,76,76,76,75,76,75,76,76,77,76,77,76,77,76,77,76,77,77,78,77,78,77,78,77,78,78,78,78,78,78,79,78,79,78,79,78,79,79,79,64,79,64,79,64,79,64,79,64,79,29,79,64,64,64,64,28,65,28,65,28,65,28,66,27,66,27,67,27,67,67,68,67,68,67,68,68,69,68,69,68,69,28,70,27,70,26,71,25,71,24,72,23,72,23,72,22,73,23,73,23,27,23,28,22,28,22,29,22,30,22,31,22,218,31,218,29,218,27,218,25,218,23,218,22,218,218,218,218,218,218,218,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,220,221,220,221,220,220,220,220,219,221,219,220,219,220,219,220,219,220,219,220,219,220,196,196,196,197,196,194,197,194,194,198,197,196,196,197,196,197,196,197,196,197,197,198,197,198,197,198,197,198,197,198,197,198 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,107,108,107,108,107,108,107,108,108,109,108,252,108,108,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,107,109,107,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,109,109,109,109,107,109,107,109,107,107,107,109,109,54,53,54,53,54,53,54,53,54,53,54,53,54,54,54,54,54,55,54,55,54,55,54,55,55,55,55,55,55,55,55,56,56,56,56,56,56,57,57,57,57,57,57,57,57,58,58,58,57,58,58,58,55,56,56,56,57,57,57,57,57,58,58,56,56,56,56,56,55,55,55,55,55,55,55,56,56,56,56,56,57,57,57,57,57,57,57,57,58,58,58,58,58,58,58,58,59,58,59,59,59,59,59,59,60,59,60,60,59,60,60,60,59,60,60,60,61,61,61,61,61,61,61,62,83,81,82,83,82,82,83,82,83,84,83,84,84,85,85,85,85,85,86,86,87,86,87,86,87,87,89,64,64,89,64,64,64,66,64,65,65,65,65,66,66,67,66,66,67,67,67,67,68,68,69,68,68,68,69,69,69,69,69,70,69,68,70,70,71,69,69,69,69,70,69,70,70,69,70,70,71,70,70,71,71,72,71,71,72,72,105,105,105,105,105,105,105,105,110,110,110,110,111,111,111,111,105,110,110,110,110,110,110,110,111,110,111,104,111,104,76,76,76,76,75,76,76,76,75,75,76,75,76,76,75,75,76,76,76,76,76,77,76,77,76,76,76,76,76,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,78,77,78,77,78,78,78,78,78,78,78,78,79,79,79,79,79,31,79,79,79,79,79,64,79,64,79,64,64,64,64,64,64,64,64,30,64,29,65,28,65,27,65,26,66,25,66,66,67,67,67,67,67,67,68,26,68,26,68,68,69,69,69,69,70,70,70,70,70,70,71,71,71,24,71,31,72,29,72,26,73,31,78,30,79,29,218,28,218,27,22,26,25,25,28,25,31,24,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,217,217,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,220,221,220,220,220,220,220,220,219,219,219,219,219,219,219,219,219,219,196,196,197,197,196,197,194,196,197,198,196,196,196,196,196,197,196,197,197,197,197,197,197,198,197,198,198,198,198,198,198,198,198 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,107,108,107,252,107,252,107,252,107,252,108,252,108,252,108,109,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,107,252,107,252,107,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,109,109,109,107,109,107,109,107,107,107,109,107,109,54,53,54,53,54,53,54,54,54,54,54,54,54,55,55,55,54,55,55,55,55,55,55,55,55,56,55,56,56,56,56,57,56,57,57,57,57,58,57,58,57,58,58,59,58,59,58,59,59,58,58,58,58,58,58,57,58,58,58,57,57,57,57,58,58,58,57,58,58,58,55,56,56,56,56,57,57,57,57,58,57,58,57,58,57,58,58,58,58,59,58,59,58,59,59,59,59,60,59,60,59,60,60,60,60,61,60,60,61,60,58,60,61,61,60,59,60,61,82,61,63,82,82,82,82,82,82,82,82,82,83,83,84,83,84,85,84,86,85,86,86,64,64,64,64,87,64,88,65,64,65,65,64,65,65,65,65,65,66,65,66,66,66,65,66,65,66,66,66,67,67,67,68,68,68,69,68,68,69,69,70,69,69,70,71,70,71,70,71,70,70,71,70,71,71,72,71,71,71,71,70,70,71,71,72,71,71,72,105,105,105,111,105,111,105,105,110,110,110,111,110,111,110,111,111,105,110,110,110,111,110,111,110,111,110,111,104,106,104,106,106,75,75,76,76,76,75,76,76,76,76,76,77,77,76,76,76,77,77,77,77,76,76,77,76,77,76,77,77,77,77,77,77,77,77,77,77,77,77,78,77,78,77,78,77,78,77,78,78,78,78,79,78,79,78,79,78,79,79,79,79,79,64,79,64,79,64,79,64,79,64,79,64,64,64,64,64,64,64,65,64,65,65,65,22,66,28,66,27,66,27,67,27,67,27,68,26,68,26,68,30,69,29,69,28,69,27,70,27,70,26,71,25,71,24,71,23,72,22,72,24,72,24,73,23,73,23,78,23,78,23,79,23,79,22,218,22,218,22,218,22,218,31,218,29,218,27,218,26,218,24,218,22,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,220,220,220,220,196,196,196,196,196,196,196,196,196,197,196,197,194,197,198,196,197,196,197,196,197,196,197,196,197,197,198,197,198,197,198,197,198,197,198,198,198,198,198 +,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,108,107,108,107,108,107,108,107,109,107,108,108,252,108,109,108,252,108,108,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,109,109,109,109,252,109,109,109,252,252,252,109,252,252,252,252,252,252,252,109,109,109,109,107,109,107,109,107,107,107,109,107,109,54,53,54,53,54,53,54,54,54,54,54,54,54,55,55,55,54,55,55,55,55,55,55,55,55,56,55,56,56,56,56,57,56,57,57,57,57,58,57,58,57,58,58,59,58,59,58,59,59,59,59,58,59,59,59,58,57,58,58,58,59,58,59,58,59,59,58,58,58,58,58,58,57,58,57,57,57,58,58,58,58,58,58,58,58,59,59,59,59,59,59,59,59,60,60,60,60,60,60,61,60,61,61,61,61,61,60,61,60,60,58,61,61,60,61,59,61,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,83,83,84,85,84,85,65,65,86,65,65,65,64,65,65,65,65,65,66,65,66,65,66,67,66,66,66,66,66,66,66,66,66,66,66,66,66,66,67,67,67,67,68,68,68,68,68,68,70,69,70,70,70,71,71,71,71,71,71,71,70,71,71,72,71,70,71,71,71,71,72,71,72,105,105,105,111,111,111,111,105,111,110,110,110,110,110,111,111,111,111,105,110,110,110,110,110,110,110,111,110,111,104,111,111,104,106,106,76,76,75,75,76,76,77,76,76,76,76,77,76,76,76,76,76,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,78,77,78,78,78,78,78,78,78,78,79,79,79,79,79,79,79,31,79,79,79,30,79,30,79,64,79,64,64,64,64,64,64,64,64,64,64,64,65,28,65,28,65,28,66,28,66,66,66,27,67,27,67,27,67,27,68,26,68,26,68,26,69,26,69,26,70,26,70,25,70,25,70,25,71,25,71,24,72,24,72,30,72,29,73,28,73,31,73,29,78,29,79,28,79,27,218,26,218,25,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,217,217,217,221,217,221,221,221,221,221,221,221,221,221,221,220,220,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,197,197,196,196,194,194,198,196,196,196,196,196,197,196,197,197,197,197,197,197,198,197,198,197,198,198,198,198,198,198,198,198 +,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,109,252,252,107,109,107,252,107,109,107,109,108,252,108,109,108,252,108,108,108,109,252,252,108,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,107,109,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,109,109,109,109,107,109,107,107,107,109,107,109,109,54,54,54,55,54,55,54,55,54,55,54,55,54,55,54,55,55,55,55,55,55,55,56,55,56,57,56,56,56,56,57,57,57,57,57,57,58,58,58,58,58,58,59,58,59,59,59,59,59,59,59,59,58,59,59,59,58,58,57,58,58,59,58,59,58,59,59,59,59,58,59,59,59,58,57,58,59,58,59,58,59,58,59,60,60,60,59,59,59,60,61,61,60,61,60,61,61,61,62,61,62,62,62,62,62,61,61,61,60,60,82,82,59,82,61,82,82,81,61,61,82,61,82,82,82,82,82,82,82,83,64,82,83,83,84,84,83,64,65,64,64,64,64,65,66,65,66,66,66,66,66,65,67,65,66,67,66,67,67,68,67,67,66,67,67,67,67,67,67,67,67,67,68,67,68,67,68,67,69,69,69,70,70,69,69,70,70,70,70,71,71,72,71,71,72,72,71,72,73,72,71,72,71,105,105,105,111,110,111,110,111,105,110,110,110,110,111,110,111,110,111,110,105,110,111,110,110,110,111,110,111,110,111,104,111,106,104,107,107,106,106,75,76,76,76,76,76,77,77,77,77,76,77,76,77,76,77,78,77,77,78,78,77,78,77,78,77,78,78,77,77,78,78,77,77,78,78,77,78,78,79,78,79,78,79,78,79,79,79,79,79,79,79,64,79,64,79,64,79,64,79,64,79,64,79,64,64,64,64,64,65,64,65,28,65,28,66,28,66,28,66,27,67,66,67,66,67,67,68,67,68,68,68,68,69,29,69,28,69,27,70,25,70,25,70,24,71,31,71,30,71,29,72,28,72,27,72,26,73,25,73,24,73,23,74,22,74,22,74,31,31,29,218,28,218,27,218,25,218,24,218,30,218,28,218,27,218,25,218,24,218,22,218,218,218,218,218,218,218,217,218,217,217,217,217,221,217,221,217,221,217,221,217,221,221,196,196,196,196,196,196,196,196,196,196,196,197,197,196,196,197,196,197,197,198,197,198,198,197,197,196,196,196,196,197,197,194,197,198,196,196,196,197,196,197,196,197,196,197,197,198,197,198,197,198,197,198,198,198,197,198,198,198,198,198 +,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,109,252,108,107,108,107,108,107,109,107,109,108,252,108,109,108,252,252,252,108,108,252,109,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,107,109,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,109,107,109,107,109,107,107,107,109,109,109,54,54,54,55,54,55,54,55,54,55,54,55,54,55,54,55,55,55,55,55,55,55,56,55,56,57,56,56,56,56,57,57,57,57,57,57,58,58,58,58,58,58,59,58,59,59,59,59,59,59,59,59,59,59,59,59,59,59,58,58,59,58,59,59,59,59,59,59,59,59,58,59,59,59,58,58,58,59,59,59,58,60,60,58,60,60,60,60,59,60,61,61,62,60,61,61,62,61,62,62,63,63,63,62,61,61,62,81,82,82,82,61,63,82,60,61,82,61,82,84,84,82,82,82,82,84,82,82,82,65,65,65,64,66,64,64,65,65,65,67,65,65,67,65,66,66,65,66,66,66,66,66,66,67,67,67,67,67,67,67,67,67,68,68,67,68,68,68,68,68,68,68,68,68,68,68,68,69,69,69,69,69,69,69,69,69,70,70,70,70,70,71,71,71,71,72,71,72,72,71,72,105,105,105,110,111,111,111,111,111,105,111,110,110,110,111,110,111,111,111,111,111,110,110,110,110,110,110,110,111,110,111,104,111,106,108,104,107,106,106,106,106,76,76,76,76,76,76,76,77,77,77,77,77,77,77,77,77,77,77,78,77,78,77,78,78,78,78,78,78,78,78,78,78,78,78,78,79,78,79,79,79,79,79,79,79,79,79,79,79,79,79,64,79,64,79,64,64,64,64,64,64,64,64,64,64,64,64,64,65,65,65,27,65,65,66,66,66,66,66,66,67,67,67,67,67,22,68,27,68,26,68,26,69,69,69,69,69,26,70,25,70,25,70,25,71,25,71,25,71,25,72,24,72,24,72,24,73,24,73,31,73,30,73,28,74,27,74,25,31,24,31,23,218,31,218,30,218,28,218,27,218,26,218,25,218,24,218,22,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,217,221,217,221,221,221,221,221,196,196,196,196,197,197,197,197,197,197,197,197,196,196,196,196,197,197,197,197,197,197,198,198,198,196,196,196,197,197,197,197,194,198,198,196,196,196,196,196,197,196,197,197,197,197,197,197,197,197,198,198,198,198,198,197,198,197,198,198,198,198 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,109,252,109,107,252,107,252,107,109,108,252,108,109,108,252,108,252,108,252,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,109,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,109,109,109,107,109,107,109,107,109,107,109,109,55,54,55,54,55,54,55,54,55,55,55,55,55,55,55,55,57,56,55,56,55,56,56,57,57,58,58,57,57,58,57,58,57,58,58,59,58,59,58,59,59,60,59,60,59,60,60,60,61,59,59,59,59,59,59,59,59,59,59,58,59,58,59,59,59,59,59,59,59,59,59,59,59,59,59,59,58,59,61,60,59,61,59,60,60,60,59,59,60,61,61,61,61,62,62,63,62,63,63,63,62,62,61,63,63,63,61,61,82,82,65,80,82,62,82,63,61,82,64,64,83,82,82,84,60,60,64,64,66,66,67,66,67,66,66,65,65,65,66,67,66,67,66,67,67,68,67,67,67,66,67,66,66,66,67,67,67,68,68,68,68,67,68,68,68,68,68,69,68,69,69,69,69,68,69,69,69,69,70,69,70,69,70,69,70,70,70,70,71,70,71,70,71,70,71,70,71,71,71,105,105,105,111,110,111,111,111,111,111,105,111,110,111,110,111,110,111,110,111,110,111,111,110,110,111,110,111,110,111,110,111,110,111,106,108,108,104,107,107,106,106,106,76,76,76,76,77,77,76,77,76,77,76,77,77,77,77,78,78,77,77,78,78,77,78,77,78,77,78,78,79,78,79,78,79,78,79,79,79,79,79,79,79,64,79,64,79,64,79,64,79,64,79,64,79,64,64,64,64,29,64,29,65,28,65,28,65,28,65,28,66,65,66,66,66,27,67,27,67,27,67,27,68,27,68,26,68,26,69,26,69,26,69,26,70,25,70,25,70,30,70,30,71,29,71,29,77,28,77,28,77,27,78,27,73,26,73,26,73,25,74,25,74,24,74,24,218,30,218,28,218,26,218,24,218,22,218,31,218,29,218,28,218,26,218,25,218,24,218,22,218,218,218,218,218,218,218,217,218,217,217,217,217,221,217,221,217,221,217,221,221,196,196,196,196,196,197,196,196,196,197,196,197,196,197,196,196,196,197,196,197,196,197,197,198,197,196,196,197,196,197,196,197,197,198,197,198,198,196,196,197,196,197,196,197,196,197,197,197,197,198,197,198,197,198,197,198,198,198,198,196,198,198,198,198 +,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,108,252,108,107,108,107,109,107,108,107,252,252,109,108,252,252,252,108,108,108,252,252,109,252,109,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,109,109,109,252,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,109,109,109,109,107,109,107,107,107,109,109,109,107,55,55,55,55,55,55,55,56,57,56,57,56,57,57,58,58,58,56,56,57,56,57,57,59,57,58,59,58,58,58,58,59,59,59,59,60,60,60,60,60,60,61,60,61,61,61,61,61,61,61,59,59,59,61,59,59,59,59,59,59,60,59,60,60,60,61,59,59,59,59,59,59,59,59,59,61,61,61,62,60,59,60,62,59,60,58,59,59,60,59,60,63,62,62,63,62,63,63,81,63,63,61,63,82,61,64,64,64,64,63,65,63,82,82,82,65,64,64,83,63,65,83,83,66,83,65,65,66,67,67,66,67,66,67,68,66,67,67,70,67,67,68,69,68,68,67,68,67,69,67,67,66,67,66,67,67,66,68,67,68,68,68,68,68,68,69,69,69,69,70,71,70,70,70,70,70,70,70,70,70,70,70,71,70,71,70,71,71,71,71,71,71,71,71,72,72,105,105,105,111,111,111,111,111,111,111,111,111,111,110,110,110,110,110,111,111,111,111,111,111,110,110,110,110,110,110,111,111,111,111,111,106,107,108,104,107,107,107,107,106,106,106,76,76,76,77,77,77,77,77,77,77,77,77,77,77,77,77,78,78,78,78,78,78,78,78,79,78,79,78,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,64,79,64,79,64,79,64,79,64,79,64,79,64,64,64,65,65,65,65,66,66,66,66,66,66,66,66,67,67,67,27,68,26,68,26,68,25,68,25,69,24,69,24,69,23,70,23,70,22,70,25,71,25,71,25,71,25,71,24,78,24,78,24,78,24,79,31,79,30,27,29,29,28,31,27,218,26,218,31,218,29,218,30,218,29,218,28,218,27,218,25,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,221,217,221,221,221,221,221,196,196,196,196,197,196,196,196,196,196,197,196,196,196,197,197,196,196,196,196,197,196,196,196,196,196,197,197,197,197,197,197,197,197,198,198,198,198,196,196,196,196,197,196,197,196,197,197,197,197,197,197,198,197,198,198,198,198,198,198,198,198,198,198,198,198 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,252,107,109,107,109,107,109,108,252,108,252,108,252,108,252,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,107,109,107,252,107,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,109,109,109,107,109,107,109,107,107,107,109,109,109,55,55,55,55,55,55,56,57,56,57,56,57,57,58,58,58,56,56,57,56,57,57,59,57,58,59,58,58,58,58,59,59,59,59,60,60,60,60,60,60,61,60,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,59,59,59,59,59,59,61,61,61,61,61,59,59,59,61,59,62,62,62,61,62,60,59,59,61,59,60,62,60,58,59,59,90,91,92,61,92,63,62,63,62,63,62,94,94,82,80,80,94,80,94,80,65,81,82,65,65,82,82,66,66,67,67,83,68,84,67,66,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,69,70,70,71,69,68,69,69,68,68,69,68,69,68,67,67,68,68,67,68,69,69,68,69,68,69,70,70,71,71,70,71,70,70,70,71,71,70,71,70,70,71,72,72,71,71,72,71,72,72,72,71,72,105,105,105,111,111,111,111,111,111,111,111,111,111,111,110,110,110,111,110,111,110,111,110,111,111,111,110,111,110,111,110,111,111,111,111,111,104,106,107,104,107,108,107,107,106,107,106,106,106,76,77,77,77,77,77,77,77,78,77,78,77,78,77,78,78,79,78,79,78,79,78,79,79,79,79,79,79,79,64,79,79,79,30,79,30,79,30,79,30,79,31,79,30,79,29,64,29,64,28,64,28,65,27,65,27,66,26,66,25,66,25,66,24,67,24,67,23,67,22,67,22,68,26,68,26,68,26,69,26,69,31,69,30,70,29,70,29,70,28,70,27,71,26,71,26,71,25,72,24,72,23,72,30,67,29,73,28,79,27,26,26,28,24,29,23,30,22,31,23,218,31,218,29,218,27,218,26,218,24,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,217,217,217,221,217,221,217,221,221,196,196,196,196,196,197,196,196,196,197,196,197,196,197,196,197,198,197,196,196,196,197,196,197,196,197,196,197,197,197,197,197,197,198,197,198,197,198,197,198,196,196,196,196,196,197,196,197,197,197,197,197,197,198,197,198,198,198,198,198,198,198,198,198,198,198,196,196 +,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,108,252,108,107,109,107,108,107,109,108,109,108,109,252,252,252,252,252,108,108,252,252,109,252,109,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,109,107,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,107,109,107,109,107,109,109,109,107,107,57,57,57,57,58,58,58,58,58,58,58,57,57,59,59,57,57,58,57,58,59,59,58,59,59,60,59,60,60,61,60,61,61,61,62,61,60,62,60,61,60,62,62,62,61,62,62,61,61,61,61,61,61,94,61,61,61,59,59,61,59,61,61,61,61,59,59,63,61,63,62,62,84,84,62,62,62,62,63,61,61,62,60,60,60,60,60,59,91,61,91,92,92,92,93,93,94,94,63,94,63,62,65,63,63,80,63,63,63,64,66,66,65,64,65,65,66,68,68,69,68,69,105,105,105,105,105,110,105,105,110,110,110,111,110,111,111,111,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,68,69,69,69,69,70,69,70,70,70,71,71,72,70,71,70,71,71,71,71,71,71,72,71,71,72,72,72,72,72,72,72,71,72,105,105,111,105,111,111,111,111,111,111,111,111,111,111,111,110,110,110,110,110,111,111,111,111,111,110,110,110,111,111,111,110,111,111,111,111,111,111,111,104,106,106,107,107,107,107,107,106,106,106,106,77,77,77,77,77,78,78,78,78,78,78,78,78,78,78,79,78,79,79,79,79,79,79,79,79,79,79,79,79,79,31,64,30,64,30,64,29,64,28,64,27,65,27,65,26,65,26,65,29,65,29,65,28,65,28,66,28,66,28,66,28,66,28,67,27,67,27,67,27,68,27,68,27,68,27,68,26,69,26,69,26,69,26,70,26,28,26,30,25,71,25,71,25,71,25,71,25,72,25,72,24,72,24,73,24,27,24,28,24,28,30,29,29,30,28,30,26,31,25,31,24,218,23,218,31,218,29,218,28,218,27,218,25,218,24,218,23,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,217,217,217,221,221,221,196,196,196,196,196,196,196,196,197,196,196,196,196,196,196,196,197,197,198,198,196,196,196,196,196,196,197,197,197,197,197,197,197,197,197,197,197,197,198,198,198,198,198,198,196,196,196,196,197,197,197,197,197,197,197,197,198,198,198,198,198,198,198,198,198,198,196,196,196,196,196,196 +,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,109,107,109,107,252,107,109,108,252,108,252,108,252,108,252,108,252,108,252,108,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,107,109,107,109,107,107,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,109,109,107,109,107,109,107,107,107,109,109,109,107,107,58,59,58,59,58,59,59,58,59,59,59,59,59,58,59,59,60,60,94,60,61,61,58,59,59,60,59,60,60,61,60,61,61,61,62,61,60,62,60,61,60,62,62,62,61,62,62,62,62,61,62,62,62,94,61,61,81,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,84,84,63,59,83,62,62,64,61,60,66,62,64,62,62,85,60,63,91,92,93,94,63,94,94,63,64,94,95,95,66,65,64,65,66,65,66,66,67,67,68,67,67,68,105,105,105,105,105,105,105,105,105,105,110,110,111,110,111,110,111,111,105,105,105,105,105,110,111,110,111,110,111,111,110,109,105,110,111,110,111,105,105,105,71,70,70,70,70,70,70,71,71,71,72,71,72,71,72,71,72,72,72,71,72,72,72,72,73,72,73,72,73,72,73,105,105,111,111,105,111,111,111,111,111,111,111,111,111,111,111,110,110,110,111,110,111,111,111,111,111,110,111,111,111,111,111,110,111,110,111,110,111,110,111,104,104,106,107,106,107,107,107,106,107,106,107,106,106,77,78,77,78,78,78,78,79,78,79,78,79,78,79,78,79,79,79,79,79,64,79,64,79,29,79,29,79,28,79,28,64,28,64,27,65,27,65,26,65,26,65,25,66,25,66,24,69,23,70,23,71,22,72,22,73,30,74,30,75,29,77,28,78,28,79,27,26,27,27,26,27,25,28,25,28,24,29,23,30,23,30,22,31,22,71,25,71,25,71,24,71,24,72,24,72,24,72,24,73,24,25,23,26,23,26,23,27,23,28,23,29,31,29,29,30,27,31,26,31,24,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,221,217,221,217,221,221,196,196,198,198,198,198,196,198,197,198,197,198,197,198,197,198,198,196,196,197,196,197,196,197,196,197,196,197,197,197,197,197,197,198,197,198,197,198,197,198,197,198,198,198,196,197,196,197,196,197,196,197,197,198,197,198,197,198,197,198,198,198,197,198,197,198,196,196,196,196,196,197,197,197 +,108,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,109,107,108,107,109,107,109,108,109,252,109,108,252,252,252,252,108,108,252,252,252,252,109,252,252,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,107,107,107,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,109,109,107,109,107,109,107,107,107,109,107,109,107,59,59,59,59,59,59,60,58,59,58,60,59,61,61,61,62,62,60,60,94,60,61,61,61,61,60,61,61,61,59,58,59,59,60,59,60,60,61,60,61,61,61,62,61,60,62,94,61,60,62,62,93,61,62,61,105,105,105,105,105,105,105,110,110,110,110,110,110,111,111,111,111,110,104,106,61,64,84,83,67,65,67,66,62,67,64,64,85,65,86,65,91,92,93,64,64,65,64,94,64,64,64,65,65,65,66,67,67,66,67,67,67,67,67,105,105,105,110,105,110,105,105,105,109,110,110,110,110,110,110,111,111,111,105,105,109,110,110,110,109,110,111,111,110,111,111,111,105,105,110,110,110,110,105,105,105,105,106,73,71,71,71,71,71,71,71,71,72,72,71,72,73,72,72,72,72,73,72,72,74,73,73,73,73,73,73,105,105,111,111,111,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,111,111,111,110,111,111,111,106,104,108,106,106,107,107,107,107,107,106,106,107,106,106,78,78,78,78,78,78,79,79,79,79,79,79,79,79,79,79,79,31,64,30,64,30,64,29,64,28,64,27,65,27,65,26,65,26,65,65,26,65,72,24,73,23,75,23,77,22,79,29,30,28,31,28,31,28,67,31,22,30,23,30,23,29,24,28,24,28,25,27,25,26,26,26,26,25,27,25,27,24,28,23,28,23,29,22,29,25,30,31,30,30,31,30,72,29,218,28,218,27,218,27,218,26,218,25,218,24,218,24,25,23,31,22,218,22,218,22,218,31,218,29,218,27,218,25,218,23,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,217,217,221,217,221,221,221,221,196,198,198,198,198,198,196,196,197,197,197,198,197,198,197,198,198,196,196,196,196,196,196,197,197,197,196,197,197,197,197,197,197,197,197,198,197,198,197,198,198,198,198,198,198,198,196,197,197,197,197,197,197,197,197,198,198,198,198,198,197,198,197,198,198,196,196,196,196,197,197,197,197,197,197 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,108,252,252,252,252,108,109,107,109,107,252,107,109,108,252,108,252,108,252,108,252,252,108,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,109,107,252,107,109,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,109,107,109,107,109,107,109,107,109,107,109,107,109,107,60,61,61,61,61,59,61,94,58,62,62,59,61,61,61,62,62,62,62,61,62,62,62,59,60,60,94,60,61,58,59,59,60,59,60,60,61,60,61,61,92,62,92,60,93,60,61,95,62,94,94,61,105,105,105,105,111,110,111,110,110,110,111,110,111,110,111,111,111,109,110,109,104,107,106,64,65,69,69,67,68,68,68,68,68,69,70,66,69,69,67,65,65,65,66,66,66,66,66,66,66,65,66,66,66,67,67,67,67,105,105,105,105,110,111,110,105,110,111,110,105,110,110,109,110,110,110,110,111,110,111,105,110,109,110,110,111,110,111,110,111,110,111,111,111,105,111,110,111,110,111,111,105,105,111,106,107,106,73,72,73,72,72,72,72,72,72,72,73,72,73,72,73,72,73,73,73,73,73,73,73,74,74,105,105,111,111,105,105,105,111,111,111,111,111,111,111,111,111,111,111,110,111,111,111,110,111,111,111,110,111,110,111,110,111,111,111,111,111,110,111,110,111,110,106,107,108,104,104,107,106,106,107,106,107,107,107,106,107,106,106,106,79,78,79,78,79,79,79,30,79,79,79,64,79,27,23,26,79,28,64,28,64,27,65,27,65,26,65,26,65,25,66,25,66,24,25,66,24,30,30,29,30,29,31,29,66,29,66,29,67,29,67,28,67,28,68,28,23,28,24,27,25,27,26,27,27,27,29,26,30,26,31,26,70,26,70,26,70,26,71,25,71,25,71,25,218,25,218,24,218,24,218,24,218,24,218,24,218,24,218,23,218,23,218,30,218,29,218,28,218,26,218,25,218,24,218,23,218,22,218,23,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,217,217,217,221,217,221,217,221,217,221,217,221,221,221,221,221,196,197,198,197,198,197,198,197,198,197,196,196,196,196,197,196,197,196,197,196,197,197,197,197,197,197,198,197,198,197,198,197,198,197,198,197,198,198,198,198,197,196,197,196,197,197,198,197,198,197,198,198,198,197,198,197,198,197,196,196,196,196,197,197,198,197,198,197,198 +,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,108,252,108,252,108,108,109,108,109,107,109,252,109,108,252,252,252,252,252,252,252,252,108,252,252,252,108,108,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,107,109,107,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,109,107,109,107,109,107,107,107,109,109,109,107,107,107,60,61,61,61,61,59,61,94,58,62,62,62,62,58,62,62,62,60,59,61,61,61,62,60,60,94,60,61,61,61,60,61,60,94,60,61,61,61,62,92,92,93,93,94,62,94,62,94,105,105,105,110,105,111,111,111,111,110,110,109,110,110,111,110,111,111,111,109,110,109,104,107,107,106,67,69,71,67,70,70,69,71,70,70,71,72,69,70,68,69,66,66,69,66,71,68,67,68,67,66,66,67,67,67,105,105,105,105,110,110,111,111,111,111,111,109,110,110,110,110,110,110,110,110,110,110,111,111,111,105,110,110,110,110,111,111,111,110,111,111,111,105,110,110,111,110,111,111,111,111,105,111,110,110,110,106,106,73,74,74,74,73,74,74,73,73,74,73,73,73,73,73,73,73,73,73,74,74,74,74,105,105,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,111,111,111,111,111,111,111,111,111,110,111,110,111,106,107,107,108,104,104,104,108,106,106,106,106,107,107,106,106,106,106,106,106,106,79,31,79,30,79,30,79,79,79,29,79,28,79,28,79,27,64,27,64,26,66,26,71,25,75,25,79,24,64,24,65,23,65,23,65,22,65,22,66,31,66,31,66,30,66,30,67,30,67,30,67,29,67,29,68,29,68,29,68,28,69,28,69,28,218,31,218,30,218,30,218,29,218,28,218,28,218,27,218,27,218,26,218,25,218,25,218,24,218,23,218,31,218,29,218,28,218,27,218,25,218,24,218,23,218,23,218,22,218,22,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,196,196,197,196,197,196,197,197,197,197,197,197,197,197,198,197,198,197,198,198,198,198,198,198,197,197,197,197,197,197,198,198,198,197,197,197,197,197,197,197,198,197,198,198,196,196,196,198,197,197,197,197,197,197,198,197 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,108,109,107,252,108,252,108,252,107,252,108,252,108,252,252,252,108,252,252,252,252,108,107,108,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,107,107,107,252,107,252,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,107,109,107,109,107,109,107,109,107,109,107,109,107,107,63,60,59,59,59,60,61,61,60,61,61,61,61,59,61,94,58,62,59,61,83,61,62,62,62,61,62,61,61,61,62,62,62,59,60,59,60,63,62,91,92,93,94,63,94,94,105,105,111,111,110,111,111,111,111,110,109,110,109,110,111,111,110,111,111,111,109,110,104,104,107,108,107,107,106,71,71,70,72,70,72,71,73,71,70,74,68,68,74,73,73,72,69,73,68,72,75,68,68,69,69,105,105,105,110,111,110,111,111,111,110,111,111,110,109,110,109,110,109,110,109,110,110,110,110,111,110,105,110,111,110,111,110,111,110,111,110,111,105,111,111,111,110,111,110,111,110,111,111,111,111,110,110,111,106,110,106,106,74,75,74,74,74,74,74,75,73,75,74,73,74,74,74,73,74,74,74,75,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,111,110,111,111,111,111,111,110,111,106,107,107,108,108,104,104,104,107,106,107,108,106,107,107,107,106,107,106,106,106,106,30,79,29,79,28,79,27,79,26,79,25,79,24,79,23,64,22,64,29,64,28,64,28,65,28,65,28,65,27,65,27,66,27,66,26,66,26,66,26,67,25,67,25,67,25,218,25,218,24,218,24,218,24,68,23,218,23,218,23,218,22,218,22,218,22,218,22,218,27,218,31,218,29,218,28,218,27,218,25,218,24,218,23,218,22,218,27,218,26,218,24,218,23,218,22,218,22,218,22,218,23,218,22,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,196,197,196,197,196,197,196,197,197,198,197,198,197,198,197,198,197,198,197,198,198,197,196,197,197,198,197,198,197,198,197,198,198,198,197,198,197,198,197,198,197,198,196,196,198,197,197,198,197,198,197,198,197,198 +,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,108,109,108,108,107,109,107,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,107,108,108,108,108,108,252,252,252,108,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,107,107,107,107,109,107,109,107,252,109,109,109,252,252,252,109,252,252,252,252,252,252,252,252,109,107,109,107,109,107,107,107,109,109,109,107,109,107,60,63,59,59,59,60,61,61,60,61,61,61,61,59,61,94,58,62,83,83,82,62,83,84,84,62,62,62,59,60,58,59,59,60,59,60,63,62,92,91,92,93,105,105,105,105,105,111,111,111,111,111,111,111,110,109,109,109,110,110,111,111,109,109,109,109,110,104,108,108,108,107,107,107,106,71,72,72,72,71,72,71,73,72,70,74,75,73,75,74,73,74,72,68,71,73,105,105,105,105,105,110,111,110,111,110,111,111,111,111,111,111,110,109,110,110,110,110,110,110,110,110,111,111,110,110,111,110,111,110,111,111,111,110,111,111,111,111,111,110,110,110,111,110,111,110,111,111,111,105,110,110,110,110,106,108,110,106,106,75,75,75,75,75,74,75,74,75,74,75,74,75,75,75,75,76,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,111,111,111,111,111,111,111,111,111,111,106,106,107,108,108,104,104,104,107,107,107,107,107,106,107,107,107,106,107,106,106,106,106,31,79,28,79,25,64,22,64,31,64,30,64,30,64,29,64,28,64,27,65,27,65,26,65,26,65,25,66,24,66,23,66,23,66,22,67,29,218,28,218,28,218,27,218,26,218,25,218,24,218,23,218,23,218,22,218,29,218,25,218,22,218,28,218,26,218,24,218,22,218,31,218,29,218,27,218,25,218,23,218,218,218,30,218,30,218,29,218,28,218,27,218,26,218,25,218,25,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,221,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,197,197,197,197,197,197,197,197,197,197,197,197,198,198,198,198,198,197,197,197,197,197,197,197,198,198,198,197,198,198,198,198,198,197,197,197,198,198,198,196,196,198,197,197,197,197,198,197,198,197,198,198 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,252,108,108,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,108,108,108,252,252,252,252,252,252,252,252,252,252,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,107,109,107,109,107,109,107,109,107,109,109,109,107,107,60,63,63,63,95,63,80,59,82,63,83,84,84,56,63,85,63,83,82,82,84,83,82,84,85,84,61,66,67,65,68,71,68,68,69,65,65,66,69,67,21,105,105,105,105,111,111,111,110,111,111,111,111,109,109,110,109,110,110,111,110,111,111,110,109,110,104,108,108,108,107,108,107,107,107,106,72,71,72,72,72,73,75,72,72,74,75,75,75,73,71,75,105,105,105,105,111,111,111,111,110,111,110,111,110,111,111,111,110,111,109,110,109,110,109,110,109,110,110,111,110,110,110,110,110,111,110,111,111,110,110,111,110,111,111,111,111,110,110,111,110,111,110,111,110,111,111,111,111,110,110,110,110,106,107,109,109,107,106,106,75,76,75,75,75,75,75,75,75,76,75,76,75,75,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,111,111,111,110,111,110,111,110,111,111,111,111,109,109,104,106,107,107,108,108,104,104,108,107,108,107,108,107,106,106,107,106,107,106,107,106,106,106,106,30,79,30,79,29,64,29,79,28,64,28,64,27,65,27,65,26,65,26,65,25,66,25,66,24,66,24,66,23,67,22,218,22,67,31,67,29,68,28,68,27,218,26,218,25,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,30,218,30,218,29,218,29,218,28,218,28,218,27,218,27,218,26,218,26,218,25,218,25,218,24,218,24,218,23,218,23,218,22,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,217,221,221,221,217,221,221,221,221,221,221,197,198,197,198,198,198,197,197,197,198,197,198,197,198,197,198,197,198,197,198,198,198,198,198,197,198,197,198,197,198,196,196,196,197,196,197,197,198,197,198,198,198,197,198 +,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,109,252,109,252,109,108,108,108,252,252,252,252,252,252,252,252,252,252,108,252,252,252,108,108,108,108,108,252,108,252,252,252,252,252,252,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,107,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,107,107,107,109,109,109,107,109,107,107,81,63,63,95,81,62,63,80,83,82,84,85,84,64,62,64,82,84,83,84,82,84,83,84,86,67,68,67,68,67,70,71,73,75,67,69,70,68,105,105,111,111,111,111,111,111,111,111,111,111,111,109,109,110,110,110,110,110,110,111,111,111,111,104,104,108,108,108,108,108,108,108,107,107,106,71,72,72,72,72,66,70,69,105,105,105,105,105,105,105,105,111,111,111,111,111,111,111,110,111,110,111,111,111,111,111,111,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,111,110,110,110,110,111,111,111,111,110,110,110,110,110,110,110,110,111,110,111,111,111,105,110,110,110,110,106,107,108,109,110,106,106,106,106,76,75,75,75,75,76,76,76,76,75,76,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,111,111,111,111,111,111,111,111,111,109,109,104,106,107,108,108,104,104,108,107,107,107,107,107,107,106,107,106,107,106,106,106,106,106,106,106,64,29,64,28,64,26,64,24,64,23,65,28,65,27,65,26,65,25,66,24,66,24,66,23,66,22,67,24,218,23,218,23,218,22,218,31,218,29,218,28,218,26,69,24,69,23,218,28,218,27,218,27,218,26,218,26,218,25,218,25,218,24,218,24,218,23,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,220,198,198,198,198,198,198,198,198,198,198,198,198,196,196,196,196,196,197,197,197,197,197,198,198,198,198,198,198 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,107,108,107,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,107,109,107,109,107,109,107,109,109,109,107,109,107,61,81,62,81,82,82,82,81,82,84,83,84,86,64,65,87,66,87,86,65,65,86,69,66,66,65,64,66,68,69,75,72,73,73,74,105,105,105,111,111,105,110,111,110,111,110,111,111,111,111,110,109,110,110,110,110,111,110,111,111,111,109,104,108,108,108,108,108,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,111,111,111,111,111,111,111,111,111,111,110,111,110,109,109,109,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,110,111,111,111,111,111,111,110,110,111,110,111,110,111,109,110,109,110,109,110,110,110,110,111,110,111,110,111,111,111,109,110,109,110,109,110,106,108,108,110,106,107,106,107,106,106,75,75,75,75,76,76,76,76,105,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,109,110,111,111,111,111,111,110,111,111,111,110,111,111,111,110,111,111,111,110,111,110,111,110,111,110,111,111,111,111,109,109,104,106,107,108,104,104,108,107,108,107,108,107,107,107,107,106,107,106,107,106,107,106,107,106,106,106,64,30,64,30,65,29,65,28,65,27,65,27,66,26,66,25,66,24,66,24,218,23,218,22,218,31,218,29,68,27,218,25,218,23,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,30,218,30,218,29,218,29,218,28,218,28,218,27,218,26,218,26,218,25,218,25,218,24,218,24,218,23,218,22,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,220,220,220,220,220,220,220,198,198,197,196,196,196,196,197,196,197,197,198,197,198,198,198,197,198,198,198 +,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,109,108,109,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,108,107,108,107,108,252,252,252,108,252,252,252,109,109,252,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,109,109,109,252,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,107,252,107,109,107,107,107,109,109,109,109,109,107,107,62,81,80,65,62,65,81,83,83,83,65,65,65,64,65,65,65,65,66,89,65,88,66,66,68,70,66,68,70,71,71,75,72,105,105,111,111,111,111,111,110,111,111,111,111,111,111,111,109,110,110,110,110,111,111,111,111,111,110,111,111,104,104,105,105,105,105,105,110,111,111,111,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,110,109,110,109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,111,109,109,110,111,109,110,110,110,109,109,109,109,109,110,110,110,110,110,110,111,110,111,111,111,109,110,110,110,110,110,110,106,107,106,110,107,107,107,106,106,106,75,75,75,75,75,76,105,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,109,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,111,111,111,111,111,111,111,111,111,111,109,109,109,104,106,108,104,108,108,108,108,108,108,107,108,107,107,107,106,106,106,106,107,107,107,106,106,106,106,31,65,30,65,29,65,29,65,28,66,27,66,26,66,26,66,25,67,24,67,23,218,23,218,22,68,31,218,30,68,29,68,29,69,28,69,27,218,27,218,26,218,26,218,25,218,25,218,24,218,23,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,218,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,196,196,196,197,198,196,197,196,197,197,198,198,198,198,198,198,197,198 +,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,109,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,107,108,107,252,252,252,252,252,252,252,252,252,109,109,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,107,107,109,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,107,252,107,109,107,107,107,109,107,109,107,109,107,95,81,81,66,81,67,82,82,65,65,65,68,65,66,66,66,67,66,66,66,66,66,66,66,67,67,67,67,68,70,105,105,105,111,111,111,105,110,111,110,111,110,111,110,111,111,111,111,110,110,111,110,111,109,110,110,111,110,111,111,110,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,111,111,111,111,111,111,111,111,111,111,110,110,110,109,110,109,109,109,111,111,110,109,110,109,110,110,110,109,110,110,111,110,111,110,111,110,111,111,111,111,111,110,111,109,109,109,111,111,110,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,111,111,110,109,110,110,110,109,110,110,111,110,106,110,108,107,107,107,107,106,107,106,74,76,76,105,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,109,110,110,111,111,111,110,111,111,111,110,111,111,111,110,111,111,111,111,111,110,111,110,111,111,111,110,111,111,109,109,109,109,104,106,104,108,108,108,108,108,108,107,106,107,108,107,107,106,106,106,107,106,107,107,107,106,107,106,106,31,66,29,66,27,66,25,66,23,67,22,67,30,67,28,218,27,68,25,68,23,68,22,68,29,68,26,218,23,218,28,218,27,218,26,218,30,218,29,218,29,218,28,218,27,218,26,218,25,218,24,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,217,217,218,217,217,217,217,221,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,220,220,220,220,220,220,220,220,220,220,220,220,220,196,196,196,197,197,198,196,197,197,197,197,198,197,198,197,198,197,198,198,198 +,108,252,108,252,252,252,108,252,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,108,107,108,108,108,252,108,252,252,252,252,252,109,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,107,109,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,107,252,107,109,107,107,107,109,107,109,109,109,107,109,107,80,68,66,81,66,65,64,66,66,66,69,67,67,67,67,70,69,68,68,68,68,67,69,67,68,69,68,105,105,105,111,105,105,105,111,110,111,111,111,111,111,111,111,110,110,110,111,110,111,111,110,110,110,109,110,110,111,111,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,111,111,110,110,110,109,109,109,109,109,110,110,110,110,111,111,110,109,109,111,110,110,110,110,110,110,111,110,111,111,111,111,111,110,111,109,109,109,110,109,109,110,111,110,110,110,110,110,109,109,109,109,110,110,111,111,111,109,110,109,110,110,110,110,109,110,110,110,110,110,111,106,110,107,107,107,107,107,107,106,106,106,105,105,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,109,109,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,111,110,111,111,111,111,111,111,111,111,111,111,109,109,109,104,104,106,104,108,108,108,107,108,108,108,106,107,107,108,107,107,106,106,107,107,106,107,107,106,106,106,106,106,106,28,66,28,66,27,66,26,67,25,67,25,67,24,67,24,67,23,218,22,218,28,218,28,218,27,218,26,218,25,218,25,218,31,218,29,218,28,218,26,218,25,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,196,196,196,197,198,198,198,196,197,197,197,197,197,197,198,198,198,197,198,198,198,197 +,252,108,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,108,252,109,108,109,108,109,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,107,108,108,108,252,252,252,252,109,252,252,252,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,107,109,109,107,109,107,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,107,252,107,109,107,109,107,109,107,109,107,109,107,107,66,67,66,68,64,67,66,66,67,69,69,67,69,69,69,69,69,70,69,69,68,69,68,69,70,105,105,105,105,105,105,111,110,110,110,110,111,111,111,111,110,111,111,111,110,111,110,111,111,110,109,110,109,110,109,111,109,110,110,110,110,110,110,111,110,111,110,111,110,109,111,111,110,111,110,111,111,111,111,111,110,110,110,110,109,109,109,109,109,110,109,110,110,109,109,111,111,110,109,110,110,110,110,111,110,111,110,111,110,111,111,111,111,110,109,110,109,110,109,110,109,110,109,110,109,110,110,111,110,109,109,110,111,109,109,110,109,110,109,110,109,109,109,111,111,111,110,111,110,111,110,111,110,111,107,108,107,107,106,105,105,105,111,111,111,105,105,111,111,111,110,111,111,111,111,111,111,111,110,111,109,110,109,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,111,110,111,110,109,110,111,110,111,111,111,111,109,109,109,104,106,107,104,104,108,108,108,108,108,107,106,106,107,107,108,107,108,106,107,106,107,107,107,107,107,106,107,106,106,106,106,27,67,26,67,106,67,23,67,22,68,67,68,67,68,30,68,29,69,29,218,28,218,27,218,26,218,25,218,25,218,24,218,30,218,28,218,27,218,25,218,24,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,196,196,197,197,198,197,198,198,197,196,197,196,197,197,196,197,198,198,198,198,198,198,198 +,108,252,108,252,252,252,252,252,108,109,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,108,109,108,108,109,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,252,252,252,108,252,252,252,109,109,108,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,109,109,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,107,252,107,252,107,107,107,109,109,109,109,109,107,109,107,68,70,68,69,69,67,69,68,70,70,69,69,68,70,70,70,70,69,68,70,69,71,105,105,105,105,105,105,111,111,110,110,111,111,110,110,111,111,111,110,110,110,110,110,111,111,111,111,111,111,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,109,109,110,110,111,111,110,111,111,111,111,111,111,111,110,110,110,110,109,109,109,109,109,110,110,109,109,111,111,111,111,111,111,110,110,110,110,110,110,111,110,111,110,111,111,111,111,110,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,111,111,111,109,109,109,109,109,110,110,110,109,110,110,111,111,110,110,110,110,111,111,111,111,111,109,109,109,105,105,105,111,111,111,111,111,105,105,111,111,111,111,111,111,111,111,111,111,111,111,109,109,110,110,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,111,111,111,109,109,110,110,111,111,111,111,111,109,109,109,109,104,106,108,104,108,108,108,108,108,108,108,108,106,106,107,108,108,107,106,106,106,106,107,106,107,106,107,106,106,106,106,106,67,29,67,28,67,27,68,26,68,25,218,24,218,23,218,22,218,29,218,28,218,27,218,27,218,26,218,25,218,24,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,220,220,220,221,220,220,220,221,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,196,197,197,197,197,198,198,198,196,196,196,197,196,196,196,197,198,198,198,198,198,198,197 +,252,252,252,252,252,252,252,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,252,108,252,252,252,109,252,252,252,109,109,109,108,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,107,107,109,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,107,252,107,109,107,109,107,109,107,109,107,109,107,107,107,68,70,70,71,69,69,69,69,70,69,70,70,69,70,70,71,70,70,71,105,105,111,111,105,111,111,111,111,111,110,110,110,111,110,111,111,111,111,110,110,111,110,111,110,111,110,111,111,111,111,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,111,111,110,110,111,110,111,110,111,110,111,109,110,109,109,109,110,109,110,109,109,110,110,110,111,110,111,111,110,109,110,110,111,110,111,110,111,110,111,111,111,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,111,111,109,109,110,109,110,109,109,109,110,110,111,111,110,109,110,109,110,110,111,110,111,110,111,110,105,105,105,105,105,105,105,105,105,105,111,111,111,110,111,110,111,111,111,110,111,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,109,109,110,109,110,110,111,110,111,109,110,109,110,110,111,104,104,106,104,108,108,108,108,108,108,107,108,106,107,107,108,108,108,106,107,106,107,107,107,107,107,106,107,106,106,106,106,106,68,30,68,29,68,28,68,26,68,25,218,23,69,22,69,68,69,69,70,69,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,196,197,196,197,197,198,197,198,197,198,197,198,196,197,196,197,196,198,197,198,198,198,197,198 +,108,252,108,252,108,252,252,252,108,109,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,252,108,252,252,252,252,252,252,109,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,107,107,109,109,107,107,109,109,109,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,107,252,107,107,107,109,107,109,107,109,107,109,107,109,70,71,70,71,70,70,71,70,71,71,72,71,71,71,71,70,105,105,105,105,105,105,111,111,111,111,111,110,110,110,110,110,110,111,111,111,111,111,111,110,110,111,111,111,111,111,111,109,109,109,109,110,109,110,109,109,109,110,109,110,110,110,110,110,110,111,111,111,111,111,110,110,109,109,109,109,109,110,109,110,109,110,109,109,109,110,110,110,110,111,111,111,110,111,110,109,109,109,109,110,110,110,110,110,110,111,111,111,109,110,109,109,109,109,109,110,110,110,109,110,110,110,110,110,109,109,109,109,109,109,109,109,109,110,109,110,109,110,110,111,111,110,110,110,110,110,110,110,110,111,110,111,105,105,105,105,111,111,111,111,111,111,111,105,111,111,111,111,111,111,111,111,111,111,109,109,109,110,110,111,111,111,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,109,109,110,109,110,110,110,110,111,111,110,110,110,110,110,104,106,104,106,108,108,108,108,108,108,108,108,107,108,106,107,108,108,107,107,106,107,106,107,106,108,107,107,106,106,106,106,106,106,106,68,29,68,28,68,27,69,26,69,25,218,24,218,23,218,22,218,27,218,27,70,26,218,25,218,24,218,23,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,197,198,198,198,197,198,197,198,196,196,196,197,197,197,197,198,197,198,198,198,197 +,252,108,252,252,252,252,252,252,252,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,109,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,252,252,252,252,252,252,252,252,109,109,108,109,252,109,252,109,252,109,252,252,252,252,252,252,252,107,109,107,109,107,252,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,107,252,107,109,107,109,107,109,107,109,107,109,107,107,107,109,71,71,71,71,71,71,71,70,71,71,72,71,70,105,105,111,105,105,111,111,111,111,111,111,111,111,110,111,110,111,110,111,110,111,111,111,111,111,110,111,110,111,111,111,111,111,109,109,109,110,109,109,109,110,109,110,109,110,110,110,110,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,109,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,109,110,109,110,109,110,109,110,109,109,109,110,109,110,109,110,109,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,111,111,110,110,110,110,110,110,111,110,111,110,105,105,105,111,111,111,111,111,111,111,111,111,105,111,111,111,111,110,111,110,111,111,110,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,109,109,110,109,110,110,111,110,111,111,110,109,110,110,111,104,106,104,108,108,108,108,108,108,108,108,108,108,108,108,108,106,108,107,108,107,108,106,107,106,108,108,107,106,107,106,107,106,106,106,106,27,69,26,69,24,218,23,218,218,70,69,70,30,218,30,218,29,218,29,218,28,218,27,218,27,218,26,218,25,218,25,218,24,218,24,218,23,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,198,197,198,197,196,196,197,196,197,196,197,197,198,197,198,198,197 +,108,252,108,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,252,252,252,108,252,252,252,252,252,108,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,107,107,109,109,109,107,109,107,252,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,107,252,107,107,107,109,107,109,107,109,107,109,107,109,109,70,70,70,70,71,71,72,71,71,72,72,105,105,105,105,105,111,111,111,111,111,111,110,110,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,110,110,109,109,109,109,109,109,110,110,110,109,109,109,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,109,110,110,110,110,111,111,111,110,111,110,111,110,111,111,111,110,111,111,111,109,109,109,109,109,110,110,110,110,110,110,110,110,111,109,109,109,110,110,110,109,109,109,110,110,110,110,111,111,110,110,110,109,110,110,110,110,109,110,111,110,110,110,110,110,110,110,110,110,111,105,105,111,105,111,111,111,111,111,111,111,111,105,111,105,111,111,110,110,111,111,111,111,110,109,109,109,110,110,111,111,111,110,110,110,111,111,111,110,111,111,111,111,111,111,111,109,111,109,109,109,110,110,110,110,111,111,110,110,110,110,110,110,111,104,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,107,108,107,107,106,106,107,108,107,107,107,106,106,106,106,106,106,106,69,69,30,218,28,218,26,218,29,218,28,218,26,218,25,218,24,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,218,218,217,218,217,217,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,221,221,220,221,220,220,220,221,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,196,196,197,197,197,197,198,197,198,198,198,198 +,252,108,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,252,108,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,108,108,252,108,252,252,252,252,252,252,252,252,108,252,108,109,109,109,252,109,252,109,252,109,252,252,252,252,252,107,109,107,109,109,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,107,252,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,70,70,70,70,70,71,71,105,105,105,105,111,111,111,111,111,111,111,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,111,111,111,110,111,111,110,110,109,109,109,109,110,109,110,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,111,111,111,110,111,110,111,110,111,110,111,111,111,109,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,109,109,111,111,110,110,110,110,111,110,111,111,110,109,110,109,110,109,110,109,110,110,110,109,110,110,111,110,110,110,111,110,105,105,111,111,105,111,111,111,111,111,111,111,111,111,111,105,111,110,111,110,111,111,111,111,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,111,111,109,109,110,109,110,110,111,111,110,109,110,110,111,110,111,104,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,107,108,107,108,107,108,106,106,107,108,106,107,106,107,106,107,106,106,106,106,69,218,69,70,69,70,70,70,23,70,31,71,30,218,29,218,28,218,27,218,26,218,26,218,25,218,24,218,23,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,218,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,217,221,221,220,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,198,197,198,197,198,197,198 +,108,252,108,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,109,108,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,108,108,108,252,108,252,252,252,252,252,252,252,108,109,109,109,109,109,252,109,252,252,252,252,252,252,252,252,107,107,109,109,109,107,109,109,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,107,252,107,107,107,109,107,109,107,109,107,109,107,109,109,107,107,70,71,70,71,105,105,111,111,111,111,111,111,111,111,111,111,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,110,109,109,109,109,110,109,110,110,110,109,109,109,109,109,109,109,109,109,110,109,109,110,110,111,110,110,110,109,109,109,110,110,110,110,111,111,111,110,111,110,111,110,111,111,111,111,111,111,111,111,109,109,109,109,110,109,110,110,110,110,110,110,110,110,111,110,111,111,111,111,110,110,110,110,111,110,111,111,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,105,105,105,105,105,105,111,111,111,111,111,111,111,111,111,105,111,105,111,110,110,111,111,111,110,110,110,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,111,111,111,109,109,109,109,109,110,109,110,110,110,110,110,110,110,110,110,109,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,107,108,108,108,108,107,108,107,107,106,106,108,107,107,107,106,106,106,106,106,106,106,218,28,70,27,70,26,70,25,71,25,71,24,218,24,218,23,218,23,218,22,218,30,218,28,218,26,218,24,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220 +,252,108,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,108,108,109,108,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,108,108,108,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,109,252,252,252,252,252,252,252,107,109,107,109,107,109,107,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,107,252,107,252,107,109,107,109,107,109,107,109,107,107,107,109,109,107,107,105,105,105,105,111,111,111,111,111,111,111,111,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,110,110,110,110,110,110,109,109,110,109,110,109,110,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,109,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,109,110,109,110,110,111,111,110,109,110,109,110,109,110,109,110,110,111,111,111,111,111,110,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,110,110,105,105,105,111,111,111,105,111,111,111,111,111,111,111,111,111,105,111,105,111,110,110,109,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,109,109,109,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,109,108,108,108,108,108,108,108,108,108,108,105,105,105,105,111,105,104,104,104,104,104,104,104,108,107,108,106,108,106,107,106,107,106,107,106,107,106,106,106,70,29,218,29,218,28,218,27,218,26,218,26,218,25,218,24,218,23,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221 +,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,108,108,108,108,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,108,108,252,108,252,108,252,252,252,252,252,252,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,107,107,107,107,109,109,109,109,109,109,109,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,107,252,107,109,107,109,107,109,107,109,107,109,107,109,109,109,107,107,111,111,111,111,111,111,111,111,111,111,111,110,110,110,110,110,110,110,110,111,110,110,110,111,111,111,111,111,111,111,111,111,111,111,110,109,110,111,109,109,109,110,109,109,109,109,109,110,109,110,109,110,110,110,110,109,109,109,109,110,109,110,110,110,110,110,110,110,110,111,110,111,111,111,111,110,110,110,110,111,110,111,110,111,111,111,110,109,109,109,109,110,110,110,110,110,110,111,110,111,111,111,110,110,111,111,111,111,111,110,109,109,109,109,109,109,109,109,109,110,109,110,109,110,110,110,109,110,110,110,110,110,110,110,110,110,105,105,105,105,111,111,105,105,111,111,111,111,111,111,111,111,111,111,111,105,111,111,111,109,109,110,110,111,110,110,110,110,110,110,110,111,110,110,110,111,110,111,110,111,111,111,110,111,111,111,111,109,111,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,105,109,105,105,105,105,105,105,105,105,105,105,109,109,109,109,109,109,104,104,104,104,104,104,104,104,108,107,107,106,108,107,107,106,107,106,106,106,106,106,106,106,218,24,218,23,218,23,218,22,218,25,218,24,218,23,218,31,218,30,218,29,218,28,218,27,218,27,218,26,218,25,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,217,218,218,218,217,218,217,218,217,218,217,217,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220,221,220,220,220 +,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,108,252,108,109,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,108,108,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,109,252,252,252,252,252,107,109,107,109,109,252,107,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,107,252,107,252,107,109,107,109,107,109,107,109,107,107,107,109,109,107,107,107,111,111,111,111,111,111,111,111,111,111,111,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,111,111,110,109,110,110,109,109,110,110,111,110,109,109,110,109,110,109,110,109,110,110,111,110,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,111,110,110,111,110,111,110,111,110,111,110,111,110,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,111,110,109,109,109,109,109,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,110,110,110,105,105,105,111,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,105,111,110,111,110,109,109,110,110,111,110,111,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,111,109,110,111,109,109,110,109,110,109,110,109,110,110,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,111,110,109,110,110,111,110,111,111,111,109,104,106,107,108,104,104,108,107,107,106,107,106,107,106,107,106,107,106,107,106,106,24,218,23,218,23,218,22,218,25,218,31,218,29,218,27,218,26,218,24,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,218,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221 +,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,108,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,108,108,108,108,108,109,109,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,108,108,252,108,252,252,252,252,252,252,109,108,109,109,109,252,252,252,252,252,252,252,252,252,252,107,107,107,107,109,109,109,109,109,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,107,252,107,109,107,109,107,109,109,109,107,109,107,109,109,107,107,107,107,111,111,111,111,111,111,111,110,111,111,110,109,110,110,110,110,111,111,111,111,111,111,111,111,111,111,109,109,110,109,110,110,110,110,111,109,109,109,110,110,109,109,109,109,110,109,110,110,110,110,110,110,111,109,109,109,110,109,110,109,110,110,110,110,110,110,111,110,111,111,111,111,110,110,110,110,110,110,111,110,111,111,111,109,109,109,110,109,110,110,110,110,110,110,111,111,111,111,111,111,111,110,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,110,109,110,109,110,109,110,110,110,110,110,110,105,105,105,111,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,109,110,110,110,110,111,110,110,110,110,109,110,111,111,110,110,110,111,110,111,110,111,111,109,111,111,111,111,111,111,109,110,110,111,109,109,109,111,109,110,109,110,110,110,110,110,110,110,110,110,110,111,110,111,111,111,111,111,111,111,109,110,109,110,109,110,110,110,110,110,110,104,106,107,108,104,104,107,107,107,107,107,107,107,106,107,106,106,106,106,106,106,71,72,71,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220 +,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,108,108,109,108,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,108,109,108,109,252,109,252,109,252,252,252,252,252,252,252,107,107,107,109,107,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,107,252,107,109,107,107,107,109,107,109,107,107,107,109,107,107,107,107,107,111,111,111,111,111,110,111,110,111,110,111,111,110,110,110,110,111,110,111,111,111,110,111,111,109,109,110,110,111,111,110,109,110,110,109,109,110,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,110,111,110,111,110,111,110,111,110,111,110,109,109,110,109,110,110,111,110,111,110,111,111,110,110,111,110,111,111,109,109,109,109,110,109,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,105,105,105,111,111,105,110,111,111,111,105,111,111,105,105,111,105,111,111,111,109,111,111,111,105,111,110,109,109,110,110,111,111,111,110,111,109,110,109,111,110,111,110,111,110,111,110,111,110,109,110,111,110,111,110,111,111,109,109,110,109,111,110,111,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,111,111,109,110,109,110,109,110,109,110,110,110,110,111,110,104,106,107,107,104,104,104,107,107,107,107,106,107,106,107,106,107,106,106,106,106,29,218,28,218,26,218,25,218,24,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,217,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221 +,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,108,109,109,108,108,109,108,109,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,108,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,107,107,107,107,109,109,109,107,109,109,109,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,107,252,107,109,107,109,107,107,109,109,107,109,107,107,109,107,107,107,107,107,107,111,110,110,110,111,110,110,110,111,111,111,111,111,111,111,110,111,111,111,111,109,109,109,109,110,110,110,110,111,111,110,110,109,109,109,109,109,109,109,109,109,109,110,109,110,110,110,110,111,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,111,111,111,111,111,110,110,110,111,110,110,110,111,111,111,110,109,109,109,109,110,110,110,110,111,109,110,110,110,110,111,111,109,109,109,109,109,109,109,109,109,109,109,110,109,109,109,109,109,109,109,109,110,109,110,109,110,110,110,105,105,105,105,111,111,105,105,111,111,105,111,105,110,111,111,111,111,111,111,111,111,109,111,111,111,111,111,111,109,109,110,110,111,111,111,110,109,109,109,109,110,110,110,110,111,111,111,110,111,111,109,109,110,110,109,109,110,110,110,110,110,110,111,111,111,109,109,109,110,110,110,109,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,109,110,111,110,109,110,110,110,110,110,110,110,110,111,104,106,107,108,108,104,104,107,107,107,107,107,107,107,106,106,106,106,106,106,106,218,29,218,28,72,27,218,26,218,25,218,31,218,29,218,28,218,26,218,25,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,218,218,217,218,217,218,217,218,217,217,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,221,221,220,221,220,221,220,221,220,221,220 +,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,108,108,252,108,252,108,109,109,108,108,252,108,252,108,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,109,109,109,252,109,252,109,108,109,252,252,252,252,252,107,252,107,109,107,252,107,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,107,252,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,107,107,107,110,111,110,110,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,109,109,109,110,109,109,109,110,109,110,110,110,110,111,109,110,109,110,110,111,111,110,110,110,110,111,110,111,110,111,111,111,111,111,110,111,110,111,110,111,110,111,110,111,109,109,109,110,109,110,110,111,110,109,111,110,110,111,110,111,109,109,109,110,109,109,109,110,109,109,109,110,109,110,109,110,109,109,109,110,109,110,109,110,109,110,109,105,105,105,105,111,110,105,105,111,111,111,111,111,110,110,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,109,109,110,110,111,110,109,109,110,109,110,110,110,110,111,110,111,110,111,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,109,110,109,110,109,110,109,110,109,109,109,110,109,110,109,110,110,111,110,111,111,111,109,110,110,111,109,110,109,110,109,109,110,111,110,110,110,104,106,107,107,104,104,104,104,106,107,107,107,107,106,107,106,107,106,106,106,106,106,218,26,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221 +,109,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,252,109,109,108,108,108,109,108,109,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,109,109,252,252,252,252,252,252,252,252,252,252,252,107,107,107,109,109,109,109,109,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,107,252,107,109,107,109,107,109,107,109,107,109,107,107,109,109,109,109,107,107,107,111,109,109,110,110,110,110,110,110,110,111,110,111,111,111,111,111,111,111,109,109,109,110,110,110,110,110,110,111,111,111,111,111,109,109,109,109,109,110,109,109,109,110,110,110,110,109,109,110,110,110,110,110,110,111,111,110,110,110,110,111,110,111,111,111,111,111,110,110,110,110,110,111,110,111,110,111,109,109,109,110,110,110,110,111,111,109,111,110,110,111,111,109,109,109,109,109,109,109,109,109,109,110,109,109,109,109,109,109,109,109,109,109,109,109,109,110,109,105,105,105,105,105,111,105,105,105,111,111,111,111,111,111,110,110,110,110,110,110,110,111,110,111,111,111,111,111,111,111,105,111,111,111,109,110,110,111,110,109,109,109,109,110,110,110,110,110,110,110,110,111,111,111,111,110,110,110,110,110,110,110,110,111,111,111,111,111,109,109,109,109,109,110,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,109,110,110,111,110,110,110,104,106,107,108,104,104,104,106,108,106,107,107,107,107,107,107,106,107,106,106,106,106,106,218,25,218,24,218,31,218,30,218,28,218,27,218,26,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,217,221,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221 +,252,108,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,108,252,108,109,109,108,108,252,108,252,108,252,108,108,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,252,252,252,252,252,252,252,107,107,109,107,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,107,252,107,109,107,107,107,109,107,109,107,107,107,109,107,109,109,107,107,107,107,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,109,111,110,109,110,109,110,109,110,109,110,110,111,110,111,110,109,110,109,109,110,109,110,110,110,110,111,110,111,110,111,110,111,110,111,111,111,111,111,110,111,110,111,110,111,110,111,110,111,109,110,109,110,109,110,110,111,110,109,110,111,110,111,111,109,109,109,109,109,109,110,109,110,109,110,109,110,109,109,109,110,109,110,109,110,109,110,109,110,105,105,105,105,105,105,105,105,111,111,110,111,110,111,111,111,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,111,109,111,110,111,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,111,111,110,111,110,111,110,111,110,111,111,111,109,109,109,110,109,109,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,111,109,109,110,110,111,111,111,104,106,106,108,108,104,104,104,106,106,106,108,107,107,107,107,106,106,106,106,106,106,106,106,218,218,218,218,218,218,30,218,29,218,27,218,26,218,25,218,24,218,28,218,24,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221 +,252,252,109,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,109,109,109,108,108,108,108,108,252,108,108,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,109,109,252,252,252,252,252,252,252,252,252,107,107,107,109,109,109,109,109,109,109,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,107,252,107,109,107,109,109,109,107,109,107,109,107,107,107,109,109,109,107,107,107,107,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,110,111,109,110,110,111,111,109,109,110,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,109,109,109,109,110,110,110,110,110,110,111,110,111,111,111,110,111,111,111,109,111,111,111,111,111,111,110,109,109,109,109,109,110,110,110,110,110,110,109,109,109,110,111,111,110,109,109,109,109,109,109,109,109,109,109,109,110,109,109,109,110,110,110,109,109,109,109,109,109,109,105,105,105,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,110,110,110,110,111,111,111,110,111,111,111,111,111,111,111,111,111,110,110,110,110,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,111,111,111,111,110,110,110,110,111,111,111,111,111,111,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,109,109,110,110,110,111,111,111,110,104,106,107,108,104,104,104,107,107,106,106,106,107,107,107,107,107,107,106,106,107,106,106,106,106,27,218,27,218,26,218,25,218,25,218,24,218,23,218,22,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220 +,252,252,252,109,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,109,109,109,108,108,252,108,252,108,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,107,109,107,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,107,109,107,107,107,109,109,109,107,109,107,107,109,109,107,109,109,109,107,107,107,110,109,110,110,111,110,110,110,111,110,111,110,111,110,111,110,111,110,109,109,111,111,111,111,110,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,109,109,110,109,110,109,110,110,110,110,111,110,111,111,111,111,111,110,111,109,111,110,111,110,111,109,110,109,110,109,110,109,110,110,111,110,111,110,109,109,109,110,111,111,110,109,109,109,109,109,110,109,110,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,109,105,105,105,105,105,111,111,111,111,111,111,111,111,111,110,111,111,111,111,111,111,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,110,111,110,110,110,109,109,110,109,110,109,110,110,110,110,111,110,111,110,111,111,111,111,111,110,111,110,111,111,111,111,111,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,109,110,109,110,110,111,110,111,111,111,110,111,110,106,108,104,107,107,106,107,106,107,106,106,107,107,106,107,106,106,106,106,106,106,106,218,31,218,29,218,28,218,27,218,25,218,24,218,23,218,22,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,218,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221 +,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,108,109,108,109,108,109,108,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,107,109,109,109,107,109,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,107,109,107,109,107,107,109,109,107,109,107,107,107,109,107,109,109,109,109,107,107,107,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,109,110,111,111,111,111,111,110,109,110,110,110,110,110,110,110,110,110,110,111,110,111,111,111,111,111,109,111,111,110,110,110,110,110,110,111,111,111,111,111,110,111,111,111,111,111,111,110,110,110,109,109,109,109,109,110,109,110,110,110,110,110,109,109,109,109,110,111,111,111,109,109,109,109,109,109,109,110,109,110,109,109,109,109,109,110,109,110,109,110,110,109,109,105,105,105,105,105,111,111,111,111,111,111,105,111,111,111,110,111,111,111,111,111,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,110,110,110,110,110,110,109,109,109,109,109,110,110,110,110,110,110,110,110,111,111,111,111,111,110,111,110,111,111,111,111,111,109,109,109,109,109,110,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,109,109,109,110,110,110,110,111,111,110,110,110,110,111,110,106,107,107,106,107,106,106,106,106,107,106,108,107,107,107,106,107,107,106,106,106,106,218,218,218,31,218,30,218,29,218,28,218,27,218,26,218,24,218,23,218,22,218,218,218,218,218,218,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,109,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,252,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,109,252,109,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,107,109,107,107,107,109,107,109,107,109,107,107,109,109,107,109,109,109,107,107,107,110,110,110,110,109,110,111,110,111,110,111,110,111,110,111,110,111,109,110,109,111,111,109,109,110,110,111,110,111,111,111,110,111,110,111,110,111,110,111,109,110,110,111,109,110,110,111,110,111,110,111,111,111,110,111,110,111,110,111,111,111,111,110,109,109,109,110,109,110,109,110,109,110,110,110,110,111,110,111,109,109,111,110,110,111,110,111,111,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,105,105,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,111,110,111,110,111,111,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,110,111,110,111,109,109,109,109,109,110,109,110,110,111,110,111,110,110,110,111,110,111,110,111,110,111,110,111,111,111,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,109,109,110,110,111,110,110,110,111,110,111,110,111,104,111,109,108,107,107,106,107,106,106,106,106,107,106,108,107,106,106,106,107,106,107,106,106,106,218,25,218,23,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221,220,221 +,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,108,109,108,109,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,109,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,252,109,109,109,252,252,252,252,252,252,252,252,252,252,252,107,109,107,109,107,107,107,109,109,109,107,107,107,109,107,109,109,109,109,109,107,107,109,110,110,110,110,111,111,111,110,111,110,111,111,111,111,111,109,111,111,111,111,109,110,111,110,110,110,110,110,111,111,111,110,111,110,111,111,111,111,109,110,110,111,111,110,110,109,110,110,110,110,111,111,111,111,111,111,111,110,111,109,109,109,109,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110,111,109,109,109,110,110,110,110,111,111,109,109,110,109,109,109,110,110,110,109,110,110,110,110,110,110,105,105,105,105,111,111,111,111,111,111,111,111,105,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,111,110,111,110,111,111,111,110,111,111,111,111,111,111,111,110,110,109,109,109,109,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,109,109,109,110,109,109,109,110,110,110,109,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,109,110,109,110,111,111,110,110,110,110,110,110,110,111,104,111,109,108,108,107,107,107,106,107,106,106,106,107,106,108,107,107,106,107,107,108,106,106,106,106,31,218,29,218,27,218,26,218,24,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221 +,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,108,109,252,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,109,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,109,109,109,107,109,107,110,109,110,110,111,110,111,110,111,111,111,110,111,109,111,109,111,110,111,111,110,109,110,110,111,110,111,111,111,110,111,110,111,111,111,110,111,110,109,109,111,111,111,111,111,110,111,110,111,110,109,109,110,110,111,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,109,109,110,109,110,110,111,111,111,109,110,109,110,109,110,109,110,109,110,109,110,109,110,105,105,105,105,111,111,110,111,111,111,111,105,111,105,110,111,111,111,110,111,111,111,110,111,111,111,111,111,111,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,111,111,111,111,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,110,110,111,110,110,110,111,110,111,110,109,109,110,109,110,110,111,110,111,111,111,110,111,110,110,110,111,110,111,104,111,109,108,107,108,107,107,106,107,106,107,106,106,106,108,106,107,106,106,106,107,107,107,106,107,106,106,30,218,28,218,26,218,31,218,28,218,25,218,23,218,217,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221,221,221,220,221 +,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,108,109,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,109,109,109,109,109,107,107,107,110,110,110,110,111,110,111,111,111,111,111,111,111,111,111,111,111,111,110,110,110,110,110,110,111,110,111,111,111,111,111,110,111,111,111,111,109,109,109,110,109,109,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,109,109,109,110,110,111,111,111,110,110,110,110,110,110,110,111,111,111,111,111,111,109,109,110,109,110,110,110,110,110,110,105,105,111,111,111,111,110,110,111,111,111,105,105,111,111,110,111,111,111,111,111,105,111,110,111,111,111,111,111,111,111,110,110,110,110,109,111,110,111,110,111,111,111,111,111,111,111,111,109,109,109,109,109,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,111,111,111,111,111,111,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,109,110,110,110,110,110,110,111,109,109,109,110,110,110,110,110,110,111,111,111,111,110,110,110,110,110,110,104,104,111,106,108,108,108,107,107,107,107,106,106,106,107,107,106,106,106,107,107,106,106,107,107,106,106,106,106,106,106,26,218,24,218,22,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,217,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221 +,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,108,109,252,109,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,109,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,109,109,109,107,107,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,110,109,110,109,110,110,110,110,111,110,111,110,111,110,111,111,111,110,109,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,109,110,109,110,109,110,110,111,110,111,111,110,110,110,110,111,110,111,110,111,110,111,110,111,111,111,111,110,109,110,105,105,105,105,105,105,110,111,110,111,110,111,105,111,110,111,110,111,111,111,111,111,111,111,110,111,110,111,110,111,111,111,109,110,109,111,110,111,110,111,110,111,110,111,110,111,111,111,111,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,109,111,110,111,110,111,111,111,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,111,110,111,110,111,110,111,109,110,109,110,109,110,110,111,110,111,110,111,111,111,110,111,110,111,110,104,106,108,104,109,108,108,107,108,107,107,106,107,106,107,106,107,107,106,107,106,107,106,106,107,107,106,106,107,106,106,106,218,25,218,31,218,28,218,25,218,22,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,221,217,217,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,220,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221 +,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,108,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,252,252,108,252,108,252,108,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,252,109,109,109,252,252,252,109,252,252,252,252,252,252,252,107,107,109,109,107,109,107,109,107,109,107,107,107,107,107,109,107,109,109,109,107,107,107,107,110,111,111,111,110,111,109,111,111,111,111,111,111,111,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,110,110,111,109,109,109,109,109,109,109,110,109,109,109,110,110,110,109,110,110,110,110,110,110,110,110,110,110,110,110,109,109,109,109,110,110,110,110,110,110,111,111,111,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,105,105,105,111,111,110,110,110,110,111,111,111,111,111,111,110,110,111,111,111,111,105,111,111,110,111,111,111,111,111,111,111,110,110,110,111,111,111,110,111,110,111,111,111,111,111,111,111,111,109,109,109,109,109,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110,109,110,111,110,111,111,111,111,111,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,109,110,111,110,110,110,110,110,111,109,109,109,110,110,110,110,110,110,111,111,111,111,111,111,110,110,110,110,106,107,109,104,109,107,108,108,108,107,107,107,107,107,106,106,106,107,107,106,106,107,107,107,106,107,106,107,106,107,106,106,106,106,218,218,218,218,218,218,218,218,218,218,218,218,218,217,218,218,218,217,218,217,217,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,109,108,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,109,107,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,109,109,109,109,109,107,107,107,110,109,110,110,110,110,111,110,111,111,111,109,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,111,110,110,111,110,111,110,111,109,109,109,105,105,105,105,105,105,105,105,110,109,110,109,110,109,110,110,111,109,109,109,110,109,109,109,110,109,109,109,110,110,111,111,110,109,110,110,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,105,105,111,111,111,111,110,110,111,110,111,110,111,110,111,110,111,109,110,110,111,111,111,110,111,111,111,110,111,110,111,111,111,111,110,109,110,111,111,110,111,110,111,111,111,110,111,111,111,110,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,109,110,111,109,111,111,111,111,111,109,110,109,110,109,110,109,110,109,110,109,109,111,110,109,109,109,111,111,110,110,109,110,111,110,109,109,110,109,110,110,111,110,111,111,111,111,111,111,111,110,111,110,106,107,108,106,104,104,108,107,108,108,108,107,108,107,107,106,106,106,108,107,106,106,106,107,107,106,106,106,107,107,107,106,106,106,106,106,218,218,218,222,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221 +,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,108,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,252,109,108,252,108,252,108,252,108,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,109,109,109,109,252,109,252,109,252,252,252,252,252,252,252,109,109,107,109,109,109,107,109,107,109,107,109,107,107,107,107,107,109,109,109,109,109,107,107,107,107,107,110,110,110,110,110,110,111,111,111,111,111,111,110,110,110,109,109,109,110,110,110,110,111,111,109,109,110,110,110,110,110,110,110,110,111,110,111,105,105,105,105,109,107,107,106,106,106,106,106,105,105,105,105,105,105,105,105,105,105,109,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,105,105,111,111,111,111,110,110,110,110,110,111,110,111,111,111,110,111,111,110,110,110,110,105,111,111,110,110,110,111,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,110,110,110,110,110,109,109,109,109,109,109,109,110,109,110,110,110,109,110,110,110,110,110,110,109,110,110,109,110,110,111,111,111,109,109,109,110,109,110,109,110,110,110,110,109,110,111,109,110,110,111,111,109,111,110,110,111,110,111,110,109,109,110,110,111,111,111,111,111,111,111,111,111,110,110,110,106,107,108,104,104,104,106,104,108,107,108,108,108,107,107,107,108,107,107,106,107,106,106,106,107,107,107,106,107,107,107,106,107,106,106,106,106,218,218,218,218,218,218,218,218,218,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,221,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,109,252,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,109,107,109,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,109,107,109,109,109,107,107,107,107,109,110,110,111,110,111,110,111,110,111,110,111,110,111,111,110,110,111,110,111,110,109,109,110,109,109,109,110,110,111,110,111,110,105,105,105,105,109,109,110,105,105,111,104,107,106,106,106,106,106,106,106,106,107,107,107,107,107,105,105,105,105,108,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,110,110,111,110,105,105,111,111,111,110,110,110,111,110,111,110,111,110,111,110,111,105,111,110,111,110,111,110,111,111,111,110,111,110,111,110,111,110,111,111,111,110,111,111,111,111,110,109,110,110,110,110,110,110,110,110,110,109,109,109,110,109,110,109,110,109,110,109,109,109,110,110,111,110,111,110,111,109,109,109,110,110,111,110,111,111,110,109,110,109,110,109,110,109,110,109,110,109,111,109,110,110,111,109,111,110,111,110,111,110,111,110,111,110,111,109,111,110,111,110,111,111,111,110,111,110,111,110,106,107,104,104,110,110,104,106,107,107,108,108,104,104,108,107,108,107,107,106,106,106,107,106,106,106,108,107,107,106,107,107,106,106,107,106,107,106,106,104,104,104,104,104,218,218,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,218,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,222,222,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221 +,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,108,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,252,252,252,252,108,252,108,252,108,252,108,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,109,109,252,109,109,109,252,252,252,252,252,252,252,109,109,107,107,107,109,109,109,107,109,107,109,107,109,107,109,107,107,107,107,107,109,109,109,109,109,107,107,107,110,110,110,110,111,110,111,110,111,111,111,111,111,111,110,110,110,110,109,109,110,109,110,110,110,110,110,110,111,105,105,105,105,109,109,109,110,105,105,105,111,111,111,104,107,106,107,106,107,106,107,106,107,106,107,106,107,106,107,107,108,108,109,108,109,109,109,109,110,109,110,109,110,110,110,109,110,110,110,110,110,110,110,110,110,110,110,105,105,111,111,111,111,110,110,110,110,110,110,110,111,111,111,109,110,105,111,110,111,111,110,110,111,111,111,110,110,110,110,110,111,111,111,111,111,111,111,111,111,111,110,110,110,110,110,110,110,110,110,110,110,109,109,109,109,109,109,109,110,110,110,109,109,110,110,110,111,111,111,110,111,109,109,109,110,110,110,110,111,110,111,111,111,109,110,109,110,110,110,110,110,109,109,109,110,110,110,111,111,110,110,110,111,110,110,110,111,111,111,111,111,111,111,111,111,111,111,111,110,109,109,110,110,104,104,110,111,111,109,104,106,106,107,107,108,108,104,104,104,108,108,107,107,106,106,106,107,107,106,106,107,107,107,106,108,106,108,106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104,104,218,217,218,217,218,217,218,217,217,217,217,217,217,221,217,217,217,221,217,221,217,221,217,221,221,221,221,221,221,221,217,221,217,221,221,221,222,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,109,252,109,252,109,108,252,252,252,108,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,109,107,109,107,109,107,109,109,109,107,109,107,107,107,109,107,107,107,109,107,109,107,109,107,109,107,107,107,107,107,111,110,111,110,111,110,111,110,111,110,111,111,109,109,110,109,110,109,110,110,110,110,110,110,105,105,105,105,105,105,105,105,105,105,105,105,111,110,111,110,111,111,111,104,107,106,107,106,107,106,107,107,108,107,107,107,107,107,107,108,107,108,109,108,109,108,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,110,110,105,105,105,111,111,110,111,110,111,110,111,110,111,110,111,110,111,109,111,111,111,111,110,110,111,110,111,111,110,109,110,110,111,110,111,110,111,110,111,111,111,110,111,111,110,109,110,110,110,109,110,110,111,110,110,109,110,109,110,109,110,109,110,109,109,109,110,109,110,110,111,111,111,110,111,110,109,109,110,109,110,109,110,110,111,110,111,111,110,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,111,111,111,109,110,109,110,110,111,110,111,110,109,109,110,109,104,106,107,106,107,107,108,108,104,104,104,104,107,106,107,106,107,107,107,106,106,107,108,107,107,106,106,107,107,106,107,106,106,106,104,104,104,104,104,104,104,104,104,104,104,106,104,217,218,217,217,217,218,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,222,222,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221 +,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,109,109,109,252,109,252,252,252,252,252,252,109,109,107,107,109,107,109,109,109,107,109,107,107,109,109,107,109,107,107,107,109,107,109,109,109,109,109,107,107,107,107,110,110,110,111,110,111,110,111,111,111,109,109,109,109,109,110,109,110,110,110,105,105,105,105,111,111,111,111,111,110,110,110,110,110,110,110,110,111,111,111,111,111,111,104,107,107,106,107,107,107,106,107,107,108,107,107,107,107,107,107,108,108,108,109,108,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,105,105,105,105,105,105,105,111,111,110,110,110,110,109,110,110,111,111,111,111,105,111,111,110,111,111,111,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,111,110,110,110,110,110,110,110,110,110,110,110,109,109,109,109,109,109,110,109,109,109,110,110,110,110,111,111,111,110,111,110,109,109,110,110,110,110,110,110,111,111,111,109,110,109,110,110,110,110,110,109,109,109,110,110,111,111,111,110,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,111,109,109,109,110,110,111,111,111,109,110,110,110,110,104,106,106,106,107,107,108,108,108,108,104,104,104,104,104,106,106,106,107,107,107,106,106,107,107,107,107,106,108,106,107,106,106,106,106,106,104,104,104,104,104,104,104,104,104,106,107,108,104,217,218,217,218,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,217,221,222,221,217,221,217,221,222,221,222,221,222,221,222,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,107,109,252,109,252,109,252,109,252,252,109,109,107,107,109,107,109,107,109,109,109,107,107,109,109,107,109,107,107,107,109,107,109,107,109,109,109,107,109,107,107,107,107,110,111,110,111,110,111,110,111,109,109,109,110,109,110,109,105,105,105,105,111,105,105,111,111,111,111,109,110,109,110,110,110,110,111,110,111,110,111,110,111,111,110,104,107,107,107,106,107,107,107,107,107,107,108,107,107,107,107,107,107,108,107,108,109,108,110,108,110,109,110,109,110,109,110,109,110,109,110,109,110,105,105,105,105,105,111,111,111,110,109,109,110,109,110,110,111,110,111,110,111,111,105,111,110,110,111,111,110,109,110,109,110,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,110,110,110,110,110,110,110,110,110,110,111,109,109,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,109,110,109,110,110,111,110,111,109,110,109,110,109,110,109,110,109,110,110,109,109,111,111,111,110,111,110,111,110,111,110,111,110,111,110,111,109,110,109,110,109,110,110,111,110,111,111,110,110,111,111,110,109,110,110,110,110,104,106,107,106,107,107,108,107,108,108,104,108,104,104,104,104,107,106,107,106,107,107,106,106,106,106,108,107,106,108,107,106,107,106,107,106,106,106,104,104,104,104,104,106,104,106,107,107,104,104,106,217,218,217,217,217,217,217,217,217,217,217,217,217,217,221,217,221,217,221,217,221,221,221,221,221,217,221,221,221,221,221,221,221,221,221,221,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222 +,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,252,109,252,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,107,107,252,109,252,109,252,252,252,252,252,109,107,107,107,107,107,107,109,109,109,109,107,109,109,107,109,107,109,107,107,107,107,107,109,109,109,107,109,107,107,107,107,107,110,110,110,110,110,110,111,109,109,109,105,105,105,105,105,105,105,111,105,105,111,111,111,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,104,108,107,107,107,108,107,107,107,107,107,107,107,107,108,107,108,107,108,107,108,107,108,109,108,110,109,109,109,110,109,110,109,110,110,110,109,105,105,111,111,111,111,111,111,111,110,110,110,109,109,110,110,111,111,111,111,111,111,105,111,111,110,111,110,111,109,110,109,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,111,111,110,110,110,110,110,110,110,110,110,110,109,109,109,109,109,110,111,110,109,110,110,110,110,110,110,110,110,111,110,111,110,109,110,111,111,111,109,109,109,110,109,110,109,110,110,110,109,110,110,110,109,111,110,110,110,110,110,110,110,111,110,110,110,111,111,111,109,109,109,110,110,110,110,110,110,111,111,109,111,110,110,110,110,110,110,110,110,110,110,104,106,107,107,107,107,108,108,108,108,104,104,104,104,108,107,106,106,107,107,107,106,106,106,106,108,107,106,108,106,107,107,106,106,107,106,106,106,104,104,104,106,104,104,104,106,107,108,104,106,106,217,218,217,217,217,217,217,217,221,217,221,217,221,217,221,217,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,221,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,252,107,252,109,252,109,252,109,252,109,252,252,109,107,107,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,107,107,109,107,109,107,109,109,109,107,109,107,107,107,109,107,110,110,111,110,111,105,111,105,105,110,105,110,105,111,111,110,111,111,111,111,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,111,104,104,108,107,108,107,107,107,107,107,107,107,107,107,107,107,107,108,107,108,107,108,108,108,108,108,109,108,110,108,110,109,110,109,110,109,110,105,105,111,111,110,111,110,111,110,111,110,111,110,111,109,110,109,110,110,111,111,111,105,111,110,111,110,111,110,111,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,111,111,110,111,110,110,109,110,110,110,110,110,110,111,109,110,109,110,110,111,111,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,111,111,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,110,110,111,110,110,110,111,110,111,110,111,110,111,110,111,109,110,109,110,109,110,110,111,110,111,111,111,110,111,111,110,109,110,110,110,109,110,110,111,110,104,104,106,106,107,107,108,108,104,104,104,104,106,108,107,106,106,106,107,106,107,106,106,106,106,107,106,107,107,106,107,106,106,106,107,106,106,104,104,104,104,104,104,104,106,107,104,106,106,106,218,217,218,217,218,217,217,217,217,217,217,217,217,217,222,221,217,221,217,221,221,221,222,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,108,252,108,252,252,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,107,107,107,252,109,252,252,252,252,252,252,109,107,107,107,107,107,109,109,109,109,107,107,109,109,109,107,109,107,109,107,107,107,109,107,109,109,109,107,109,107,107,107,107,107,107,107,105,111,111,105,111,111,111,111,111,111,111,111,111,111,111,110,110,110,110,110,110,110,110,110,110,110,111,110,111,111,111,111,111,111,111,111,104,108,108,108,108,107,108,107,108,108,108,107,107,107,107,107,107,108,107,107,107,108,107,108,107,108,108,108,109,108,109,109,110,109,110,109,105,105,111,111,111,111,111,110,110,110,110,110,110,110,110,110,111,110,109,110,110,111,111,111,110,110,111,110,111,111,111,109,109,109,110,110,110,110,110,110,110,110,111,110,111,111,111,111,111,111,111,111,110,110,110,110,110,110,110,110,109,109,110,110,110,110,111,111,111,109,110,110,110,110,110,110,111,110,111,111,111,111,111,111,111,111,111,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,110,111,111,109,110,110,111,109,109,109,109,110,110,110,110,110,110,111,111,111,111,110,110,110,110,110,110,110,104,106,106,107,107,108,108,104,104,104,104,107,107,107,108,106,106,106,107,107,107,106,106,106,107,107,107,106,108,107,107,107,106,106,107,107,107,106,104,104,104,104,104,106,107,104,106,107,106,106,106,218,217,217,217,217,217,217,221,217,221,221,221,217,217,217,221,222,221,217,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,221,221,221,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221,221,221,222,221,221,221,221,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,107,107,252,107,252,109,252,109,252,252,109,109,107,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,109,107,109,109,109,107,109,107,107,107,107,107,107,107,111,110,111,110,111,111,111,110,111,111,111,109,110,109,110,109,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,104,108,108,108,108,107,108,107,108,108,108,108,108,107,108,107,107,107,107,107,107,108,107,108,107,108,108,108,107,108,109,108,110,109,110,105,105,105,105,111,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,110,109,111,111,111,111,110,111,110,111,110,111,111,110,109,110,109,110,110,110,110,111,110,111,110,111,110,111,111,111,110,111,111,111,110,110,110,110,110,110,110,109,109,110,109,110,110,111,110,111,109,110,110,110,110,111,110,111,110,111,110,111,111,111,110,111,111,111,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,109,109,110,109,110,109,110,110,110,110,111,110,111,110,111,111,110,110,111,110,111,110,111,104,104,104,104,106,107,107,104,104,104,107,108,107,107,108,107,106,107,107,107,106,106,106,106,107,108,106,108,107,107,106,107,106,106,106,107,106,106,104,104,104,104,106,104,106,107,107,107,106,106,106,218,217,217,217,217,217,217,217,217,217,217,222,217,222,221,221,222,221,221,221,221,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,108,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,108,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,107,107,107,252,252,252,109,252,252,252,109,107,107,107,107,109,107,109,107,109,109,107,107,109,109,109,107,109,107,109,107,107,107,107,107,109,109,109,107,109,107,109,107,107,107,107,107,107,111,111,110,111,111,111,111,111,111,111,109,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,111,111,104,104,108,108,108,108,108,108,108,108,107,108,108,108,108,108,108,108,107,107,107,107,107,107,107,107,108,107,108,107,108,107,108,109,108,109,105,105,105,105,111,109,109,110,109,110,109,110,110,110,110,110,110,110,110,111,111,111,109,111,110,111,110,111,111,111,111,111,111,111,109,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,110,110,110,110,109,109,110,110,110,110,111,110,111,109,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,111,111,109,109,109,110,109,110,109,110,110,110,109,110,110,110,110,110,110,110,110,110,110,110,110,111,110,110,110,111,111,111,110,111,111,111,111,111,109,109,109,110,110,110,110,110,110,110,110,111,111,111,111,110,110,110,110,111,110,110,110,111,111,111,110,104,106,108,104,104,108,107,107,107,107,108,106,106,106,107,106,106,106,106,106,106,107,106,108,107,107,107,106,106,107,106,107,107,106,104,106,107,108,104,106,106,106,107,107,106,106,106,106,218,217,221,221,217,217,217,221,217,217,217,221,217,222,217,221,222,221,222,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221,222,221,221,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,108,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,109,252,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,107,252,107,252,107,252,252,252,252,109,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,107,109,107,109,109,109,107,109,107,109,107,107,107,109,107,107,107,107,110,111,111,111,111,111,109,110,109,110,109,110,109,110,110,111,110,110,110,111,110,111,110,111,110,111,111,111,111,111,104,108,107,108,108,108,107,108,107,108,107,108,107,108,107,108,108,108,107,107,107,108,107,107,107,108,107,107,107,107,107,107,108,108,109,105,105,105,105,105,111,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,111,111,109,111,110,111,110,111,110,111,110,111,111,111,111,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,110,111,111,111,111,111,111,111,111,110,110,109,109,110,110,111,109,110,110,111,110,111,110,110,110,110,110,111,110,111,111,111,111,111,110,111,110,111,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,110,110,111,110,109,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,109,109,110,109,110,109,110,110,111,110,111,111,111,110,110,110,111,110,111,110,111,110,111,110,111,110,111,104,106,107,108,104,104,107,108,107,108,107,108,107,107,106,107,106,107,106,106,106,108,106,108,107,107,106,107,106,106,107,107,107,104,106,107,108,104,107,106,106,107,106,107,106,107,106,106,106,217,221,217,217,217,217,217,221,222,221,222,221,217,221,221,221,221,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,108,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,107,252,252,252,252,252,109,109,107,107,107,107,107,109,107,109,109,107,107,109,107,109,109,109,107,109,107,107,109,109,109,109,107,109,107,109,107,109,107,107,107,107,107,107,107,111,111,111,111,109,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,111,111,111,111,111,111,104,108,108,108,108,108,108,108,108,108,108,108,108,108,107,108,108,108,107,107,107,107,108,108,107,107,107,107,107,107,107,107,107,107,105,105,105,105,105,105,111,109,109,109,109,110,109,110,110,110,110,110,110,111,109,110,110,111,111,111,110,111,110,111,111,111,111,111,111,111,111,111,109,110,110,110,110,110,110,111,111,111,110,111,110,111,110,111,111,111,111,111,111,111,111,111,110,110,110,109,109,109,109,110,110,110,110,111,111,110,110,110,110,111,111,111,111,111,110,111,111,111,111,111,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,109,110,110,111,111,110,110,110,110,110,110,111,110,111,111,111,111,111,111,111,111,111,111,109,109,110,110,110,110,110,110,111,111,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,104,106,106,107,108,104,104,108,107,107,107,107,107,107,107,107,106,106,106,106,106,106,106,108,107,107,107,107,107,107,106,107,107,104,106,106,107,104,108,107,106,106,106,107,107,107,106,106,106,106,106,217,221,217,221,217,221,217,221,217,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,108,252,109,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,252,107,107,109,252,109,252,252,109,109,107,107,109,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,107,107,107,107,107,109,107,107,107,111,111,109,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,111,111,104,108,108,108,108,108,108,108,108,108,107,108,107,108,107,108,107,108,108,108,107,108,107,108,108,108,107,108,107,108,107,107,107,105,105,105,105,111,105,105,111,110,109,110,109,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,110,110,111,110,111,111,110,110,110,110,111,110,111,110,111,110,111,111,111,110,111,110,111,111,111,110,111,109,110,109,110,109,110,110,111,110,111,111,111,110,111,111,111,110,111,110,111,110,109,111,111,109,110,109,111,109,110,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,110,109,109,109,110,110,111,111,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,104,104,106,107,107,108,108,104,107,108,107,108,107,107,108,107,106,107,106,107,106,107,106,106,106,108,106,108,107,107,106,107,106,106,107,104,106,104,108,108,107,107,106,107,106,107,106,107,106,107,106,106,221,217,221,217,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,108,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,107,107,107,107,252,109,252,252,252,109,109,109,107,107,107,107,107,107,109,109,109,109,107,107,109,109,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,107,107,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,111,111,111,110,111,111,111,111,104,104,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,107,108,108,108,107,108,107,107,108,108,108,108,107,108,107,105,105,111,105,111,105,105,111,110,109,110,110,110,110,110,110,109,109,110,110,110,110,111,111,111,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,111,110,111,109,109,109,110,110,110,110,110,110,109,109,111,111,111,111,111,111,111,111,111,111,111,110,111,109,109,109,110,110,110,110,110,110,111,111,111,110,110,110,111,110,111,110,111,111,111,111,111,109,109,110,111,109,109,109,109,109,109,109,110,110,110,110,110,110,111,110,111,111,111,110,110,110,110,110,111,111,111,110,111,111,111,111,111,111,111,111,111,110,110,110,111,111,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,104,106,107,107,108,108,104,104,106,107,108,107,107,107,107,107,107,106,107,106,106,106,106,106,106,107,106,107,108,107,107,106,107,107,108,104,104,107,108,108,107,107,107,106,107,107,107,106,106,106,106,106,106,221,217,217,222,221,222,217,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,109,252,252,109,109,252,252,252,252,252,252,252,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,109,107,252,109,252,109,252,109,109,109,109,107,107,107,109,107,109,107,109,107,109,109,107,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,107,107,107,109,107,107,107,109,107,107,109,110,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,111,104,108,108,108,108,108,108,108,108,108,108,108,108,108,108,107,108,108,108,107,108,107,108,107,108,107,108,107,108,108,108,107,108,105,105,105,111,105,111,105,105,111,110,109,110,109,110,109,110,110,109,109,110,109,110,110,111,111,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,110,111,110,110,109,110,109,109,109,110,109,110,110,109,109,110,110,111,110,111,111,111,110,111,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,111,109,110,110,111,111,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,111,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,109,110,110,111,110,111,111,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,104,106,106,107,107,108,108,104,106,106,107,108,107,107,107,107,106,107,106,107,106,107,106,106,106,106,107,108,106,107,107,106,107,108,104,107,107,108,107,108,107,107,106,107,106,107,106,107,106,107,106,107,106,106,221,217,221,217,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,109,109,252,252,109,109,252,252,252,252,252,252,108,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,107,107,107,107,252,252,252,252,252,252,109,109,109,107,107,107,107,107,109,107,109,109,109,107,109,109,109,107,109,107,107,109,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,107,107,107,109,109,109,109,109,110,109,110,111,110,110,109,111,110,110,111,111,111,111,111,111,107,107,108,108,108,108,108,108,108,108,108,108,108,108,107,107,108,108,108,108,108,108,108,107,108,107,108,107,108,107,107,108,105,105,105,111,111,105,111,105,111,111,110,109,110,110,110,110,110,110,109,109,110,110,110,110,111,111,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,111,111,111,109,109,109,110,109,110,110,110,109,109,109,110,110,110,110,111,111,111,109,109,109,109,109,110,109,109,109,110,110,110,110,110,110,111,111,111,110,111,110,111,111,111,111,111,111,109,109,109,109,110,110,111,110,110,110,110,110,110,110,110,110,110,110,111,109,110,111,111,111,111,111,111,110,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,109,110,110,110,110,111,111,111,111,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,104,106,106,107,107,108,108,104,104,106,106,108,107,108,107,107,107,107,107,107,106,107,106,106,106,106,106,106,107,107,107,107,106,107,108,104,108,108,108,108,107,107,107,107,106,106,107,107,107,107,106,106,106,106,106,106,221,217,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,109,252,109,252,252,109,109,252,109,252,109,252,252,252,252,108,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,107,252,109,252,109,252,109,252,109,109,109,107,107,107,107,109,107,109,107,109,107,109,107,109,109,109,107,107,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,109,107,107,107,107,107,107,109,110,109,110,110,111,110,109,111,110,110,111,110,111,110,111,110,109,109,110,107,107,107,107,108,108,108,108,108,108,108,108,107,108,107,107,107,108,108,108,107,108,107,108,107,108,107,108,107,108,107,105,105,111,111,111,111,111,105,111,111,110,109,110,109,110,109,110,110,110,109,110,109,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,110,111,110,109,109,110,109,110,109,110,109,110,109,109,109,110,109,110,110,111,110,111,111,109,109,110,109,110,109,110,110,111,111,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,111,110,109,110,109,111,110,111,109,110,110,110,110,111,110,111,110,111,110,109,109,110,110,111,110,111,111,111,111,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,110,109,110,110,111,110,111,110,111,111,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,104,106,106,107,107,108,108,104,104,104,106,106,106,108,107,108,107,107,107,107,106,107,106,107,106,107,106,106,106,108,107,108,107,107,104,107,108,108,107,108,107,108,107,108,107,107,107,107,106,107,106,107,106,107,106,107,106,106,221,217,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,109,252,109,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,109,252,252,252,252,252,109,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,252,252,252,252,252,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,109,107,107,109,109,252,252,252,252,109,109,109,107,107,107,107,107,109,107,109,107,109,109,109,109,109,109,109,107,109,109,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,107,107,107,107,110,109,110,110,110,109,111,111,111,111,111,110,110,110,111,111,109,109,110,110,107,106,107,107,107,107,108,108,108,108,108,108,108,108,108,107,107,107,108,108,108,108,108,105,105,105,105,105,105,105,105,105,111,111,111,111,111,105,111,111,110,109,110,110,110,110,110,110,110,110,109,110,111,110,111,110,110,110,111,111,111,110,111,111,111,111,111,111,111,110,111,111,111,110,109,109,109,109,110,109,110,109,110,110,109,109,110,110,110,110,110,110,111,111,111,109,109,109,110,110,110,109,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,110,109,109,110,110,110,110,111,111,110,110,110,110,110,110,111,110,110,110,109,109,110,110,110,110,111,111,111,111,111,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,109,109,110,110,110,110,111,110,111,111,111,111,110,110,110,110,110,110,111,110,110,110,111,111,111,110,104,106,108,109,108,104,110,108,104,104,104,106,106,106,108,107,108,107,107,107,107,107,107,106,107,106,106,107,106,106,108,107,107,107,107,108,108,108,108,108,108,108,108,107,108,107,106,108,107,107,107,106,106,106,106,106,106,106,107,221,222,217,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,107,252,109,252,109,252,109,252,109,109,109,109,107,109,107,109,107,109,107,109,107,109,107,109,109,109,107,109,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,107,107,109,107,107,107,107,107,110,110,111,110,111,110,111,110,111,111,111,110,111,110,109,109,110,109,110,107,107,106,107,106,107,107,107,108,108,108,108,108,108,108,108,107,107,105,105,105,105,105,111,111,105,105,105,105,105,111,111,110,111,111,111,105,111,111,110,109,110,110,110,109,110,110,111,110,109,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,111,111,111,110,111,110,111,110,111,109,109,109,110,109,110,109,110,109,109,109,110,109,110,109,110,110,111,110,111,111,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,111,111,110,111,109,109,109,110,110,111,110,111,111,111,110,110,110,111,110,111,110,111,110,109,109,110,109,110,110,111,110,111,110,111,111,111,110,111,110,111,110,111,110,111,111,111,110,111,111,109,109,110,109,110,109,110,110,111,110,111,111,111,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,106,110,108,104,104,111,104,107,106,106,107,108,107,108,107,107,107,107,106,107,106,106,106,107,107,106,106,108,107,108,108,108,108,108,108,108,108,108,107,108,107,108,106,107,108,107,106,106,106,107,106,107,106,107,106,107,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,107,107,109,109,109,252,109,252,252,109,109,109,109,107,107,107,107,107,107,109,107,109,109,109,109,109,109,107,107,109,109,109,107,109,107,109,107,107,107,109,107,107,107,107,107,107,107,107,107,107,107,107,110,110,110,110,110,111,111,111,111,111,110,110,110,109,109,109,109,110,107,107,106,107,106,107,106,107,107,107,107,108,108,105,105,105,105,105,105,105,111,105,111,105,105,105,105,105,105,111,111,105,111,111,111,111,105,111,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,110,111,110,111,111,111,111,111,109,109,109,109,109,109,109,110,109,110,109,109,109,110,110,110,110,111,110,111,111,109,109,110,109,111,110,110,110,110,110,110,110,110,110,111,110,111,111,111,111,111,111,110,109,109,109,110,110,111,111,111,110,110,110,110,110,110,110,111,110,111,110,109,109,109,109,110,110,110,110,110,110,111,110,111,111,111,110,111,111,111,111,109,111,111,111,111,109,109,109,110,110,110,110,111,111,111,111,111,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,106,107,108,104,104,104,107,106,106,106,106,107,108,107,107,107,107,107,107,107,107,106,107,107,107,106,106,106,108,108,108,108,108,108,108,108,108,108,108,108,108,107,106,107,108,107,106,106,107,107,107,106,106,106,107,107,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,109,252,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,109,252,109,252,109,252,109,109,109,109,107,107,107,109,107,109,107,109,107,109,109,109,109,107,107,107,109,109,107,109,107,109,107,109,107,109,107,107,107,107,107,109,107,109,107,109,107,107,107,107,110,111,110,111,110,111,109,110,110,110,110,109,109,110,109,110,109,107,106,107,106,107,106,107,106,105,105,105,105,105,111,105,105,111,105,105,111,105,111,111,111,105,105,105,105,105,105,105,111,111,111,111,105,111,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,110,111,110,111,110,111,110,111,109,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,110,111,110,111,111,110,109,109,109,110,110,111,110,110,110,110,110,111,110,111,110,111,110,111,111,111,111,109,109,110,109,110,110,111,110,111,111,111,110,111,110,111,110,111,110,111,110,111,109,110,109,110,109,110,109,110,110,111,110,111,110,111,111,111,110,111,110,109,110,111,111,109,109,110,109,110,110,111,110,111,110,111,111,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,109,110,111,110,111,110,111,110,106,106,110,104,107,106,107,106,107,106,106,107,108,107,108,107,107,106,107,106,106,106,107,107,106,106,106,108,108,108,108,108,108,108,108,108,108,107,108,107,108,107,106,107,107,106,106,106,107,106,107,106,107,106,107,106,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222,221,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,108,252,108,252,108,108,109,252,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,109,109,109,109,109,252,109,109,109,109,107,107,107,109,107,109,107,109,109,109,109,107,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,107,107,107,107,107,107,107,107,107,107,107,107,111,111,111,109,110,110,110,110,110,110,110,109,109,109,110,109,110,107,107,105,105,105,105,105,105,105,105,105,105,105,111,111,111,111,111,111,111,111,111,105,105,105,111,111,111,111,111,111,111,111,105,111,111,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,110,111,111,111,111,111,111,111,110,111,110,110,110,111,111,111,110,111,109,109,109,109,109,109,109,110,109,109,109,109,109,110,109,110,110,110,110,111,111,109,109,109,109,110,110,111,111,110,110,110,110,110,110,111,111,111,111,111,111,111,109,109,109,110,110,111,110,110,110,111,111,111,110,110,110,110,110,111,110,111,110,111,111,109,109,110,109,110,110,110,110,110,110,111,111,111,111,111,111,111,110,111,109,110,111,109,109,109,109,110,110,110,110,111,111,111,111,110,110,110,110,110,110,110,110,111,110,110,110,111,110,111,110,109,111,111,111,111,111,111,106,107,108,104,110,107,107,107,106,107,106,106,106,108,107,107,107,107,107,107,107,107,106,106,106,107,107,106,106,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,107,107,107,106,106,107,107,107,106,106,106,106,106,107,107,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,108,109,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,109,109,252,109,252,109,109,109,109,109,107,107,107,107,109,107,109,107,109,107,109,107,109,107,109,109,109,107,109,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,107,107,107,107,107,109,110,109,110,109,110,109,110,110,111,110,109,109,110,109,110,105,105,105,111,111,111,105,111,105,111,111,105,111,109,111,111,111,111,111,111,111,105,105,105,105,111,105,111,111,111,111,105,111,111,111,110,109,110,109,110,110,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,111,110,111,110,111,110,111,110,111,110,109,109,109,109,109,109,109,109,110,109,109,109,109,109,110,110,111,110,111,109,110,109,109,109,110,110,111,111,111,110,111,110,111,110,111,110,111,110,111,111,109,109,110,109,110,109,110,110,111,111,111,111,111,110,110,110,111,110,111,110,111,110,111,110,111,109,109,109,110,109,110,110,110,110,111,110,111,110,111,111,111,110,111,110,111,110,111,109,110,109,110,110,111,110,111,110,111,111,110,110,111,110,110,110,111,110,111,109,110,109,110,110,111,110,111,110,111,110,111,110,111,106,107,108,104,110,107,107,107,106,106,107,107,106,106,106,108,107,108,107,108,106,107,107,106,106,107,107,107,106,106,106,108,108,108,108,108,108,108,108,108,108,108,108,108,107,108,107,108,107,106,106,107,107,107,106,106,106,107,106,107,107,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222,222,222,221,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,108,108,108,108,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,252,109,109,109,109,252,252,109,109,109,107,107,107,107,107,109,109,109,109,109,107,107,107,109,109,109,109,109,107,109,107,109,107,107,109,109,107,107,107,107,107,107,107,107,107,107,107,107,107,109,109,109,109,109,109,110,109,110,109,110,110,109,109,110,110,110,111,111,110,111,105,105,111,111,105,111,111,111,111,111,111,111,111,111,105,105,111,105,111,111,111,111,111,111,105,111,111,105,111,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,111,111,110,110,110,111,111,111,110,111,110,111,110,111,110,111,111,111,111,111,109,109,109,109,109,109,109,109,109,109,109,109,109,109,110,110,111,109,109,109,109,110,109,110,110,111,111,110,110,110,110,110,110,109,110,111,111,111,109,109,109,110,109,109,109,110,110,110,110,111,111,111,110,110,110,110,110,110,110,111,110,111,110,111,110,109,109,109,109,110,110,110,110,110,110,111,111,111,110,111,110,111,111,111,111,111,111,109,109,110,110,110,110,111,111,111,111,111,110,110,110,110,110,110,110,109,109,110,110,110,110,110,110,111,111,111,111,111,111,111,111,106,107,108,104,110,107,107,107,106,106,107,107,107,106,106,106,108,107,107,107,106,106,107,106,106,106,107,107,106,106,106,106,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,107,107,106,106,106,107,107,107,106,106,106,107,107,107,106,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,252,109,109,252,109,252,109,109,109,107,107,109,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,109,107,109,107,107,109,109,109,110,109,110,109,110,109,111,109,110,109,110,109,110,110,111,110,111,111,111,111,111,111,111,110,111,110,111,111,111,111,105,105,105,105,105,105,111,105,111,111,111,105,111,111,111,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,111,110,111,110,111,110,111,109,109,109,109,109,109,109,109,109,109,109,110,109,110,109,110,109,109,109,110,109,110,109,110,109,111,110,110,110,111,109,110,109,110,110,111,110,111,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,109,109,110,109,110,110,111,110,111,111,111,110,111,110,111,110,111,110,111,111,111,109,110,109,110,110,111,110,111,111,111,111,110,110,110,110,111,110,109,109,110,109,110,110,111,110,111,111,111,110,111,110,111,110,106,107,108,104,110,107,108,107,107,106,107,106,107,107,107,106,106,107,108,107,108,107,107,106,107,106,107,106,107,106,106,107,106,108,108,108,108,108,108,108,108,108,108,108,108,107,108,107,108,107,106,107,106,106,107,106,106,106,107,107,107,107,106,106,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,108,108,108,108,108,252,108,108,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,109,109,109,252,252,252,252,109,107,107,107,109,109,109,109,109,107,109,107,107,107,107,107,109,109,109,107,109,107,109,107,107,109,109,107,109,107,107,107,107,107,107,107,107,107,107,107,107,109,109,109,110,110,110,110,111,110,110,109,110,110,110,110,110,110,110,110,111,111,111,110,111,111,111,111,111,111,111,111,105,111,111,111,105,111,111,111,111,111,105,105,111,111,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,110,110,110,111,110,111,111,111,111,110,110,111,111,111,110,111,111,111,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,110,109,109,109,110,109,110,109,110,110,109,109,110,110,110,110,110,110,111,110,111,111,109,109,110,109,109,109,110,110,110,110,111,111,111,111,110,110,110,110,111,110,110,110,111,110,111,110,111,111,111,110,111,111,111,111,111,111,111,111,111,110,111,110,111,111,111,111,111,111,111,111,111,109,109,110,110,111,111,110,111,111,111,110,110,110,110,110,109,109,109,109,110,110,110,110,111,111,111,110,111,111,111,111,111,106,107,108,109,110,108,107,107,107,106,106,107,107,107,106,106,106,106,107,108,107,107,107,107,107,107,106,107,107,106,106,107,107,106,108,108,108,104,104,104,104,108,108,108,108,108,108,108,108,108,107,106,106,106,106,107,107,106,106,107,107,106,106,106,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,107,252,252,252,109,109,109,252,109,252,252,107,107,109,107,109,107,109,109,109,107,107,107,109,107,109,109,109,109,109,107,109,107,109,107,107,107,109,107,109,107,107,107,109,107,107,107,109,107,107,107,110,109,110,110,111,111,110,109,110,109,110,110,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,111,111,105,105,111,111,105,105,111,111,105,111,105,105,111,111,111,110,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,111,111,110,110,110,111,110,111,111,111,110,111,110,111,110,111,110,111,111,111,109,109,109,110,109,109,109,109,109,109,109,110,109,109,109,110,109,110,109,109,109,110,109,110,109,110,110,109,109,110,109,110,109,110,110,111,110,111,110,111,111,110,109,110,109,110,110,111,110,111,111,111,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,111,110,111,110,111,110,111,111,111,111,111,109,110,109,110,110,111,110,111,110,111,110,110,110,111,110,109,109,110,109,110,110,109,110,111,110,111,110,111,110,111,110,111,111,109,109,109,108,108,107,108,107,108,107,107,106,106,106,107,107,107,106,108,107,108,107,107,107,107,106,107,106,106,106,107,106,104,104,104,104,104,104,104,104,104,104,104,108,108,108,108,108,108,107,108,107,108,106,107,106,107,106,107,106,107,107,107,106,106,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,223,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,108,108,108,108,108,108,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,252,252,252,252,107,107,107,107,109,109,109,107,107,107,107,107,109,109,109,109,109,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,107,107,107,107,107,110,110,111,111,109,110,109,110,109,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,105,105,111,105,105,105,105,111,111,111,111,111,111,111,111,109,109,109,109,109,110,109,110,110,110,110,110,110,110,110,111,110,111,111,111,111,111,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,110,110,109,109,109,109,110,110,110,110,110,110,111,110,111,111,111,111,110,110,110,110,111,110,111,111,111,110,110,110,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,111,110,111,111,111,111,111,111,111,111,111,110,110,109,109,109,110,110,110,110,111,111,110,110,110,110,110,109,110,110,110,111,109,110,111,111,111,111,111,111,111,111,111,111,109,109,109,109,108,108,108,107,107,107,107,107,106,106,107,107,107,106,106,106,107,107,107,107,107,106,106,106,106,104,104,104,104,104,109,109,109,109,109,109,109,109,109,104,104,104,104,108,108,108,108,107,108,107,107,107,107,107,107,107,106,106,107,106,106,106,106,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,252,108,252,108,252,108,252,108,252,108,252,108,109,108,252,108,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,109,107,109,107,107,109,109,107,109,109,107,109,107,107,107,107,107,109,107,109,107,109,107,109,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,110,111,110,111,111,111,105,105,105,105,105,111,110,111,111,111,111,111,111,110,111,111,111,109,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,110,111,111,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,109,110,111,110,111,109,109,109,109,109,109,109,110,109,109,109,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,109,109,110,109,110,109,110,110,111,110,111,110,111,111,111,110,111,110,111,110,111,111,110,109,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,109,110,111,110,111,111,111,111,111,111,110,110,109,109,110,109,110,110,111,111,111,110,111,110,111,110,111,110,111,110,109,111,111,110,111,110,111,110,111,110,111,110,109,109,110,109,108,107,108,107,108,107,108,107,107,106,107,106,107,106,107,106,106,106,107,106,106,104,104,104,104,104,109,109,110,109,110,109,110,110,111,110,111,109,110,109,110,109,110,110,109,109,109,107,108,107,108,107,108,107,107,107,107,106,107,106,107,106,107,106,106,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,108,108,108,252,252,108,108,108,108,108,108,252,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,109,109,109,107,107,107,109,107,109,107,109,109,109,109,107,107,107,107,109,107,107,107,109,107,109,107,107,107,107,107,107,107,107,107,107,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,105,105,111,105,105,111,111,111,111,111,111,111,111,111,110,110,111,110,110,110,109,109,109,109,110,110,110,110,110,110,110,110,111,111,111,111,110,110,110,110,110,110,110,110,110,110,110,110,111,110,110,110,109,109,110,110,110,110,111,111,109,111,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,110,109,109,109,110,109,110,109,109,109,109,109,110,110,110,110,110,110,110,110,111,111,111,111,111,110,111,111,111,111,110,109,111,110,110,110,110,110,110,110,111,110,110,110,111,111,111,110,111,111,111,111,111,111,111,111,111,111,111,111,109,109,110,110,111,111,111,111,111,111,110,110,110,110,109,109,110,111,111,110,110,110,110,110,111,110,110,110,111,110,109,111,111,111,111,110,111,111,111,111,111,109,109,109,110,109,108,108,108,108,108,107,108,107,107,107,106,106,106,106,107,107,106,104,104,104,104,104,104,109,109,109,110,110,110,110,110,110,110,110,111,110,111,109,109,109,110,110,110,110,110,110,111,111,104,104,106,108,108,107,107,107,107,107,107,107,106,106,107,106,106,106,106,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,108,108,252,108,252,108,252,108,252,108,252,108,252,108,252,107,252,107,252,252,252,107,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,109,109,107,107,107,107,107,109,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,109,107,109,107,109,109,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,105,105,105,105,105,111,111,111,110,111,111,111,110,111,111,110,110,111,110,111,111,110,110,109,109,110,109,110,109,110,110,111,110,111,111,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,109,110,109,110,110,111,110,111,111,111,110,109,109,109,109,110,109,109,109,109,109,109,109,110,109,109,109,110,109,110,109,110,109,109,109,110,109,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,111,111,110,111,111,109,109,111,111,111,110,110,110,111,110,111,110,109,110,111,110,111,110,111,110,111,110,111,111,111,110,111,111,111,111,109,109,110,110,111,111,111,110,111,111,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,109,109,111,110,111,110,111,110,111,110,111,109,110,108,108,108,108,108,108,108,108,107,108,107,108,107,106,106,107,110,110,110,110,110,109,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,109,109,109,110,109,110,110,111,110,111,110,111,111,104,104,106,107,108,107,108,107,107,107,107,106,107,107,107,106,106,106,106,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,108,108,108,252,252,252,108,108,108,108,108,108,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,109,107,107,107,107,107,109,109,109,109,109,109,107,107,109,109,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,107,109,109,109,109,109,110,110,110,110,110,110,110,110,111,111,111,111,111,111,105,105,105,105,111,111,111,111,111,111,111,111,111,105,111,111,111,110,110,110,111,111,110,110,110,110,109,109,110,110,111,111,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,109,109,109,110,110,110,110,111,111,111,111,111,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,110,109,110,110,110,110,110,109,110,111,111,110,111,111,111,111,111,109,110,110,110,111,111,110,110,110,110,110,110,109,110,110,111,111,111,110,111,111,111,111,111,111,111,111,111,111,111,111,109,110,110,111,111,111,111,111,111,111,111,111,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,109,111,110,111,110,111,110,111,111,111,111,109,109,109,108,108,108,108,108,108,108,108,108,108,108,108,110,110,110,110,110,109,109,109,109,109,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,109,109,109,109,110,109,110,110,110,110,111,110,111,111,111,111,104,106,106,107,108,107,107,107,107,107,107,106,107,106,107,106,106,106,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,252,252,252,252,252,252,252,108,108,108,252,108,252,108,252,108,252,107,252,107,252,107,252,107,252,252,252,107,252,252,252,252,252,252,252,252,252,252,252,252,107,107,109,107,107,107,109,107,109,107,109,107,109,109,109,107,109,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,109,107,109,107,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,105,105,105,111,105,111,110,111,110,111,111,111,111,111,111,111,111,111,109,110,110,111,111,110,109,110,109,110,109,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,110,111,110,111,109,110,109,110,110,111,111,111,109,110,110,111,109,109,109,109,109,110,109,110,109,110,109,109,109,110,109,110,109,110,109,109,109,109,109,110,109,110,109,110,109,110,109,110,110,111,110,111,111,111,110,111,110,111,110,109,109,110,109,111,110,111,111,110,110,111,110,111,109,110,109,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,111,110,111,110,111,110,111,111,111,110,111,110,110,110,110,110,110,110,111,110,111,110,111,110,109,109,110,110,111,110,111,110,111,110,111,110,111,110,109,109,108,108,108,108,108,108,108,108,108,108,111,111,110,110,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,104,111,104,107,106,106,107,108,107,108,107,107,107,107,106,107,106,107,106,107,106,223,222,223,222,223,222,104,104,104,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,108,108,107,107,107,252,107,107,107,252,107,252,107,252,252,252,107,252,252,252,252,252,252,252,252,252,107,252,107,109,107,107,107,109,107,109,107,109,109,109,109,107,107,107,109,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,107,107,109,109,110,109,110,110,110,110,110,110,111,111,111,111,105,105,105,111,111,111,111,111,111,111,111,111,111,105,111,105,111,111,110,109,110,110,111,111,110,110,110,109,110,110,110,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,109,109,110,110,111,111,110,109,110,110,111,111,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,110,110,110,110,111,110,111,111,111,111,110,110,111,111,111,109,109,109,110,110,110,110,111,111,110,110,110,110,110,110,109,109,110,110,111,110,111,111,111,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,109,111,109,111,111,110,110,110,110,110,110,110,110,110,110,111,110,109,110,111,110,110,110,111,111,111,110,111,111,111,110,109,108,108,108,108,108,108,108,108,111,111,111,111,110,111,109,109,109,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,109,109,109,109,109,109,110,110,110,110,110,110,110,110,111,111,111,111,104,106,106,106,106,107,107,107,107,107,107,107,107,107,107,106,106,106,106,106,223,222,104,104,104,104,104,104,104,104,104,104,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,252,107,107,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,252,252,107,252,107,107,107,109,107,109,107,109,109,109,109,109,107,109,107,109,109,109,107,107,107,109,107,109,107,109,107,107,107,109,107,107,107,109,107,109,109,110,109,110,110,111,110,111,110,111,111,105,105,105,105,105,105,111,105,111,111,111,110,105,105,111,111,111,111,109,109,111,111,110,109,110,109,110,109,110,109,110,109,109,109,110,109,110,109,110,109,111,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,109,110,109,110,110,111,111,109,109,110,109,110,110,111,111,109,109,110,109,109,109,110,109,109,109,110,109,109,109,110,109,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,111,109,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,109,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,109,109,109,110,109,110,110,111,110,111,111,111,110,111,111,110,110,110,110,111,110,110,110,111,110,109,109,111,110,111,110,111,110,111,110,109,110,111,110,111,110,109,108,108,108,108,108,108,108,111,110,110,110,111,110,109,109,109,109,110,109,110,109,110,109,109,111,110,109,110,109,110,109,110,110,110,109,110,110,111,110,110,110,109,109,109,111,110,109,110,109,110,109,110,110,111,110,111,110,111,110,106,108,104,106,106,106,106,107,108,107,108,107,107,107,107,106,107,106,107,106,106,106,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,108,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,107,107,107,107,107,107,107,107,107,252,107,252,107,252,107,252,107,252,252,252,252,252,252,252,252,252,107,252,107,107,107,107,107,109,109,109,109,109,107,107,107,109,109,109,109,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,107,109,109,109,110,110,110,110,111,111,111,105,105,105,111,111,111,111,111,111,111,111,111,111,111,111,109,110,111,111,109,111,110,109,110,109,110,110,110,109,110,110,110,110,110,109,109,109,109,109,110,109,110,110,111,110,110,110,110,110,110,110,111,110,111,111,111,109,109,109,110,110,110,110,111,111,109,109,110,110,110,110,111,111,111,109,109,109,109,109,110,110,110,109,109,109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,110,110,111,111,111,111,111,110,111,110,109,109,109,109,110,110,110,110,111,110,111,111,111,110,109,111,110,110,110,110,111,110,111,110,111,110,111,110,111,111,111,111,111,111,111,109,109,109,110,110,110,110,110,110,111,111,111,111,111,111,110,110,110,110,110,110,110,110,110,109,110,110,111,110,111,110,110,110,111,109,110,111,111,111,111,110,109,109,108,108,108,108,108,108,110,110,110,110,110,110,109,109,109,109,109,109,109,109,109,109,110,110,111,111,110,110,110,110,110,110,110,110,110,110,110,110,110,110,109,110,111,111,109,109,110,110,110,110,110,110,110,110,110,110,111,110,106,107,104,104,106,106,106,106,106,107,107,107,107,107,107,107,106,107,107,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,107,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,107,107,109,107,109,107,109,107,109,109,107,107,109,107,109,107,109,109,109,107,109,107,109,107,109,107,107,107,107,107,109,107,109,107,252,109,110,109,110,110,111,111,105,105,105,110,111,110,111,109,111,110,111,111,111,111,109,109,110,109,110,110,111,111,110,109,110,109,110,109,110,109,110,109,110,109,110,109,109,109,110,109,110,109,109,109,110,110,111,110,111,110,111,110,111,110,109,109,110,109,110,110,111,110,111,110,111,111,109,109,110,109,110,110,111,110,111,110,109,109,110,109,110,109,110,110,110,109,109,109,109,109,109,109,110,109,110,109,110,110,110,110,111,110,111,110,111,111,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,111,111,109,110,111,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,109,110,109,110,110,110,110,111,110,111,111,111,111,111,111,110,110,110,110,110,110,110,110,109,109,110,110,111,111,111,110,111,110,109,109,110,110,109,109,111,111,109,109,110,108,108,108,108,108,108,110,110,110,111,110,109,109,109,109,110,109,110,109,109,109,110,110,111,110,111,109,110,109,110,109,110,109,110,110,110,110,109,109,110,110,111,111,110,109,110,109,110,109,110,110,110,110,111,110,111,110,106,107,109,104,107,106,107,106,106,106,106,107,108,107,108,107,106,106,107,106,107,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,106,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,108,252,108,252,252,252,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,107,107,107,107,107,107,252,107,107,107,252,107,107,107,252,252,252,107,252,252,252,252,252,252,109,107,109,107,107,107,109,107,109,107,109,109,109,109,107,107,107,107,109,109,109,107,107,107,109,107,109,107,109,107,107,107,107,107,107,107,107,252,109,109,110,110,111,105,105,105,111,111,109,109,110,110,111,111,111,105,111,109,109,109,110,109,110,110,110,110,111,111,111,111,110,110,110,109,110,110,110,110,110,110,110,109,109,109,109,109,110,109,110,110,111,111,109,109,110,109,110,110,110,110,110,110,111,110,111,110,111,111,111,110,109,109,109,109,110,110,110,110,111,111,109,109,110,109,110,110,109,109,109,109,110,110,109,109,109,109,109,109,110,110,110,110,110,110,110,110,111,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,111,111,111,111,109,109,110,110,111,110,110,110,111,110,110,110,111,110,111,110,111,111,111,109,110,110,111,111,109,109,110,110,111,111,111,110,111,111,111,111,110,110,110,110,110,110,110,110,110,110,110,109,111,110,110,110,111,110,110,110,109,109,110,109,110,110,110,110,111,111,109,109,108,108,108,108,110,110,110,110,110,110,109,111,109,109,109,109,109,109,109,109,110,110,110,110,111,110,110,109,110,110,110,110,110,110,110,109,110,110,110,110,111,111,109,109,110,109,110,109,110,110,110,110,110,110,110,110,111,106,108,104,107,107,106,106,106,106,106,106,106,107,107,107,107,107,106,106,107,107,107,106,107,107,106,106,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,106,106,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222,223,222,222,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,252,107,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,252,109,107,109,107,107,107,107,107,109,107,109,109,109,109,107,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,252,252,109,110,105,105,105,111,111,109,110,109,110,110,111,111,111,105,111,109,109,110,111,109,110,110,110,110,111,110,111,110,111,111,111,109,110,109,110,109,110,110,110,109,109,109,110,109,110,110,111,110,111,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,109,111,110,109,109,110,109,110,109,110,110,111,109,109,109,110,109,109,109,109,109,110,109,110,109,110,109,109,109,110,109,110,109,110,110,110,110,111,110,109,109,110,109,110,109,110,109,109,110,111,110,110,110,111,110,111,110,111,110,109,109,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,109,110,109,110,110,111,110,111,111,109,110,111,110,111,110,111,111,111,111,110,110,110,109,110,110,111,110,110,110,111,110,110,110,111,110,111,110,111,110,111,109,109,109,110,109,110,110,111,110,111,111,110,108,108,108,110,110,110,110,109,109,111,111,109,109,110,109,110,109,110,109,109,109,111,111,110,109,110,109,110,110,110,109,110,110,109,109,110,110,111,110,111,111,110,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,106,109,107,106,107,106,107,106,107,106,106,106,106,107,108,107,108,107,107,107,106,106,106,106,107,107,106,106,104,104,104,104,104,104,104,104,104,104,106,104,104,104,104,104,104,106,106,106,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,109,108,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,252,252,252,107,107,107,107,107,107,107,252,107,107,107,252,107,252,107,252,252,252,252,252,252,109,109,109,107,109,107,107,107,109,107,109,109,109,107,109,107,107,107,109,107,109,109,109,109,109,107,109,107,109,107,109,107,107,107,107,107,107,107,107,107,252,105,105,105,105,111,111,109,109,110,110,110,111,111,111,105,111,111,109,110,111,111,110,109,110,110,110,110,110,110,111,110,111,111,111,111,110,110,110,110,110,110,110,109,109,109,110,110,111,111,111,110,109,109,109,109,110,110,110,110,110,109,109,109,110,110,110,110,111,111,111,109,109,109,110,110,110,110,110,110,109,109,110,109,109,109,109,109,109,109,110,109,110,109,109,109,109,109,110,110,110,110,110,110,110,110,109,109,109,109,110,110,110,110,111,111,111,111,110,110,111,110,111,111,111,109,109,110,110,110,111,111,110,110,110,110,110,110,111,110,111,110,111,109,109,109,110,110,110,110,111,111,110,110,110,110,110,110,111,109,110,110,111,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,109,109,109,110,109,110,110,110,110,111,111,111,111,110,109,110,110,109,109,110,110,111,111,109,109,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,109,109,109,110,110,111,111,109,109,109,109,109,109,110,109,110,110,110,110,110,110,110,110,110,110,110,109,107,107,107,107,107,106,106,106,107,107,106,106,106,107,107,107,107,107,107,107,107,106,106,106,107,107,106,106,104,104,104,104,104,104,104,104,106,104,104,104,104,104,104,104,106,106,106,106,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,252,108,252,252,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,109,107,109,107,109,107,107,107,109,107,109,109,109,107,109,107,107,107,109,107,109,107,109,107,109,109,109,107,109,107,109,107,109,107,107,107,109,107,109,107,252,107,252,105,111,111,111,109,110,109,110,110,111,110,111,111,111,110,111,110,111,110,111,109,110,109,110,110,111,110,111,110,111,110,111,111,110,109,110,109,110,109,110,110,110,109,109,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,111,110,109,110,109,110,109,110,110,109,109,109,109,110,109,110,109,110,109,110,109,110,109,109,109,109,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,110,111,111,111,110,111,110,111,109,110,109,110,110,111,110,111,111,111,110,111,110,111,110,111,110,111,110,111,109,110,109,110,110,111,110,111,109,110,109,110,109,110,110,111,110,111,110,111,111,110,109,110,110,110,110,110,110,111,110,110,110,111,109,110,109,110,109,110,110,109,109,110,109,110,109,110,110,111,110,111,111,110,109,108,109,110,109,110,110,111,111,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,110,110,111,111,111,110,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,109,107,107,107,106,107,106,106,106,107,106,107,106,106,106,106,107,108,107,108,107,107,106,106,106,107,106,107,106,106,106,104,106,104,104,104,104,104,104,106,107,104,106,104,104,104,106,107,106,106,106,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,108,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,252,252,252,107,107,107,107,107,107,107,107,107,252,107,252,107,252,252,252,107,252,107,107,107,109,109,109,107,109,107,109,109,109,107,109,107,109,107,107,107,107,107,107,107,109,109,109,109,109,109,109,107,109,107,109,107,107,107,107,107,107,107,107,107,252,252,111,111,111,111,109,109,110,110,110,110,111,111,105,111,110,110,110,110,111,111,110,110,110,110,110,110,111,111,111,111,111,111,110,110,110,110,110,109,109,109,109,109,110,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,111,109,109,109,110,109,110,110,110,109,109,109,109,109,109,109,109,109,110,109,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,110,110,109,109,109,109,110,110,110,110,111,111,111,110,111,110,110,110,111,110,110,110,111,111,111,110,109,110,111,109,109,109,109,109,110,110,110,110,111,111,111,111,111,111,111,110,110,110,110,110,110,110,110,110,110,110,109,109,109,109,110,109,110,110,109,109,110,110,110,110,110,110,111,110,111,111,110,109,108,108,109,109,110,110,111,111,109,109,109,109,109,109,109,109,110,109,110,109,110,110,110,109,110,110,110,110,110,110,109,109,111,111,110,110,109,109,109,109,109,109,109,109,110,110,110,109,110,110,110,110,110,110,110,109,107,107,107,107,107,107,107,106,106,106,107,107,107,106,106,106,106,107,107,107,107,107,107,107,106,107,106,107,107,106,106,104,106,108,104,104,104,104,104,104,106,107,108,104,104,106,107,106,107,106,106,106,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,252,108,252,108,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,107,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,109,109,107,109,107,109,107,109,107,107,107,107,107,252,107,252,107,252,252,111,110,111,109,110,110,111,110,111,111,111,111,110,110,111,110,111,111,111,109,110,110,110,110,110,110,111,110,111,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,110,110,111,110,110,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,109,110,109,110,110,111,109,109,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,111,111,110,109,109,110,109,110,110,111,110,111,111,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,109,109,109,109,110,109,110,110,110,110,111,110,111,110,111,111,111,111,110,110,110,110,110,110,111,110,110,110,109,109,110,109,110,109,110,110,109,109,110,109,110,109,110,110,111,110,111,109,110,109,108,108,110,109,110,110,111,111,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,110,110,109,110,111,110,111,110,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,109,110,110,111,109,108,107,108,107,107,107,107,106,107,106,107,106,107,107,107,106,106,106,106,107,108,107,108,107,107,107,107,106,107,106,106,106,104,106,104,104,104,104,104,104,104,106,107,108,104,104,108,107,107,106,107,106,106,106,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,108,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,108,252,252,252,252,107,107,107,107,107,107,107,107,107,107,252,107,252,107,252,252,252,107,107,107,109,109,109,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,109,107,109,109,109,109,109,109,109,107,109,107,109,107,107,107,107,107,107,107,107,107,252,111,111,111,109,109,110,110,111,111,111,110,110,110,110,110,111,111,111,111,109,109,110,110,109,109,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,111,111,111,111,111,111,111,110,110,110,110,110,109,109,109,109,109,109,109,109,109,109,109,109,109,110,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,109,111,110,111,111,111,111,111,111,109,109,109,109,110,110,110,110,111,111,111,111,110,110,110,110,111,110,111,110,111,110,111,110,111,111,109,109,109,109,109,109,110,110,110,110,110,110,111,111,111,111,111,111,111,111,110,110,110,110,110,110,110,110,109,109,109,109,110,109,110,110,110,110,109,109,110,110,111,111,111,111,111,109,109,109,110,109,109,110,110,110,111,111,109,109,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,109,111,110,110,110,110,110,110,110,110,110,111,109,109,109,109,109,109,109,110,109,110,109,110,110,110,110,110,110,110,109,108,107,107,107,107,107,107,107,107,107,107,106,106,106,107,107,106,106,106,106,106,107,107,107,107,107,107,106,107,107,106,106,106,104,104,104,104,104,104,104,104,104,106,107,104,104,108,107,107,107,106,107,107,106,106,106,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,222,223,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,108,252,108,252,107,252,252,107,107,252,107,252,107,252,107,252,107,252,107,252,107,252,107,107,107,109,107,109,107,109,107,109,107,109,107,107,109,109,107,109,107,107,107,109,107,109,107,109,107,109,107,109,109,109,109,109,107,109,107,109,107,107,107,107,107,252,107,252,252,111,109,111,110,109,110,111,111,111,111,110,110,111,110,111,110,111,111,111,109,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,109,111,111,111,110,110,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,109,109,110,110,111,110,111,110,111,110,111,111,111,109,110,109,110,109,110,110,111,110,111,111,111,110,111,110,111,110,111,110,109,111,111,110,111,110,111,109,109,109,110,109,110,109,110,110,111,110,111,110,111,111,111,110,111,111,111,110,110,110,110,110,110,110,111,109,109,109,110,109,110,109,110,109,110,110,109,110,111,110,111,110,109,109,108,108,111,109,110,109,110,110,111,111,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,111,110,110,110,110,111,110,111,110,111,110,109,109,109,109,110,109,110,109,110,109,110,109,110,110,110,110,109,109,108,107,108,107,108,107,108,107,107,107,107,106,107,106,107,106,107,106,107,106,106,106,106,107,108,107,108,107,107,106,107,106,106,106,104,104,104,104,104,104,104,104,106,107,104,104,108,107,108,107,108,106,107,107,107,106,106,106,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223,222,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,108,109,108,109,108,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,108,252,252,252,252,252,107,107,107,107,107,107,107,252,107,107,107,252,107,252,107,252,107,107,107,109,109,109,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,109,107,109,107,109,109,109,109,109,107,109,107,109,107,107,107,107,107,107,107,252,107,252,111,111,111,109,109,109,111,111,111,110,110,110,110,111,111,109,109,109,109,109,109,109,109,109,109,110,109,109,109,110,110,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,111,111,110,109,109,110,110,111,111,111,111,111,110,110,109,109,109,109,109,109,109,109,109,110,109,109,109,110,109,110,109,110,109,109,109,110,110,110,110,110,110,109,109,110,110,110,110,111,110,111,110,111,111,111,111,111,109,109,109,110,110,110,110,110,110,111,111,111,110,110,110,111,110,110,109,110,110,110,110,111,111,111,109,109,109,109,109,110,110,110,110,110,110,111,111,111,111,110,110,111,111,111,111,111,110,110,110,110,110,110,110,109,109,109,109,110,109,110,110,110,110,110,110,110,110,110,110,108,108,108,108,111,110,109,109,110,110,111,111,110,109,109,109,109,109,109,109,109,109,109,109,110,110,110,109,110,109,110,111,110,110,110,110,110,110,110,110,111,110,110,109,109,109,109,109,111,109,110,109,110,110,110,110,110,106,110,108,108,108,108,107,108,107,107,107,107,107,107,107,107,107,107,106,107,106,106,106,106,106,106,106,106,108,107,107,107,107,106,106,106,106,104,104,104,104,104,104,104,104,104,106,108,104,108,108,108,108,107,107,107,106,107,107,107,106,106,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,223,223,223,223,222,223,223,223,222,223,223,223,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,108,109,252,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,252,252,107,107,107,107,252,107,252,107,252,107,252,107,252,107,252,107,107,107,109,107,109,107,109,107,109,107,109,107,109,107,107,107,109,107,107,107,109,107,109,107,109,107,109,109,109,109,109,107,109,107,109,107,109,107,107,107,252,107,107,107,252,107,252,111,111,109,110,110,111,110,110,110,111,110,109,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,110,110,111,110,111,110,111,109,109,109,110,109,110,109,110,110,110,110,111,110,111,110,111,111,111,111,110,109,109,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,111,110,111,110,111,111,109,109,110,109,110,110,111,110,111,110,111,110,111,110,111,109,110,109,110,110,111,110,111,111,111,109,109,109,110,109,109,109,110,109,110,110,111,110,111,111,111,110,111,110,111,110,111,111,110,110,110,110,111,110,109,109,109,109,110,110,111,109,110,110,110,110,110,110,111,108,108,108,108,111,111,109,109,109,110,110,111,111,110,110,109,109,109,109,110,109,110,111,110,109,110,109,110,109,110,110,109,110,111,110,110,110,110,110,111,110,111,110,111,109,110,110,111,109,110,110,111,109,110,110,110,106,108,108,110,108,108,108,108,107,108,107,108,107,108,107,108,106,108,107,107,106,107,106,107,106,107,106,107,106,106,106,106,107,108,107,108,106,106,106,106,106,104,104,104,104,104,104,104,104,104,108,104,108,108,108,108,107,108,107,106,106,107,107,107,106,106,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,223,223,222,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,108,109,108,109,108,109,108,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,252,252,107,107,107,107,107,107,107,107,107,107,107,107,252,107,109,107,107,107,109,109,109,107,109,107,109,107,109,107,109,107,109,107,107,107,107,107,107,107,109,107,109,109,109,109,109,109,109,107,109,107,109,107,109,107,107,107,107,107,107,107,252,107,111,111,111,111,111,111,111,110,110,110,109,109,109,109,109,109,109,109,109,109,109,109,110,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,109,109,109,109,109,110,110,110,110,110,110,110,110,111,111,111,111,111,111,109,109,109,109,109,110,111,109,109,109,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,109,109,110,110,110,110,111,110,111,111,110,110,111,110,111,111,111,111,109,109,109,109,110,110,110,110,111,110,111,111,110,110,110,109,109,109,110,110,110,110,110,110,111,111,111,111,109,109,110,109,109,109,110,110,110,110,111,111,110,110,111,111,111,111,111,111,110,110,110,110,110,110,109,109,110,110,111,109,110,110,110,110,110,110,110,110,111,108,108,108,108,108,111,109,110,109,110,110,111,111,110,110,110,110,109,109,109,109,110,111,109,109,110,109,110,109,110,110,110,110,109,111,110,110,110,110,110,110,111,110,111,109,110,110,111,109,110,110,110,110,111,110,106,107,108,109,110,108,108,108,108,108,108,108,108,107,108,107,107,106,107,107,108,107,107,107,107,106,107,106,106,106,106,106,106,106,106,107,108,107,107,106,104,106,104,104,104,104,104,104,104,104,108,108,104,108,108,108,108,108,108,108,108,107,106,106,107,107,106,106,106,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,252,107,252,107,252,107,252,107,252,107,107,107,109,107,109,107,109,107,109,107,109,107,109,107,107,109,109,107,107,107,109,107,109,107,109,107,109,107,109,109,109,109,109,107,109,107,109,107,107,107,107,107,252,107,252,107,252,107,111,110,111,110,111,110,110,110,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,110,110,111,110,111,110,111,109,109,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,109,109,109,109,109,109,110,110,111,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,109,109,110,109,110,109,110,110,111,110,111,111,111,110,111,110,111,110,111,110,109,109,110,109,110,110,110,110,111,110,111,111,111,110,111,110,109,109,110,109,110,109,110,110,111,110,111,110,111,111,110,109,110,109,109,109,110,110,111,110,111,110,111,110,111,110,111,111,110,110,110,110,110,109,110,110,111,109,109,109,110,109,110,109,110,110,110,110,108,108,108,108,108,108,111,109,110,109,110,110,111,111,111,110,111,110,109,109,110,111,111,111,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,109,109,110,110,111,109,110,109,110,110,111,106,107,107,109,109,110,108,108,108,108,108,108,107,108,107,108,107,108,107,106,106,107,107,108,107,107,106,106,108,106,106,107,106,106,106,106,106,106,107,108,107,106,107,104,104,104,104,104,104,104,104,108,108,104,108,108,108,108,108,108,108,108,107,106,106,108,106,107,107,107,106,106,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,223,223,222,223,222,223,222,223,222,223,222,223,223,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,108,109,108,109,252,109,109,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,107,107,107,252,107,107,107,109,109,109,107,109,107,109,107,107,107,107,107,109,109,107,107,107,107,107,107,109,107,109,107,109,109,109,109,109,107,109,107,109,107,252,107,107,107,107,107,107,107,107,107,252,107,252,110,111,111,110,110,109,109,109,109,109,109,109,109,110,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,110,110,110,111,111,111,110,109,109,109,109,110,110,110,110,110,110,110,110,111,111,111,111,109,109,109,109,110,110,111,111,109,109,109,109,109,109,109,109,110,109,109,109,110,109,110,109,110,109,109,109,110,110,110,110,110,110,111,110,111,111,110,110,111,110,111,110,111,111,111,109,109,109,110,110,110,110,110,110,111,111,111,110,110,110,110,110,109,109,109,109,110,110,110,110,111,111,111,109,110,109,110,109,110,110,110,110,110,110,110,110,111,111,111,111,111,111,110,110,110,110,109,110,111,110,110,110,109,109,109,109,110,110,110,110,110,110,108,108,108,108,111,111,110,109,110,110,109,110,111,110,111,110,111,110,109,109,110,110,111,109,109,109,110,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,111,109,109,109,110,110,111,111,109,109,110,110,110,106,107,107,108,109,109,110,108,108,108,108,108,108,108,108,108,108,108,107,108,106,106,107,107,108,108,107,106,107,107,108,106,106,106,106,106,106,106,106,106,108,106,108,104,104,104,104,104,104,108,104,104,104,107,108,108,108,108,108,108,106,108,108,108,107,106,106,107,107,106,107,108,108,106,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,252,109,109,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,252,107,252,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,109,109,109,107,107,107,109,107,109,107,109,107,109,107,109,107,109,109,109,107,109,107,252,107,252,107,252,107,107,107,252,107,252,107,252,252,252,111,111,110,110,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,109,110,109,110,109,110,109,110,110,111,110,111,110,111,110,109,109,109,109,110,110,111,109,110,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,109,109,110,109,110,109,110,110,111,110,111,110,111,111,111,110,111,110,111,110,111,110,111,110,109,109,110,109,110,110,111,110,111,111,111,111,111,110,111,110,111,110,109,109,110,109,110,110,111,111,111,109,110,109,110,109,110,110,110,110,110,110,111,110,111,110,111,110,111,111,110,110,110,109,110,110,111,110,111,110,111,110,109,109,110,109,110,109,110,110,108,108,108,111,111,109,110,109,110,109,110,110,109,110,111,110,111,109,110,110,111,111,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,111,110,111,109,110,109,110,110,111,111,111,109,110,109,106,106,107,107,108,108,109,109,110,108,108,108,108,108,108,107,108,107,108,107,108,107,108,106,107,107,108,108,107,106,107,107,108,108,107,106,107,106,107,106,106,106,106,104,104,104,104,104,104,106,104,104,104,104,107,108,108,108,108,108,108,108,106,107,108,107,108,107,106,106,107,106,107,107,108,108,106,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223,223,223,222,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,109,108,109,108,109,109,109,109,109,109,109,108,109,108,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,107,107,107,107,107,107,109,107,109,109,109,107,109,107,107,107,109,109,109,109,107,107,107,107,107,107,109,107,109,109,109,109,109,109,109,107,109,107,252,107,252,107,107,107,107,107,107,107,107,107,252,107,252,252,252,111,110,109,109,109,109,109,109,109,109,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,110,111,110,111,110,111,111,111,111,111,111,111,111,111,109,109,109,110,109,110,110,110,110,111,110,111,111,111,109,109,109,110,110,111,109,109,109,109,109,110,109,109,109,109,109,109,109,109,109,110,109,110,109,110,109,110,110,110,110,110,110,111,111,111,111,110,110,110,110,111,110,111,111,111,111,111,109,109,109,110,110,110,110,111,111,111,111,111,110,110,110,111,110,111,110,109,109,110,110,110,110,111,111,109,109,110,109,110,110,110,110,110,110,110,110,111,111,111,111,111,111,110,110,110,110,109,110,111,110,110,110,110,110,110,110,109,109,110,110,110,110,108,108,111,111,109,109,109,109,110,110,110,110,110,110,111,111,109,109,110,110,111,109,109,109,109,109,109,109,109,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,109,109,110,110,111,111,111,111,109,109,106,106,107,107,108,108,109,109,110,110,108,108,108,108,108,108,108,108,108,108,108,108,108,107,106,106,107,107,108,108,106,106,107,107,108,108,107,106,106,106,106,106,106,106,106,104,104,104,104,108,104,104,104,104,107,108,108,108,108,108,108,108,108,108,106,108,108,108,108,106,106,106,107,107,108,108,108,106,106,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223 +,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,109,109,108,109,108,109,252,109,252,109,252,109,252,109,252,109,252,109,252,109,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,107,107,107,252,107,252,107,107,107,109,107,109,107,109,107,109,107,107,107,109,107,109,107,109,107,109,107,109,107,109,107,109,107,109,109,109,109,109,107,252,107,252,107,109,107,107,107,252,107,252,107,252,107,252,107,252,252,252,110,109,109,109,109,110,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,111,110,111,110,111,110,111,110,111,110,111,110,111,110,111,111,111,111,111,110,111,252,109,109,110,109,110,109,110,110,111,110,111,110,111,109,109,109,109,109,110,109,110,109,110,109,110,109,110,109,109,109,110,109,110,109,110,109,110,109,110,109,110,110,110,110,110,110,110,111,111,111,111,110,110,110,110,111,110,111,111,111,111,111,109,109,109,110,110,110,110,111,111,111,111,111,110,110,110,111,110,111,110,109,109,110,110,110,110,111,111,109,109,110,109,110,110,110,110,110,110,110,110,111,111,111,111,111,111,110,110,110,110,109,110,111,110,110,110,110,110,110,110,109,109,110,110,110,110,108,108,111,111,109,109,109,109,110,110,110,110,110,110,111,111,109,109,110,110,111,109,109,109,109,109,109,109,109,109,110,109,110,110,110,110,110,110,110,110,110,110,110,110,109,109,110,110,111,111,111,111,109,109,106,106,107,107,108,108,109,109,110,110,108,108,108,108,108,108,108,108,108,108,108,108,108,107,106,106,107,107,108,108,106,106,107,107,108,108,107,106,106,106,106,106,106,106,106,104,104,104,104,108,104,104,104,104,107,108,108,108,108,108,108,108,108,108,106,108,108,108,108,106,106,106,107,107,108,108,108,106,106,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223]} +); diff --git a/apps/animclk/animclk.pal b/apps/animclk/animclk.pal new file mode 100644 index 0000000000000000000000000000000000000000..d33bfcdb9524e027f6819cc62f6e853f28eb03bd GIT binary patch literal 512 zcmZQz*nfZi`S|tr^Z&Q~kJ}%&->zQIp6$Qre%^XnIo-WFF*d)gXFA7Ei%z}h9DH=^ zw%z;wZi`<(XWq@$l4+&Kf{$*C*%o6QveDV!TF?5N6rZ-g^+o54&Yyr#$VJ%2*vD#~ zzO*-!784g3YBQbX(wDwyEMybxvn8aw)^gc@ASiFWnqyWvqt|lT?tM`}EPLMe`ksCB zp4(oZ_dI&r&!s!&miL;qey!P3a<$}ZjaaQ&Yk2R?xzXG19;?4U)koN7qjrGwMr~o6 zsXpSVokbt6EDL;WkSL&D^ltU!rvb&mb3S#O@BP#rPzif=jThCtHBJqFPH<4$P?h0J( ZKf=3b&1QpakQszs>05:>%&)),0235699<=?ssstststssssstststtuuuuuœœœœ›—›œ›››—œÇÇÇÁœœ›œœœ›œœ›œœœ›œ›››œ››ÊÊÊËÊËËÌÊÇÀÁÀÁÀÁÀÁÁÁÁÀÀÀÁÂÁÂÀÀÀÁÀÁÁÂÂÂÁÀÀÁÀÁÀÁÀÂÂÂÂÀÀÁÀÁÀÁÁÁÁÂÂÂÂÃÃÃÃÃÂÂÀÀÁÀÀÀÁÀÁÁÁÁÂÃÂÃÂÀÀÃÁÃÂÃÁÄÀÅÀÅÁÅÀÅÁÅÁÅÂÆÂÆÀÅÁÅÁÅÁÅÁÅÁÅÂÁÂÂ"#%&'()*,-./ "#%'(*,-/ !!"##$%&&''()**+,,-.02478;=?œœ›œœœ————œ››—ÀÇÁÅÁÆœœ›œœ›œ›œ››œœœœœ›››œ›››ËÊËÊËËÌÊÇÀÄÀÁÀÄÀÁÀÁÁÀÀÀÁÂÁÁÁÁÀÁÁÁÀÁÂÂÂÀÀÁÀÁÀÁÁÄÁÂÂÅÀÁÀÁÀÁÁÅÁÂÁÂÂÃÃÃÃÅÂÁÀÀÁÀÁÀÀÀÁÁÁÁÂÆÂÃÂÀÀÁÁÁÁÃÂÅÄÁÁÁÁÀÁÁÁÁÁÁÂÂÁÂÀÀÁÁÁÁÁÁÁÁÁÂÂÁÂÆÂ$%( "#%&()+,./--.././œœœœœ›œ›œ››——››—ÇÁÄÁÁÆÆÆÆœœ›œ›››œœ››œ›œœ›œ›œ›››œ›ËÊËÊËËÌÊÇÀÄÀÄÁÁÄÄÁÂÁÂÀÁÁÂÀÁÀÁÀÁÀÁÁÁÁÂÂÃÀÀÀÁÀÁÁÂÂÂÂÂÀÀÀÀÁÁÁÁÁÁÁÂÂÂÃÃÃÆÂÁÀÀÁÀÁÀÀÀÁÀÁÁÂÆÂÃÂÀÀÁÀÁÁÃÂÃÃÄÁÅÀÅÁÄÀÅÁÅÂÆÂÆÁÆÀÅÁÅÁÅÁÅÁÅÁÆÂÆÂÂ)*+,-./++--./œœœœœœœ››œœ››œ›››››——››››ÇÄÁÄÁÁÆÆÆœœœœœ›››œ››œœ››œœœœœœ››››››ÊËÊËËÌÊÇÀÄÀÄÁÄÁÄÁÁÂÂÀÁÁÂÂÁÀÁÀÁÁÁÁÂÂÂÂÂÀÀÀÁÀÁÁÄÂÅÁÄÁÀÀÁÀÁÁÅÁÅÁÅÁÂÃÃÃÆÆÁÂÀÁÁÂÂÀÀÁÁÁÁÁÆÆÅÂÀÀÀÀÁÁÁÂÃÂÄÄÅÁÁÁÄÁÁÁÅÂÂÂÆÂÂÀÅÀÁÁÅÁÁÁÅÂÂÂÂÂÂÂ-../ &%&&'&'(œœœœœœœ›œ›œœœ›››››››››››———ÀÄÁÄÅÁÁÆÆÆÆœ›œ›œ›œ›œ›œ›œ›œœ›œ›œ›››››ËËËÊËËËÇÄÁÄÁÄÄÄÄÁÁÂÁÁÁÂÂÀÀÁÄÁÁÁÁÂÁÂÂÃÀÀÀÁÀÁÁÁÂÅÁÄÂÀÀÀÀÁÁÁÁÅÁÁÁÂÂÃÃÆÃÁÁÀÁÀÁÁÂÀÁÀÁÁÁÂÂÁÂÀÀÁÀÁÁÃÁÃÂÅÄÄÁÅÁÄÁÅÁÅÂÆÂÆÂÆÁÅÁÅÁÅÁÅÁÅÁÅÁÆÂÆÂÆ,- "$%()+- !"#%&'()//5689;<>?0134679:<=?024:<=?02467ÇÁÄÁÁÁÅÆÆÅÆÆ›››››››››››››œœœœ››››››››ÊËÊËËËÇÄÁÄÄÄÅÄÄÅÅÂÂÁÁÁÁÄÀÁÄÁÁÁÁÁÁÂÃÃÁÀÀÁÀÁÁÄÄÅÂÅÄÁÂÀÁÁÁÀÁÅÁÅÁÄÂÃÂÆÃÅÁÁÀÀÀÀÁÀÁÁÁÁÁÂÂÆÂÀÀÁÀÁÁÁÁÃÃÅÅÄÄÄÁÄÁÁÁÅÁÅÂÆÂÂÂÅÁÅÀÅÁÁÁÅÁÅÁÆÂÆÂÆÂ/ "#&'*+- #%(*-/>?014589<=?02367:;=?014589<=?ÇÄÁÄÁÅÅÆÅÆÅÆÆœ›››››œœœ›››œ››››››››››ËËËËËËÄÀÄÄÄÄÄÄÄÅÄÁÅÂÂÁÁÀÀÁÄÁÄÁÁÂÁÂÂÃÃÀÀÁÀÁÁÅÁÄÂÅÄÄÂÀÁÀÁÂÂÄÁÅÁÅÂÂÂÃÃÅÁÁÀÁÁÀÁÁÁÁÁÁÂÂÂÆÂÁÂÁÀÁÁÃÁÃÂÃÂÅÄÅÁÅÁÅÁÆÁÄÂÅÂÆÂÆÁÅÁÅÁÅÁÅÁÅÁÆÁÆÂÆÂÆ)*+,--// !"#$%& !"#$%&()*,-./::;;<<==>>??ÄÄÄÄÅÅÅÅÆÆÆÆÆÆKKLMNNO5556œœ›œ›››››››ËÊËËËÄÀÄÄÄÄÄÆÆÁÁÁÁÆÂÂÅÀÄÁÄÁÄÁÁÁÁÂÃÃÃÀÀÁÀÁÁÅÁÄÁÄÁÄÁÀÁÂÁÄÁÅÁÅÁÂÁÂÃÃÆÆÁÁÀÁÀÀÁÁÁÁÁÁÆÁÆÆÂÁÀÀÂÁÁÁÁÃÃÃÂÅÄÄÁÅÁÅÁÅÁÅÂÆÂÆÂÅÂÅÁÅÁÅÁÅÁÄÁÅÂÆÂÆÂÆÂ!"##%%&&''((**++,,--// !##%%'(**,,./?02367:;>>;ÇÄÄÄÄÅÅÆÅÆÅÆÆÆÆÆEGGHIJJLLNNO45465767ËËËËÄÇÄÄÄÄÄÄÅÆÆÅÁÆÅÂÂÄÄÁÄÁÄÁÄÂÁÂÁÃÃÄÀÁÁÁÁÅÁÄÄÄÂÄÄÅÁÅÁÄÁÅÅÅÁÅÂÂÂÂÃÆÅÁÀÁÁÁÁÁÁÁÁÁÆÂÆÆÂÁÂÄÂÁÄÁÅÃÁÃÂÅÄÄÁÅÁÅÁÅÁÆÁÆÂÆÂÆÂÅÁÅÁÅÁÅÁÅÁÅÁÆÁÆÂÆ "$&)*-/!!""##$$%%&&''(()**++,,-..// !#$%&()*+-./566ÄÄÄÄÅÅÅÅÆÆÆÆÆÆÆÆÆ>??@ACDEFHIJKMNO344ËËËËÇÄÄÄÄÄÅÁÁÁÆÆÁÅÃÆÂÄÄÄÄÄÁÄÁÅÂÃÃÃÃÀÁÄÁÄÁÁÅÁÆÂÅÄÅÁÅÁÄÁÅÂÅÁÂÁÂÂÃÃÆÅÁÄÁÁÁÁÁÁÁÁÁÆÂÆÆÆÆÁÁÄÀÄÁÅÁÁÃÃÄÄÄÁÅÁÅÁÅÁÅÁÆÁÆÂÆÂÅÂÅÁÅÁÅÁÄÁÅÁÅÁÆÂÆÂÆ !!""##$$%%&&''(())**++,,--..//001122ÄÄÄÄÅÄÅÅÆÅÆÆÆÆÆÆÆÆÆ<ÇÀÄ>?@AACCEEGÇÄHËËËËÇÄÄÄÄÄÁÁÆÅÆÅÆÅÃÅÆÂÄÄÄÄÁÄÂÅÂÅÃÃÃÀÁÄÁÁÁÁÅÅÄÂÆÄÄÁÅÅÄÁÅÂÅÁÅÅÂÂÃÃÆÆÂÅÄÅÁÅÁÅÁÅÁÆÂÆÆÂÆÆÁÂÁÄÁÅÁÅÃÅÃÄÅÁÅÁÅÁÅÁÅÁÆÁÆÂÆÂÆÁÅÁÅÁÅÁÅÁÅÁÆÁÆÁÆÂÆÆÆ . "%'*,/ !!""##$$%%&&''(())**++,,--../0111ÄÄÄÄÄÅÅÅÅÆÅÆÆÅÆÆÆÆÆÀÄÄÅÅ=>??@ABBÇÄÄÄÄÄÄÄÄÄÄÆÆÅÁÁÅÆÆÆÆÆÅÃÃÄÄÄÄÅÅÅÅÃÃÃÅÃÃÁÄÁÄÁÄÁÁÄÁÅÆÄÄÅÁÄÁÅÁÅÅÅÁÆÂÃÃÂÃÂÅÄÄÁÅÁÅÁÅÅÅÂÆÂÅÆÆÆÁÄÄÁÅÅÅÃÃÃÄÄÁÅÄÅÁÅÅÅÁÅÅÅÁÆÆÆÂÅÅÅÁÅÄÄÁÅÅÅÁÆÆÆÂÆÆÂÆ !"#$%&'()*+,-./ !!""##$$%%&&''(())**++,,--..//001ÄÄÄÄÄÅÅÅÄÅÅÆÅÆÅÆÆÆÄÄÄÅÅÆ<>=>>ÇÇÄÀÆÅÆÆÄÄÄÅÄÅÆÁÆÁÆÅÆÆÅÅÃÅÃÄÅÄÅÄÂÄÂÅÃÅÃÃÁÄÁÄÁÄÁÁÄÁÅÅÆÄÅÅÅÁÄÄÅÂÅÅÅÂÆÆÆÃÃÅÂÅÄÅÁÅÁÅÁÆÂÆÂÆÆÅÆÂÅÄÁÄÅÅÆÅÃÅÄÁÅÁÅÁÅÁÅÁÅÁÆÂÆÂÆÂÆÂÅÁÅÁÅÁÅÁÅÁÆÁÆÁÆÆÂÆÆ,,,,,,, $'+/ !"#$%&'()*+,-./ !!!"""##$$%%%&&'''(())**+++,,,--..//0011ÄÄÄÄÅÄÄÅÅÆÅÅÆÆÆÅÆÆÅÄÄÄÅÅÆ<==ÇÀÄÀÅÅÅÅÆÆÆÆÄÅÆÆÆÅÅÅÆÆÆÅÃÅÃÃÂÅÆÆÅÅÅÅÃÅÃÃÃÄÁÄÁÁÁÄÁÄÅÂÆÄÅÄÅÁÄÁÅÂÅÅÆÂÆÂÆÃÃÃÅÄÁÅÄÅÁÅÅÅÂÆÆÆÆÆÆÆÆÅÄÄÁÅÅÆÆÅÄÄÄÄÄÄÅÅÅÅÅÅÅÅÆÅÆÄÆÆÆÅÅÄÄÄÅÅÅÅÅÅÆÆÆÂÆÆÆÂ--------- #(+/ ! ! !!"!""##$#$$%%&%'&''(')())**+*++,,-,--.././0101122ÄÄÄÄÄÄÅÅÆÆÆÅÆÆÆÅÆÆÅÄÅÅÆÅÆ<ÀÀÄÀÅÄÅÅÆÅÆÆÆÄÅÅÆÆÆÅÆÅÆÅÆÅÃÃÃÄÆÅÆÄÅÅÃÅÃÃÃÁÁÄÁÅÁÅÁÄÅÅÆÆÄÄÆÅÆÄÄÄÅÅÅÅÆÆÆÆÃÃÂÄÂÅÁÅÁÅÅÆÅÆÂÆÆÅÆÅÆÆÅÄÁÄÅÅÆÆÅÄÄÁÅÁÅÁÅÁÅÁÆÂÆÂÆÁÆÂÆÆÅÁÄÁÅÁÅÁÅÁÆÁÆÂÆÆÆÆÆ !!!!!!! !!!!""""####$$$$%%&&&&''(((())))****++,,,,---...///0111122334ÄÄÄÅÄÄÄÅÅÆÅÆÆÅÅÆÅÆÁÅÅÅÅÆÆÆÀÄÀÄÄÅÅÅÅÆÆÆÄÅÅÆÆÆÅÅÅÃÃÅÅÄÅÅÅÆÆÆÆÅÅÅÅÃÅÃÅÄÄÄÁÅÅÄÄÅÂÆÅÆÄÄÅÆÁÅÂÅÄÅÅÆÅÆÃÆÆÆÅÄÄÄÅÄÅÅÅÅÆÅÆÆÅÆÅÆÆÆÅÁÄÁÅÆÆÅÄÄÄÄÄÅÅÅÅÅÅÅÅÅÅÅÅÄÆÆÆÆÅÄÄÅÄÅÅÅÅÅÅÆÆÆÂÆÂÆÆ"" ! !!"!#"##$#$$%$%%&%&&''('(())*)**+*++,+,,--.-.././deeff0011213233ÇÄ545ÄÄÄÅÄÅÅÆÆÆÆÅÄÅÅÆÅÆÅÆÄÅÅÆÆÅÁÀÄÅÄÅÄÅÅÆÅÆÄÅÅÆÃÃÅÃÃÅÅÅÅÆÅÆÅÆÅÆÅÆÅÆÃÅÃÅÄÄÄÅÅÄÄÅÅÅÅÆÄÄÆÆÆÄÄÅÅÅÅÅÅÆÆÆÃÃÃÆÄÄÅÁÅÄÅÅÆÂÆÂÅÆÅÆÆÆÆÅÅÄÄÅÅÆÄÄÄÅÁÅÄÅÁÅÅÅÂÅÅÆÂÄÅÆÅÄÆÅÁÄÄÅÁÅÅÅÁÆÅÆÁÆÂÆÅÅ""""#ÄÅÅ$$%%%%&&&&''(((())))**++++,,,,----..///abbccdde00111223334445ÀÄÄÄÆÄÄÅÄÄÄÅÅÆÆÅÅÆÆÄÆÅÅÅÅÆÆÆÆÆÆÀÄÀÄÄÄÄÅÆÅÅÅÆÅÆÃÃÅÃÃÅÅÅÅÅÅÅÅÆÆÆÆÆÆÆÄÄÄÅÄÄÄÄÄÄÄÅÄÆÅÆÆÅÄÆÆÄÄÅÄÅÄÅÅÆÅÆÆÆÆÆÆÅÄÄÅÅÅÅÅÅÆÅÅÅÅÆÅÆÆÆÆÅÄÅÅÆÄÄÄÄÄÅÄÅÅÅÅÅÅÅÅÅÅÆÄÅÅÆÄÆÅÄÄÄÄÅÅÅÅÅÅÆÅÆÂÆÆÆÅ%&%ÄÄÅÅÆÅÅÅÆ()())*)**+*++,+,,-,--.-.././/eeff``aa0011223343ÇÇÄÄÄÄÆÆ8ÇÄÄÅÅÆÄÅÄÅÄÅÅÆÆÅÅÆÆÆÁÇÇÅÄÅÅÆÅÆÆÆÄÄÄÄÄÄÅÆÅÅÅÆÅÆÅÃÃÃÅÅÅÅÅÆÅÆÅÆÅÆÆÆÅÆÄÄÄÅÅÆÅÆÅÆÄÄÅÅÅÆÆÄÄÄÆÆÅÄÄÄÄÅÅÅÅÆÆÆÆÆÅÆÅÄÄÅÄÅÅÅÄÅÅÆÅÆÅÆÅÆÆÆÅÄÄÆÆÄÄÅÁÅÄÅÁÅÄÅÁÅÅÆÂÆÄÅÂÆÆÄÆÅÄÅÁÅÄÅÁÅÅÆÁÆÅÆÅÆÅÅ(ÅÅÅÅÅÆÆÆÆÆÆÆÆÆ+,,,,----....////aabbccdde0011222334455667ÇÀÄÄÄÄÅÆÆÆÇÄÄÄÄÆÆÆÄÅÄÄÅÅÆÆÅÆÆÆÅÇÇÄÄÆÆÅÅÆÆÆÅÄÄÄÄÄÅÆÆÆÅÅÅÆÆÆÆÅÅÅÅÅÆÅÅÆÅÆÅÆÆÆÆÆÄÄÄÅÅÅÅÆÆÆÅÄÄÅÆÅÅÄÄÅÄÆÆÆÄÅÄÅÄÅÅÆÅÆÆÆÆÆÆÅÄÄÄÅÄÅÄÅÅÅÅÅÅÆÅÆÆÆÆÆÅÅÅÄÄÄÄÅÄÅÄÅÅÅÅÅÅÅÅÆÄÄÅÅÆÆÅÆÅÄÄÅÄÅÅÅÅÅÅÆÆÆÆÆÆÅÅÄÅÄÅÅÆÅÆÅÆÅÆÆÆÅÆ././//fg`abcdef``00112233445565778788:ÄÀÄÄÄÄÅÆÅÆÆÆÀÄÄÄÄÅÅÆÅÆÄÄÄÅÅÆÆÆÅÆÆÇÄÄÄÅÅÆÆÆÅÅÆÅÄÅÄÄÅÅÅÆÅÆÅÅÅÆÅÆÅÅÅÅÆÆÅÆÅÆÅÆÆÆÆÆÆÄÄÅÅÆÅÆÅÆÅÄÄÅÆÆÅÄÄÅÅÆÅÆÆÆÄÅÅÅÅÆÆÆÆÆÆÆÅÆÄÅÄÅÄÅÄÅÅÅÅÅÅÆÅÆÅÆÅÆÆÆÅÄÄÅÄÅÄÅÄÅÄÅÁÅÅÆÅÆÅÄÁÅÅÆÆÅÆÅÁÄÄÅÄÅÅÆÁÆÅÆÅÆÅÅÅÅÅÅÅÅÅÅÆÅÆÆÆÆÆÅÆÆÆeefffgg`01122334455566778899::;;;ÄÄÄÀÄÄÅÅÅÅÅÅÆÆÄÄÄÄÄÅÆÆÅÅÆÆÆÆÅÅÅÆÆÆÆÆÄÄÄÄÅÅÅÆÆÅÆÅÄÄÅÅÆÅÅÆÆÆÆÆÅÅÅÆÆÅÆÅÅÅÆÆÅÅÅÅÆÆÆÆÆÆÄÄÅÅÅÆÆÄÄÄÄÅÆÆÆÅÄÄÅÅÅÅÆÅÆÅÆÆÅÅÅÅÆÅÆÆÆÆÆÅÄÄÄÄÅÄÅÅÅÅÅÅÅÅÆÆÆÆÆÅÅÅÆÄÄÄÄÄÅÄÅÅÅÅÅÅÅÅÅÅÅÄÅÅÅÅÆÅÆÅÄÄÄÄÅÅÅÅÅÅÆÆÆÆÅÅÅÆÅÅÅÆÅÆÅÆÅÆÆÆÅÆÅÆÆÆ0112233445566778899::;;<<==>ÄÄÄÄÄÄÄÄÄÅÄÆÅÆÆÄÄÄÄÄÄÆÅÆÅÆÅÆÅÆÅÆÆÅÅÆÆÆÆÄÄÅÄÄÄÅÅÆÅÆÅÆÅÆÄÅÅÆÆÆÅÆÅÆÅÅÅÆÆÆÅÅÅÅÆÆÅÆÅÆÅÆÅÆÆÄÄÅÅÆÅÄÄÄÄÅÅÆÅÆÅÄÄÅÄÅÅÅÅÆÅÆÆÅÄÅÅÆÅÆÅÆÆÆÅÄÄÅÄÅÄÄÄÅÅÆÆÆÅÆÆÆÅÆÅÆÄÄÄÅÄÅÄÅÄÅÄÅÄÅÅÅÅÆÅÆÅÄÄÅÅÆÆÆÆÅÄÅÄÅÄÅÅÆÅÆÅÆÆÅÆÅÅÅÅÅÅÅÆÅÆÅÆÆÆÆÆÆÆÆÆÆÆ566778999:;;<===>??@@BBÄÄÄÄÄÄÄÄÄÅÆÄÅÅÆÆÅÅÄÄÄÄÅÄÅÅÆÅÆÆÆÅÅÅÆÆÆÆÆÆÆÆÆÄÄÄÅÅÅÅÆÅÆÆÆÆÆÆÆÄÅÆÆÅÅÅÇÄÅÅÆÅÅÅÆÆÆÆÆÅÅÅÆÆÆÆÆÆÆÄÄÅÅÅÄÄÅÄÅÅÆÆÆÅÅÄÄÄÅÅÅÅÅÅÆÆÆÅÅÅÅÅÆÆÆÆÆÆÄÄÅÅÅÅÅÅÆÅÆÆÆÅÆÅÅÄÄÄÄÄÄÆÄÄÄÄÄÄÅÅÅÅÅÅÅÅÅÅÅÅÆÄÄÅÅÆÆÅÆÅÄÄÅÄÅÅÅÅÅÅÆÆÆÆÄÅÆÅÅÆÅÆÅÆÅÆÆÆÆÆÅÆÅÆÆÆÆ;;<<==>>?YZYZZ[@BBEEÄÄÄÄÄÄÄÄÆÅÆÅÆÅÄÅÆÅÆÅÄÄÅÄÅÄÅÅÆÅÆÅÆÆÆÅÆÅÆÅÆÆÆÆÆÄÄÄÅÄÅÅÅÆÅÅÆÆÆÅÆÆÆÅÆÅÆÇÇÄÁÅÅÅÆÅÅÅÆÅÆÆÆÅÆÅÆÅÆÆÆÄÄÄÅÅÄÄÅÄÅÅÆÅÆÆÆÄÄÄÅÄÅÅÆÅÆÆÆÄÅÅÆÅÆÅÆÅÆÆÆÄÅÄÅÅÆÅÆÅÆÅÆÄÄÄÄÄÄÄÄÄÆÆÄÄÅÅÆÄÅÄÅÄÅÄÅÄÅÅÆÅÆÅÄÄÅÅÆÆÆÆÆÄÄÄÅÄÅÅÆÅÆÅÆÆÄÅÆÅÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆ€€‚‚XXYYYYYYZ@BDFHKMO2ÄÄÄÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÅÆÆÆÆÆÅÆÆÆÆÆÆÆÆÄÄÅÆÄÅÅÅÅÆÅÆÅÆÆÆÆÄÄÄÇÇÄÄÅÄÅÅÆÂÆÆÅÅÆÆÆÅÅÅÆÆÆÆÆÄÄÄÅÅÅÄÄÄÄÅÅÅÆÆÆÄÄÄÅÅÅÅÅÅÆÆÆÅÅÅÅÅÆÅÆÆÆÆÆÆÅÅÅÅÆÅÆÆÆÄÄÄÄÄÄÄÄÄÅÅÆÄÄÅÅÅÆÆÄÄÄÄÅÅÅÅÅÅÅÅÅÅÄÄÅÅÅÆÆÅÆÅÄÄÄÄÅÅÅÅÆÆÆÆÄÅÅÅÆÆÅÆÅÆÆÆƆ†ˆˆŠ‹Æ€‚@BDEHILMO@CEHJMOOÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÆÆÆÆÆÆÆÆÆÆÆÆÆÅÆÅÆÆÄÆÆÆÆÆÅÄÅÅÅÆÅÅÅÅÅÅÆÅÆÆÆÆÅÅÇÄÄÄÄÄÅÅÆÅÆÅÆÅÆÅÆÆÅÅÆÅÆÆÆÆÄÄÅÄÅÄÅÄÄÅÆÅÆÅÆÅÄÄÅÄÅÅÆÅÆÅÆÄÅÅÅÅÆÅÆÅÆÆÆÅÆÄÅÅÆÅÆÆÆÄÄÄÄÄÄÄÅÄÅÅÆÄÅÄÅÅÆÅÆÄÅÄÅÄÅÄÅÄÅÅÅÅÆÄÅÄÅÅÆÆÆÆÄÄÅÄÅÄÅÅÆÅÆÅÄÅÅÅÆÆÆŽ€‚ƒ„…‡‡‰Š‹ŒŽ€€@@AABBCCCDDEEEFFGGHHHIIJJJKKLLMMMNNOOÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÅÄÄÅÅÅÅÆÅÅÅÅÆÅÆÆÄÀÄÄÅÄÄÄÅÅÅÅÆÆÆÆÆÆÆÆÅÅÅÅÆÆÆÆÄÄÄÄÅÅÄÄÅÄÅÅÆÆÆÆÆÄÄÄÅÅÅÅÆÆÆÅÅÅÅÅÆÅÆÅÆÆÆÆÆÅÅÅÆÆÆÅÆÆÄÄÄÄÄÄÅÅÅÅÄÄÄÄÅÅÆÆÆÅÅÄÅÅÅÄÆÆÅÅÅÅÅÄÄÅÅÅÆÆÆÅÆÄÄÄÅÅÅÅÆÆÆÆÄÄÅÅÆÅÆÆ=??012244667899;;==>?@@@AABBBCCCDDDEEFFFFGGHHFEFFGFHGHHIHJIJJKJKKLKLLMLMMNNONOÛÛÛÄÄÄÄÄÄÄÄÄÅÅÆÆÅÆÆÆÆÄÆÅÄÅÄÄÄÅÄÅÅÆÆÆÅÆÆÆÅÆÆÅÅÆÅÆÅÆÄÄÄÅÅÆÄÄÄÅÄÅÅÆÅÆÄÅÄÅÅÅÅÆÅÆÆÅÅÅÅÅÅÆÅÆÆÆÆÆÆÅÄÅÅÆÆÆÅÄÄÄÄÅÄÅÅÆÅÆÄÅÄÅÅÆÅÆÆÆÅÆÅÆÅÄÅÆÅÆÄÅÆÄÄÅÅÆÅÆÆÆÆÄÄÅÄÅÅÆÅÆÆÄÄÅÅÆÅÆÆÆb7c89:::fd6778899:::>>>>??A@?B?AA@ABABCCDBDEFFGGHHFFFFGGHHHHIIJJJJKKLLLMMMNNNOOÄÄÄÄÄÅÅÅÅÅÅÆÆÆÆÆÅÆÄÄÄÄÄÄÄÅÄÅÄÅÅÆÅÆÅÆÆÆÆÛÛÛÛÛÛÛÛÛÄÄÄÅÅÅÄÄÄÄÅÅÅÅÅÆÆÄÄÅÅÅÅÅÅÆÆÅÅÅÅÅÅÆÅÆÆÆÆÆÆÆÅÅÅÆÆÆÆÄÄÄÄÅÅÅÅÆÆÆÄÄÄÅÅÅÅÆÆÆÅÅÅÅÅÄÅÅÆÅÄÅÅÅÆÆÅÅÅÆÆÆÆÆÄÄÄÅÅÅÅÆÆÄÄÅÅÆÅÆÆÆÆ2425556779fd6778899:::::=>==>>>>>@>?ABAABCCCDCDFFFFGGHHEEFFGGHHIIJJKKLLMMNNOOOÄÄÄÅÄÅÄÅÅÆÅÆÅÆÆÆÅÆÆÄÄÅÄÅÄÅÅÅÅÅÅÅÅÅÅÆÅÆÆÆÆÅÛÛÛÛÛÛÄÄÄÄÄÅÅÄÄÄÄÅÅÆÅÆÆÆÄÅÄÅÄÅÅÆÅÆÄÅÅÅÅÆÅÆÅÆÆÆÅÆÆÅÅÆÆÆÄÅÄÄÅÆÅÄÄÅÅÆÆÄÄÅÄÅÅÆÅÆÆÆÅÆÅÄÄÆÆÆÄÅÄÅÅÆÆÅÅÆÅÆÆÆÅÆÄÅÄÅÅÆÅÆÄÅÄÆÅÆÆÆÆÆ/deeeeeeefd67fd67787899:::::=====>>>??????@?A?ABDDEEF@FFGGHH@ABCDEFFHHIJKLMNOÄÄÄÅÅÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÄÄÄÅÅÅÅÅÆÅÆÆÆÆÆÆÆÆÆÆÆÄÄÄÄÛÛÛÛÆÆÆÄÄÄÄÅÅÅÅÆÆÆÆÄÄÄÄÅÅÅÅÆÆÅÅÅÅÅÅÆÆÆÆÆÆÆÄÅÅÆÆÆÆÄÄÄÄÆÅÄÄÅÅÆÆÆÄÄÄÅÅÅÅÆÆÆÅÅÅÄÅÆÅÆÅÄÄÅÅÅÅÆÅÅÅÆÆÆÅÆÆÄÄÅÅÅÆÆÄÄÄÅÅÆÅÆÅÆÆdde/ed/dddedfe/ffeecc6fc88f8f99=:::=======??????@=@=ACDCDEEFFFFGGHHKIHL@NLMÄÄÄÄÅÄÅÄÅÅÆÅÆÅÆÅÆÆÆÅÆÄÅÄÅÄÅÄÅÅÅÅÆÅÅÅÅÆÆÆÆÆÆÅÆÆÆÅÅÅÄÛÛÛÛÛÛÛÛÛÆÄÅÅÆÆÆÅÆÄÅÄÅÅÆÅÆÄÅÄÅÅÆÅÆÅÆÅÆÆÆÄÅÅÆÆÆÆÄÄÄÄÄÅÄÄÅÅÆÅÆÄÄÄÅÄÅÅÆÅÆÅÆÅÄÅÆÅÆÄÅÄÅÅÆÅÆÆÆÅÆÅÆÆÆÆÆÄÅÅÆÅÆÅÄÄÅÄÆÅÅÅÆÆÆd//e/ee/ed/dddedfe/ffeecc6fc88f889:9::<<<========>????=A=D=EEFFFFGGHHEJDFÄÄÄÄÄÅÅÅÅÅÅÆÅÆÆÆÆÆÆÆÆÄÄÄÄÅÄÅÅÅÅÅÅÅÅÆÅÆÆÅÅÅÅÄÆÆÆÆÅÆÅÅÅÄÄÄÄÄÄÛÛÛÛÛÛÛÛÛÛÛÛÛÛÅÅÆÆÆÆÄÄÅÄÅÅÅÅÆÆÆÆÆÆÆÄÅÆÆÆÆÄÄÄÄÅÆÄÄÅÅÅÆÆÆÄÄÄÅÅÅÅÆÆÆÅÄÅÆÅÄÄÅÄÅÅÅÅÆÆÆÅÆÅÆÆÆÅÆÆÄÅÅÅÆÆÆÄÄÄÅÅÅÅÆÆÆÆc/dddddde/ed/dddedfe/ffeecc6fc88ff888::9:9>99e:==>==>>>>?>??@@@^]@_B\AHÄÄÄÄÅÄÅÅÅÅÆÅÆÅÆÅÆÆÆÅÆ‚ÄÄÅÄÄÄÅÄÅÅÆÅÆÅÆÅÆÆÆÄÅÆÅÅÅÅÅÅÅÅÆÅÆÅÆÅÆÅÆÄÄÄÄÄÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÆÆÆÄÄÅÅÆÆÆÆÆÄÄÄÄÄÄÄÄÄÅÅÆÆÆÅÄÄÅÄÅÅÆÅÆÄÅÅÆÅÄÄÅÄÅÅÆÅÆÅÆÆÆÅÆÅÆÆÆÅÆÄÅÅÆÆÄÄÅÄÅÅÅÅÆÆÆÆÆcdddeeee/ed/dddedfe/ffeecc6fc88f778899:::<=:===>>>??>?=>>?>Z>^[Z^[^\]]ÄÄÄÄÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆ€ÄÄÄÄÅÅÅÅÅÅÅÅÆÆÆÆÆÄÄÅÅÅÅÅÅÄÄÅÅÆÆÅÆÅÆÅÆÆÆÆÆÆÆÆÆÅÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÄÄÄÅÅÆÆÆÄÅÅÆÆÆÆÆÄÄÅÅÅÆÆÆÄÅÅÆÆÄÄÄÄÅÅÅÅÆÆÆÆÆÅÆÅÆÆÆÅÆÆÆÄÆÆÆÄÄÄÅÄÅÅÆÅÆÆÆÆcccdde/ed/dddedfe/ffeecc6fc88f778897:9:=:<=>==>>??>>>>>?>[[\Z\\[\]]^€‚‚ƒ„††ˆˆŠŠŒŽ€Ž‡ŠŒˆÄÄÄÄÅÄÅÅÅÅÆÅÆÅÆÄÅÅÅÅÅÅÄÄÅÄÅÄÆÄÅÅÆÅÆÅÆÅÆÅÆÆÆÅÆÆÆÅÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÄÄÅÄÅÅÆÅÆÄÅÆÆÅÆÅÄÄÆÆÆÄÅÄÅÅÆÅÆÄÅÄÅÄÅÅÆÅÆÅÆÅÆÅÆÆÆÆÆÅÆÅÆÅÆÄÆÄÅÄÅÅÆÅÆÆÆÆÆd/dddedfe/ffeecc6fc88ffd6778899:::<<<=====>>>ÄÄÄÄÄ?<==>>\>\\]\^^^^€‚‚ƒ„…†‡‡ˆ‰Š‹ŒŽFGGHHIˆÄˆÅÄÅÅÅÅÅÅÆÅÆÆÅÅÅÄÅÅÅÅÄÄÄÄÄÄÅÅÅÅÆÆÆÆÆÅÆÅÆÆÆÆÆÆÆÆÆÆÆÞÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÄÄÄÅÅÅÅÅÅÆÆÆÅÆÅÆÅÆÆÆÅÆÅÆÄÅÅÅÅÆÄÄÄÅÅÅÅÅÅÆÆÆÅÅÅÆÆÆÆÆÅÆÆÆÅÆÅÄÆÄÄÅÅÅÅÆÅÆÆÆÆ787889899c9:9:9::;:;:;;;;<;<<=<=<===<==???ÄÄÄÄÄÄÅÆÆÆ=>>???]\]]^^]^^^__^_@AABBCCDDEEFFGGHˆˆˆÅĈÄÆÅÆÅÆÅÆÅÆÄÄÄÅÄÅÅÅÅÄÅÆÄÅÄÅÅÆÅÆÅÆÅÆÆÆÅÆÅÆÅÆÅÆÆÆÆÆÆÆÞÞÞÞÞÞÝÞÝÝÝÝÜÝÜÝÜÜÜÜÜÜÜÜÛÄÄÅÄÅÅÆÅÆÅÆÆÆÅÆÅÆÅÆÅÆÅÆÅÄÄÅÅÆÆÅÄÅÄÅÅÆÅÆÅÆÆÆÅÆÅÆÅÆÆÆÅÆÆÆÅÄÅÆÄÅÄÅÅÆÅÆÆÆÆÆ9999:9::::;d;;;;;;<<<<<<=<======>>>>>???ÄÄÄÅÅÆÅÅÆÆÆÆÆÆ\>?\]\]]^^^^@^A@BACBCCDDDDEEEFGGG‡ˆˆˆˆˆÆÅÆÆÆÆÆÆÄÄÄÄÄÄÄÅÅÅÅÅÅÆÆÆÅÅÅÆÅÆÆÆÆÆÅÆÅÆÅÆÆÆÅÆÆÆÆÆÆÆÆÆÆÆÞÞÞÞÞÞÞÞÝÝÝÝÝÝÝÝÜÝÜÜÜÄÄÄÄÅÅÅÅÆÆÆÆÆÆÆÅÆÆÆÅÆÆÆÅÆÆÄÄÅÅÆÄÅÅÅÅÅÅÅÅÆÆÆÅÆÅÆÅÆÆÆÅÆÆÆÅÆÄÅÆÄÄÅÅÅÅÆÆÆÆÆÆ:::;:;:;;<;<;<<<<=<=<=====>=>>>??>>????ÄÅÆÆÆÆÆÅÆÆÆÆÆÆÆ\]]\^^@BAB@BABCCCDDCCDDDDEEFFFGGG‡‰ŠŒŒŽŽ€ÄŒŒŒŽŽÆÅÆÆÆÅÆÆÆÅÆÅÆÅÆÆÆÆÅÅÆÅÆÅÆÅÆÆÆÅÆÅÆÅÆÆÆÅÆÆAABÙÞÞÞÞÞÝÝÝÝÜÝÜÝÜÄÄÅÄÅÄÅÄÅÅÆÅÆÆÆÅÆÅÆÅÆÅÆÅÆÅÆÄÅÅÆÄÅÄÅÄÅÅÆÅÆÅÆÆÆÅÆÅÆÆÆÆÆÅÆÆÆÅÄÅÆÄÅÄÅÅÆÅÆÆÆÆÆ;;;;<<<<<<<<========>>>>>=>>>>>>?0???5?Å€€ÆÆÆÆÆÆÆÆÆÆÆ„„]^^\]@A]DBBDCCDDDDFDDEEEFFFFGGHHIIIIŠŠŠŠ‹‹‹‹ŒŒŒŒŽŽŽÆÆÆÆÆÆÆÆÆÆÆÆÅÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆBBÙNÙÙÞÞÞÝÝÝÝÜÝÜÜÆÄÄÄÄÅÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÆÄÄÅÆÅÅÅÅÅÅÅÅÆÆÆÆÅÅÅÅÆÆÆÆÆÅÆÆÆÆÄÅÅÆÄÄÅÅÅÅÆÅÆÆÆÆ<=<=<====>=>=>=>>>>?>>>>>>?>?>=><=?X???€€€ƒƒ„„„„………\AA]B@B\@C@ECEFFFFFEFFEEFFGFHGHHIIJIJJKKLKLLMMNMNNOOO@O@@@A@BABBCCD„„„„……††‡‡ÆˆÆÆÆÆÅÆÆÆÆÆÆÆÆÆÆÆÆÆMÙMÙMÙÞÞÞÝÝÝÜÜÛÛÛÆÄÅÄÅÄÅÅÆÅÆÅÆÅÆÅÆÅÆÅÆÅÄÄÄÅÆÄÅÄÅÅÆÅÆÅÆÆÆÅÆÅÆÅÆÅÆÆÆÅÆÆÆÄÅÅÆÄÅÄÅÅÆÅÅÆÅÆÆ>=>>>>>>>>??????<<===?==>>>?>>>=>>;=XXXXY;>Y?YYC[AAB\D\ABDACBDCDADCDDDFFGFGFFGGFGGGGHHHHIIJJJJKKLLLLMMMMNNNNOOO@O@@@AAAABBCCDDDDEFFFGGHHIIIIJJKKLLLLLLLMMMÙMÙÙÙÞÞÝÝÝÝÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÆÆÆÆÆÆÆÆÄÄÄÄÄÄÆÅÅÅÅÅÅÆÆÆÆÆÆÅÅÆÅÆÅÆÆÆÅÆÆÆÆÄÅÅÆÄÄÅÅÆÆÆÆÆÆÆÆ>?>>?>>?>?>>>=?===?=>=?=??>>=>==>X??Y>Y=ZZA@ZBC@CCCBDCDEBDEECDFDEFEGGHHGHHGHGHHIHIIJIJKJJKKLKLLMLMMNNONOOOOO@O@@@AABBCBCCDDEEFEFFGGHHIHIIJJKKLLLÙÙÙÙÙÙÙÙÞÞÝÝÝÝÜÝÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÅÄÆÄÅÅÆÅÆÅÆÅÆÆÆÅÆÅÆÅÆÆÆÅÆÆÆÆÄÄÁÄÁÄÅÅÆÇÇÇÁÁÆÆÆ>?===??>>?>>>==<=====>=?==???>:>:=>YXW>VX@ZZ@BABCDDCBCDDDDEEFEDEFEFEEFFGIJHHJHIHIIIIIIJKKJKKKKLLLLMMMMNNNNOOOOOOO@@@@@AÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÝÝÝÝÝÝÝÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÅÅÅÅÅÅÅÅÆÆÆÆÆÆÅÅÅÅÅÅÆÆÆÆÅÅÆÆÇÇÇÇÇÁÇÄÁÇÁÁÁÁÇÇÇÇ>?SSR=>?R>???=STT>>>>>>>?>>>??>>>>>U>=>VWXYABCDCCEDEDEFEFEFFFGGFGGGGHHGIHIHJJJJJJJJKJKKJLKKKLLLMLMLMMNMNNONONOOO@O@AÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÙÙÙÝÙÝÙÝÙÝÝÝÝÜÝÜÝÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÅÄÅÅÆÅÆÆÆÆÆÅÆÆÄÄÅÄÅÅÆÅÆÆÆÆÆÆÇÇÁÄÁÁÁÁÁÁÂÁÇÇÇÁÁÁÁQQ@??RR>RR@>RSR<>S=>@>?B>@=>U>V?VUVWW@ACDCEDDEEEFFFHFGGGGHHIHIHIHIHJIJJIKKKKJKJJKJLLKLLKLLLLMMMMNNNNONOOOOO@O@AABÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÙÙÝÙÝÝÝÝÝÝÝÝÝÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÆÄÄÆÆÆÆÆÆÆÇÄÄÄÄÁÁÁÂÁÂÄÇÇÁÁÁÁÁÁÁ@Q@QARRAR@S?ASSBSSS>@TSCACB?C@@UAVAWAEVEBCEEFFFGFFFGGHGHIHJIJJIIIJIJIJKJJJKKJLKLKLKJKKLMKLLLLMLMMNMNNNNONONOOO@O@@@AABCCÚÚÚÚÚÚÚÚÚÙÚÙÚÙÙÙÙÝÙÝÙÝÝÝÝÝÝÜÝÜÝÜÝÜÜÜÜÛÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÆÇÄÄÁÄÁÄÁÂÁÂÇÇÄÄÁÁÁÁÂÁÂAAARAARRBBCCSDTCBATS@AEECDDDDDEFBECCGFGGGGGHHGGGGGGHIHJKJJJJJKJKJJJJJKKJKJKLKKLKKLKKLKLMLLMMMMMMNMNNNNONOOOOO@O@@@@@AAABCCDÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÝÙÝÝÝÝÝÝÝÝÜÜÜÜÜÛÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÇÄÄÄÄÁÁÁÁÂÂÇÄÄÄÁÁÂÁÂÁÂÁBA@BBA@AABDDEDEDDEDCCEGCFFEGFFGHGFEIFGHGHHHHHHHIIIIIJJJJKJJKJKKJKKKKKJKKKKKKKLLKLMLMLLLLLMLMMNMNMNNONONONOOO@OO@@ABBCCDEÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÝÙÝÙÝÝÝÝÝÝÜÝÜÝÜÜÜÜÛÜÛÜÛÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÇÄÄÄÄÁÄÁÂÂÂÇÄÄÄÁÄÂÁÂÁÂÂÂABABBCCDCCDEDDDEDEFGHGGFHFHGIGFGGGHHIHIHHHIHIIIJHIIIJKIJJKKKKKLKKLKKKKKKLLKLKLKLLLMLLMMLMMMMNNNNNNNNOOOOOO@O@@@AABCCDDÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÙÙÝÝÝÝÝÝÝÝÜÝÜÜÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÄÄÁÄÄÄÁÂÁÂÄÄÄÄÁÁÂÁÂÂÂÂÁÂCCBCCCCCCDDDEDEEFEEFHGHHHGHGIHGHHIIJIGJIIIIIIIJIJIJKJJJJJJJKKKKKLKKLLKKLKMLLKLMLLLLMMLMMMNMNNNNNNONOOOOO@O@O@@@AABBCDDEÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÝÙÝÙÝÝÝÝÜÝÜÝÜÝÜÝÜÜÜÜÛÜÛÜÛÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÄÄÁÄÂÄÂÂÁÂÂÇÄÄÁÄÂÁÂÁÂÁÂÂÂCCCCCCDCCDDDEEEEGEFGFGHGHHHIIHIIIHJHIHIJJJJIIIJJIKJJJJJJJJJKKKKKKKKLLLLLMMLMLLMLNMLMLMNMNNNNNNOOOOOOOOO@@@@@@@AABBCCDDEOÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÜÛÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÄÄÁÄÂÄÂÁÂÂÂÄÁÄÄÄÂÁÂÂÂÂÂÅÂÂCCCDDDDDDEEEDEEEFEEFGGGHHHHIIHIIIIJIJIJJJJJIJIJKJKIJKKJJJKJKLKLKKKLLMLMLMMMMLMNMNMMMNNMNNONONOOOOO@O@O@O@@@A@AABBCCDDEEFOÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÝÙÝÙÝÝÝÝÜÝÜÝÜÝÜÝÜÜÜÜÛÜÛÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÄÁÄÂÁÂÁÂÁÂÄÁÄÁÄÂÁÂÁÂÁÂÅÂÅÂDDCCEEFEEFEFEFFFFGGGGFFGHHIHGIHIJIIJIJJJKKJJKJJKJKJKKKKKKKJKLKLLLLLLMLMMMMMMMNMNNNNNNNNNOOOOOOOOOO@@@@@@@@AAAABBBBBBCCDDEEFFÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÝÙÝÝÝÝÝÝÝÝÝÝÜÝÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÄÄÄÂÁÂÂÂÂÂÄÁÁÄÄÁÁÂÂÅÅÅÅÅÅÅÅGHFFGEGFFGGGGFGHGGHGHHGHGGFHHIIHIIIIJJJJJJJKJKKKKJKKKKKLLKKLKKLLLMLMLMLMMNMNMNMNNONONONOOO@O@O@O@O@@@@@AAAABBCCDDEEFFGGHÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÝÙÝÙÝÙÝÙÝÝÝÝÜÝÜÝÜÝÜÝÜÜÛÜÛÜÛÜÛÛÛÜÛÛÛÜÛÛÛÜÛÛÛÜÛÄÄÁÄÂÁÂÁÂÂÄÄÄÄÅÄÂÂÂÂÅÅÆÅÆÅÆÅÆHHGGGHGIGGIHHHHHHIHHHHIIGHIGHIHIIIIIJIJJJJJJKJKKKKKKKKLLLLLLLLMMMMMMMMNMNNNNNNONOOOOOOOOOO@O@@@@@@@AAAABABBBBCCCCDDDEEFFFGGHÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÝÙÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÄÄÄÄÂÁÂÁÂÂÄÄÄÄÄÄÅÅÅÅÅÅÅÅÆÅÆÆÆÆJJHGIJHIIHIIIIIHHHHHHJJIIIIJJJIJJJKJKKJKJKJKKLKLKLKLLLLMLMLMLMMNMNMNMNNONONONOOOOOOO@O@O@O@O@@@@@AABBBCBCBCCDCDDEDEEFEFFGGHHIÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÝÙÝÙÝÙÝÝÝÝÝÝÜÝÜÝÜÝÜÜÜÝÛÜÛÜÛÜÛÜÛÜÛÜÛÜÛÜÛÄÄÄÄÅÄÂÄÂÂÂÅÄÄÅÄÅÄÅÄÅÅÆÅÆÅÆÅÆÅÆhLHIJJJIKJIJIJIJJJJJJJJJJKJKJKKKKKKKKKKKKKLKLLLLLLLLMMMMMMMMNMNMNNNNNNNNOOOOOOOOOOO@O@@@@@@@@@@@AAAABBBCCCDDDEEFFGGGHHHÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÝÙÝÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÄÄÄÄÅÄÅÅÂÂÂÂÄÄÄÄÅÅÅÅÅÅÅÅÆÅÆÆÆÆÆÆnhhJKLJKKKKKJKKJJJJKKLLKKKKKKLLKKKKLLLKLKLLMLMLMLMLMMNMNMNMNNNNNNONONONOOO@O@O@O@O@OO@@@@AAABBCCCDCDCDDEDEDEFFGGHHHIIÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÜÝÜÝÜÜÜÜÛÝÛÜÛÜÛÜÛÜÛÜÛÜÄÄÄÅÄÂÅÂÂÆÅÄÄÅÄÅÄÅÄÅÅÆÅÆÅÆÅÆÅÆÅÆohohLLLLKLLLKKLKLLKKLLLLLMLMLLLLLMMMMMMMMMMMMMMMMMNMNMNNNNNNNNOOOOOOOOOO@O@O@@@@@@@@@AAABBBCCCCCCDDDDEEEEFFFFFFGGGGHHINOÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÜÝÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÄÄÅÅÄÅÂÄÅÆÄÄÄÄÄÅÄÅÅÅÅÅÅÆÅÆÆÆÆÆÆÆÆhjhjjKKLLLKLLLLLMMLLLMMMMLLMLMLMMMMMMMMMMMMNMNMNMNMNNNNONONONOOOOO@O@O@O@O@O@@@@@@@A@AAABBBCCDDDEEEFFGGGHHHIINNOOÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÜÜÜÜÄÄÄÄÄÄÄÄÄÅÄÅÂÅÆÄÅÄÅÄÅÄÅÄÅÅÆÅÆÅÆÅÆÅÆÆÆÆÆoohjjLLKKLLMLLLLMLLLLLMMMMMMMMMMMMMMMMMMMMNMNNNNNNNNOOOOOOOOOOOO@O@@@@@@@@@@@AAABBBBCCCDDDEEFFFFGGHHHIIINOOÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÝÙÝÝÝÝÝÝÝÝÝÝÜÜÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÅÄÄÂÂÆÄÄÄÄÄÅÄÅÅÅÅÅÅÆÅÆÅÆÆÆÆÆÆÆÆjhkkjjKLLLLLMMMMLMLMLMNMMNNMNMNMNNMMNNMMNNMNNONONONOOOOOOO@O@O@O@O@O@O@@@@@A@AABBBCBCBCCDCDDDDEEEFFFGGGHHHIIIJJJÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÝÙÝÙÝÙÝÙÝÝÄÄÄÄÄÄÄÄÄÄÄÅÅÄÄÅÄÅÅÆÅÆÆÅÅÄÄÄÄÅÅÂÅÆÄÄÄÅÄÅÄÅÄÅÅÆÅÆÅÆÅÆÆÆÅÆÆÆÆÆlhkjjjjLLLLLLLMMMMMMMMMMMNMNMNNNNNNNNNNNNNONOOOOOOOOOOOOO@O@O@@@@@@@@@@@@@AAAAABBBBBBCCCCCDDDEEEEEFFFGGGHHHIIIIJJÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÝÙÝÝÝÝÝÄÄÄÄÅÅÅÅÅÅÅÅÄÄÄÄÅÅÅÅÅÅÆÆÆÄÄÄÅÅÅÅÂÆÆÄÄÄÄÄÅÄÅÅÅÅÅÅÅÅÆÆÆÆÆÅÆÅÆÆÆÆlhkkjjjLLLLMMLMLMLMMMMNNMMNNMNMNMNNONONONOOOOOOO@O@O@O@O@O@O@@@@@AAAABABBBCCCDDDEEEFFFFGGMMMNIIIJJJÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÝÙÝÙÝÙÝÝÄÄÄÄÄÅÄÄÄÅÄÅÄÅÄÄÄÅÄÅÄÅÅÆÅÄÄÅÄÅÄÅÅÆÅÆÆÄÄÅÄÅÄÅÄÅÅÅÅÆÅÆÅÆÅÆÆÆÆÄÆÆÆÆhkkkkjjjLLLMMMMMMMMMMMMMNNNNNNNNONONOOOOOOOOOOOOOOOOO@O@O@O@O@O@O@@@AAAABBBBBBBBCCCDDDDEEEFFFGGGGNNNOOÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÝÙÝÝÝÝÝÄÄÄÄÅÄÄÄÄÄÅÄÄÄÅÅÄÄÄÄÅÄÄÄÄÄÅÅÅÅÅÅÅÅÆÆÆÆÄÄÄÄÅÄÅÄÅÅÅÅÅÅÆÅÆÆÆÆÆÆÆÆÆÆÆÆklkkjkjjjLMMMMMMMNMNMNMNNONONONOOOOOOO@OOOOOOOOO@@@AABBBBCCCCDDDEEEFFFFGGGHHHCIOÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÙÙÙÝÙÝÙÝÝÄÄÄÄÄÅÄÄÄÅÄÅÄÅÄÅÆÅÄÄÄÅÄÅÄÅÄÅÅÅÅÅÅÆÅÆÅÆÅÆÄÄÄÄÄÅÄÅÅÅÅÅÅÆÅÆÆÆÆÆÆÆÆÆÆÆÄÄkkkkkjjjjMMMMMNNNNNNNNNNONOOOOOOOOOOOOO@@@@@AAAAAAABBBBCCCDDDDEEEFGGGGHHHIÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÝÝÝÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÅÆÆÄÄÄÄÄÄÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÆÆÆÄÄÄÄÅÅÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆÄÄÄÄÄÄjkkkjkjkjjMNMNNNNONONONONOOOOO@O@OOOO@@AAAABBEFGHIJKMNOGGGGHHHIÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÝÙÝÙÝÝÄÄÆÆÆÆÄÆÅÆÅÆÅÆÅÆÆÄÄÅÄÅÄÅÄÅÄÅÅÅÅÅÅÆÅÆÅÆÅÆÅÆÆÆÄÅÄÅÄÅÄÅÅÆÅÆÅÆÅÆÆÆÅÆÅÆÄÄÄÄÄÅÅÅkkkkkjjkjjNNNNNNOOOOOOOOOOO@@@@@AAAAAAHIKMOCHÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÙÙÝÙÝÝÝÝÄÆÆÆÆÆÄÄÅÅÅÆÅÆÅÆÆÄÄÄÄÄÄÅÅÅÄÅÅÅÅÅÅÅÅÆÅÆÅÆÆÆÆÆÆÆÄÅÅÅÅÅÅÅÅÆÆÆÆÆÅÆÅÆÆÄÄÄÄÅÅÅÅÅÅjkjkkkjkjjjONONOOOOOO@OO@@AAAABBBBBCCCDFFFGGGÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÙÙÙÝÙÝÙÝÙÝÙÝÝÝÝÝÄÅÆÅÆÅÆÅÆÅÄÄÄÄÅÄÅÄÅÄÅÅÅÅÅÅÆÅÆÅÆÅÆÅÆÅÆÆÆÆÅÄÅÄÅÅÆÅÆÅÆÆÆÅÆÅÆÅÄÄÄÄÅÅÆÅÆÅÆjjjkkjjjjjjjOOOOOOOOO@@BGKO@AAAABBBBCCCCDDDEEÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÄÄÅÄÅÄÅÅÅÅÅÅÅÅÆÅÆÅÆÆÆÆÆÆÅÅÅÅÅÅÆÆÆÅÅÅÅÅÅÅÆÅÆÆÄÄÄÆÅÅÅÅÅÅÆÅkljkkkjkjjjjOOOOOOO@@@@AAAABBBBCCCÚÚÚÚDÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÄÅÄÅÄÅÄÅÅÆÅÆÅÆÅÆÅÆÅÆÆÅÄÅÅÆÅÆÅÆÅÆÆÆÅÆÅÆÅÆÅÆÄÄÆÅÅÆÅÆÅÆÅÆkkkjkkkjkjjjjOO@@@@@@@AAAABBBBCÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÝÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÆÆÅÅÅÅÅÅÅÆÆÆÅÆÆÆÆÆÅÅÅÆÆÆÄÄÆÅÅÅÅÆÅÆÅÆÆklkjjkjkjkjjjjOO@O@@AAAABBBBCÚCCDDÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÙÝÝÝÙÝÝÝÝÝÝÅÆÅÆÆÆÅÅÅÆÅÆÅÆÅÆÅÆÅÆÆÆÆÆÅÆÅÆÅÆÄÄÄÅÄÅÅÆÅÆÆÆÅÆkkkjkjkjjjjjjj@@@@@AAAABBBBCÚÚÚÚÚÚÚEEÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÆÆÆÆÆÆÆÆÆÆÆÆÄÄÄÄÄÅÅÅÅÅÆÆÆÆÆÆkkkkjkjkjkjkjjj@@AAAABBBBÚÚÚÚDÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÜÜÜÜÜÜÜÆÆÅÄÄÄÄÅÄÅÅÆÅÆÆÆÅÆÆÆlkkkjjjjkkkjjjjAAAABBBBCCÚÚDÚDDEEÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÚÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÄÄÄÅÆÄÅÄÅÅÆÆÆÆÆÆÅÆklkkjjjkjkkkjkjjBBBBCCCÚDDDDDÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÙÙÚÙÙÙÙÝÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÄÄÄÅÅÆÄÅÅÅÅÆÅÆÅÆÅÆÆÆklkkjjkkjkkjjjjjjBBBCCCCCÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÄÄÄÅÆÆÆÄÅÅÅÅÅÅÆÆÆÅÆÆÆÅklkljkjkkkkkjkjjjjCCjCCDCDCDDEÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÄÄÅÅÆÅÆÆÅÄÅÄÅÅÄÅÆÆÆÆÆÆÆkllkjjjjkjkjkjjjjjCCCDDÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÜÜÜÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÄÅÅÅÅÆÆÆÄÄÄÅÄÄÄÅÆÆÆÆÆÆÅkllljkjkkkkkjkjjjjjDDDDDÚEEDEEFEÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÄÅÄÅÅÆÅÆÅÆÅÆÄÅÄÅÄÆÅÆÆÆÅÆkllkkjkjkjlkkjjjjjjjDDDEEÚÚÚÚÚFÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÅÆÆÆÅÆÅÆÄÄÄÅÅÅÅÆÅÆÆÆÅjlklkljkjllkjkjkjjjjEEÚÚÚFEFÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÆÅÆÅÄÄÅÄÅÄÅÅÆÅÆÆÅlllklkkjjklkkkjjjjjjjEEÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÚÚÙÚÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÝÜÜÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÄÄÅÅÅÅÆÅÆÆÆÆllklklkljjkljkjkjkjjjjEÚEFEFFFFGÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÚÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÙÝÝÜÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÆÅÆÅÆÅÆkllllklkkjjlkkkjjjjjjjÚFFFGGÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜhhhhhhhlkljljkjkjkjkjjjFÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝhhhhhhhhlkkjlkkjkjjjjjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÚÚÙÚÙÚÙÚÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜÝÜÜÜoomhjklhhlkkjkjkjkjkjkjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝnnnnhjklhhkkkkkkkjkjjjjjjGHGÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜnnnonhjkkhhhkkkkjkjkjkjjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÙÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝnnnnohjkllhhkkkkkkkjjjjjjjÚÚHÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÚÚÙÚÙÚÙÚÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÝÝÜÝÜÝÜÝÜÝÜnonnnhjkkhhhhjkkkkjkjkjjjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝnonnnhjklhhhjljkkkkkkjkjjjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÙÝÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝnooohjjllhhhjjjlkkkkjjjjjjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝooonhjklhhhkkjjjkkkkkkjjkjjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜnooononjlhkkjkjkjjkkjkjjjjjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÚÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝoonnnnonjkkjkjjjjkjlkkkjkkjjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝnononohomlkkjkjjjjkjlkjjjkjkjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝÜÝnnnnohomllkkkjkjjjkjlkkjkkljjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝnonohomlklkkjkjkjjjljkjjjkkkjkjjÚÚÚÚÚÚÚÙÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝÝÝÜÝnnhhojlllkkkkjjjkkjjjkkjjkkjjjjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÙÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝnhjlhmllklkkjkjkjkkjkjkjjkkjjkjjjÚÚÚÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÝÙÙÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÜÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝjkmhmklllkkkkkjjjkkjjkkkjkjkjkjjjjÚÚÚÚÚÚÚÚÚÚÚÚÚÙÚÚÚÙÚÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝkljhhlklllklkkjjjlkjjjkkjjjkkkjjjjjÚÚÚÞÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝlhhhjhlklllkkklkkjkjjjkkkjkkkjkjjjjÚÚÚÚÚÚÚÚÚÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÝÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝhnnhjkkllhhlklkkjjjkjjjlkkjkkjjkjkjjhhhhhÚÚÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÚÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝoomhjjkkllhhhllkkjjjkkjjkkkjljljjjjjjhhhhhhhhhhhÚÙÚÙÚÙÚÙÙÙÙÙÙÝÙÙÙÝÙÝÙÝÙÝÝÝÝÝÝÝÙÝÙÝÝÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝmnmhjkjkkllhhhhkjkjkkkjjklkkjjkkjkjjjhhhhhhhhhhhjhÙÚÙÙÙÚÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞÞÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝnnhjjjkkllllhhhhhjjjkkkjjkkkkjljkjjjjjhhhhhhhhhjklhÙÚÙÚÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÙÝÞÝÙÝÙÝÞÝÞÝÞÝÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝnhjkjkklkllhlhhhhkjkjkkjjjjlkjlkjkjkjjjhhhhhjhjkkhhjÙÚÙÙÙÙÙÙÙÙÙÙÙÙÝÙÝÙÝÙÝÝÝÝÝÙÝÝÝÝÝÝÝÝÝÝÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞnnhjkkkkllllhhhhlkjjkkkjjjjlkjljkkjjkjjjhhhjhhhjklhjjÙÚÙÙÙÙÙÙÝÙÝÙÝÙÝÙÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝnonhhjjkkllhhhhjlkjjjkjkjjjjkjkkjkjjjkjjhhhhhhhjkhjjjÚÙÚÙÚÙÙÙÙÙÙÙÙÙÞÝÙÝÙÝÝÝÞÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞnnnhjjkkllhhhhkkkljjjkkkjjjkkkjlkkkjjkkkjhhhhhjkhjkjjjÚÙÙÙÙÙÙÝÙÝÝÝÙÙÙÝÞÝÙÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÝÝÝÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝÝÝÞÝÝÝÝÝnonohhhhjkkhhhklkklkjkkkjjjjkljlkkjkjjjkjjhhhhjhjkkkjjjÚÙÙÙÙÙÙÙÙÙÙÞÙÞÝÝÞÝÝÝÝÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞonnnooonhjlhhlkkkkljjjkjjjjjjkjlkkkjjkjkkjhjklhjjjkkjjjjÚÙÝÝÙÙÙÝÙÙÙÝÙÞÙÝÞÝÞÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝÞÝÝÝnonononohjklhhklklklkkjkjkjjjljlkkjkjjkkkhjklhkjjkjkjkjjjÙÝÙÙÙÙÙÝÞÝÞÝÙÝÝÝÝÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞnnononohjjklhhlkkkkkkkkjjjjjjjlkkkkkkjkkhjjkhlkjjjkkkjjjjjÙÝÙÝÙÝÙÝÙÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝnononohhjkkllhklklkklkjkjkjkjjjljlkkjkjjkhjhllkkjkjkjkjkjjÝÙÝÙÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞononoohjkkllhhjklkkkkkkjkjjjjjjkjklkkjkklhhkllkkkjkkkjjjjjjÝÙÙÞÝÞÙÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝnononohjjkkllhjjklkkkkjkjkjkjjjjkljkkjklhkklklkkjkjkjkjkjkjjÝÙÝÙÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞonooohjjkkllhhjjlklkkkkkkjkjjjjjjkkkkjklhllllkkkkjjkkkkjjjjjjÝÙÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞnonohjjkkllhhhjjjlklkkkkjkjkjkjjjlklkkhkllklklklkkkkjkjkjkjkjjÝÙÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞooonhjlmlhnlhhhjjjlklkkkkkkjkjjkjjlkkkkllllllllklkjlkkkjjjjjjjkÝÞÙÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝnonononojnlhhohkjjklklkkkkjkjjjkkjjlklllllllllklkljklkjjjkjkjkjkÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞonoooooojklhhhkjjjjklkkkkkkkkjkkkjjjlllllllllllllkjklkjjkkkjjjkkÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞnmnonononjjnhkjkjkjjklklkkjkjjjkkjjjllllllllllklklkjkkjjjkjkjkjkjÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞÝÞmoooooojklhnkkkjkjjjlkkkkkkkkjjjkkjjlllllllllllllllkkkjjkkkjjjjjkkÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞnononojklhnkkkjjkkjjjlklkljkkjjkkkjjjlllllllllllllklklkjjkkkjjjkjkkÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞÞÞÝÞoooooojklhnkkkjjkkkjjjlkkkjjkjjjkkjjjjlllllllllllllllkkjjjkkkjjjkkkjÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞnononjklhnklkkjkjkkkjjklklkkjkjkjkjjkjllllllllllllklklkjkjjkjjjkkkkjjÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞooooojklmnlkkkjjkkkjjjjklkkkkkkjkkjjkkjlllhhhhlllllllllkjjjjkkjjkkjjjÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞnonoommmllklklkkjjjkkkjlklkkkkjkjjjkjhhhhhhhhhhhllllllklkljkjkjkjkkkjjÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞÞÞÞÞÞßÞÞoooommmmlllkkkkkjjkkkjjjkkkkkjjjjhhhhhmmmmmmmmmhhhhllllklkkkkkkkjjkjjjjÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞnonmmnmlklklklkkjkjkjkjjjkjjhhhhhmmnmnmnnonomnmnmnnmmmklklklkkkkjkjkjkjjÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞßÞÞÞß \ No newline at end of file diff --git a/apps/animclk/app-icon.js b/apps/animclk/app-icon.js new file mode 100644 index 000000000..f904072e3 --- /dev/null +++ b/apps/animclk/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+i4AFnYHGBBIAPDA0dAH4A/ABtBFtlk0uALlml0uBF1uAvQvtvQvroGAF4NWdteARwIvsXwNWq1BAFEdwK+CF9VBF4d6F9SOBR4OAF1OIF4KOB0opjwV6vd7rrtCFwIvlwN70q6BFQN6RwIEBsoAHrwJIACGBdINWvTtDAoIvINgIuYxAvBwAsCLwIjB0glGxKbCMDGCvYvBDwItBGYdWxIAExBpBp9dx4LFAAuPx+IxAQELoK9BE4S+CLgKQCC4IAD1gKBp9WBQoAFxOCE4WCAAIvB0uBWgIuCq2kAoIiBp962YAECIVPqFWBYoAEWQIAH0qNBLwYDBLwRfCF49Pp+BAIIuI1gnBvYADAoIBC0q9BAAWl0hiBp4nBDwoRBLwOzNwOtBgms1ouBq4mBAAQECRwICBGAJeCvQEEldeAAZxESIIzBBgeCq9dFwKKEqwuDvS/CMAQCCXgJiBp9dAAQFBFYUrAAgrBAAszmddq4ABJwI0CFANVXIjsCAIU5nMznNXLYIpBlksmUyq0yBgIBBroDBAwQKCJAMrJIIiBDYJNBAoILBqoJBHIIaDJYIABJgIsBAAIKBAAI7CAgIJBHgNVqsrkgCBPAgwBAAMkDARYBJ5AAFGgcrFQOIAALBFEQQwBbQQ3BAASGCqokDLAwACToKfDAYRyCwQzBFYaODfAOl0q/BR4I1BL4IcDAYIyDmUOhw4DN4IABr1eLQJkDxGsAAWBLAQxBA4L3BYQQoChEIFAIABFAuCKoWIAYYqE1oAB2ez6+sxGrLwOr6HW63XBQOrFYQxBFIRRBEgglBFogqEFYQtC2YODGAWl1nQGQXWU4geBAYNeE4YXD0mBFIoqBJ4RpG1YwEAQOBvQNBZYQHBwI1EBIQABcAOsFoaOCSw4XFeIkr0mlwACBBYYgBCooSBbwIrDwOIB4oAFMAITC6GrL4N60gCBAgSFBRAQCDvUkkgwBruIw+CQIYsHXQQAHwGAF4YTB5+kMwgABqp0Cp+BNgwsEFpQABD4JdDFQgxCAgOAAYIwCqzgEQwgsLAAWkEAIACGIQ2DNQmkYIUrOIRaEFx/QXA4oCY4g4CFwSRBB4SJOX4wiBMIYpDFwhfCGAtPSYJeCACC5FLoYEDNQYJBSAcqAQNWF6oeBXQgrCAoIzBAIKQFGAeAdwIAQDwNVqt6vLeDLQYzDFwVWfAYHCCIYAOwAaEEwJbCLQSTC0krHwV6CwOkqqWBYgVWF5whCRwr1BMgQ8ECAYCBp8kFwIwCAQIvN")) diff --git a/apps/animclk/app.js b/apps/animclk/app.js new file mode 100644 index 000000000..451003d62 --- /dev/null +++ b/apps/animclk/app.js @@ -0,0 +1,116 @@ +var pal = new Uint16Array(E.toArrayBuffer(E.toString(require("Storage").read("animclk.pal")))); +var img1 = require("Storage").read("animclk.pixels1"); +var img1height = img1.length/240; +var img2 = require("Storage").read("animclk.pixels2"); +var img2height = img2.length/240; +var cycle = [ + {reverse:0,rate:1,low:32,high:47}, + {reverse:0,rate:3,low:48,high:63}, + {reverse:0,rate:3,low:64,high:79}, + {reverse:0,rate:2,low:80,high:95}, + {reverse:0,rate:1,low:96,high:103}, + {reverse:0,rate:3,low:128,high:143}, + {reverse:0,rate:2,low:22,high:31} +]; +var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]; +var IX = 80, IY = 10, IBPP = 1; +var IW = 174, IH = 45, OY = 24; +var inf = {align:0}; +var bgoptions; + +require("Font7x11Numeric7Seg").add(Graphics); +var cg = Graphics.createArrayBuffer(IW,IH,IBPP,{msb:true}); +var cgimg = {width:IW,height:IH,bpp:IBPP,transparent:0,buffer:cg.buffer}; +var locale = require("locale"); +var lastTime = ""; + +// store clock background image in bgimg (a file in flash memory) +var bgimg = require("Storage").read("imgclock.face.bg"); +// if it doesn't exist, make it +function createBgImg() { + cg.drawImage(img,-IX,-IY,bgoptions); + require("Storage").write("imgclock.face.bg", cg.buffer); + bgimg = require("Storage").read("imgclock.face.bg"); +} +if (!bgimg || !bgimg.length) createBgImg(); + +function drawClock() { + var t = new Date(); + var hours = t.getHours(); + var meridian = ""; + if (is12Hour) { + meridian = (hours < 12) ? "AM" : "PM"; + hours = ((hours + 11) % 12) + 1; + } + // draw time + cg.clear(1); + cg.setColor(1); + var x = 74 + 32 * inf.align; + cg.setFont("7x11Numeric7Seg",3); + cg.setFontAlign(1,-1); + cg.drawString(hours, x, 0); + x+=2; + if (t.getSeconds() & 1) + cg.fillRect(x, 10, x+2, 10+2).fillRect(x, 20, x+2, 20+2); + x+=6; + cg.setFontAlign(-1,-1); + cg.drawString(("0"+t.getMinutes()).substr(-2), x, 0); + x+=44; + cg.setFont("7x11Numeric7Seg",1); + cg.drawString(("0"+t.getSeconds()).substr(-2), x, 20); + cg.setFont("6x8",1); + cg.drawString(meridian, x+2, 0); + let date = locale.date(t); + if (cg.stringWidth(date) < IW-64) { + cg.setFontAlign(0, -1); + cg.drawString(date,IW/2+32*inf.align,IH-8); + } else { + cg.setFontAlign(inf.align, -1); + cg.drawString(date,IW*(inf.align+1)/2,IH-8); + } +} + +function draw() { + var t = (new Date()).toString(); + if (t!=lastTime) { + lastTime = t; + drawClock(); + } + // color cycling + cycle.forEach(c=>{ + var p = pal.slice(c.low,c.high); + pal[c.low] = pal[c.high]; + pal.set(p,c.low+1); + }); + // draw image + g.setColor(-1); + // draw just the clock part overlaid (to avoid flicker) + g.drawImages([{x:0,y:OY,image:{width:240,height:img1height,bpp:8,palette:pal,buffer:img1}}, + {image:cgimg,x:IX,y:IY+OY}], + {x:0,y:OY,width:239,height:img1height}); + // now draw the image on its own below - this is faster + g.drawImage({width:240,height:img2height,bpp:8,palette:pal,buffer:img2},0,OY+img1height); +} + +if (g.drawImages) { + // draw clock itself and do it every second + draw(); + var secondInterval = setInterval(draw,100); + // load widgets + Bangle.loadWidgets(); + Bangle.drawWidgets(); + // Stop when LCD goes off + Bangle.on('lcdPower',on=>{ + if (secondInterval) clearInterval(secondInterval); + secondInterval = undefined; + if (on) { + secondInterval = setInterval(draw,100); + lastTime=""; + draw(); + } + }); +} else { + E.showMessage("Please update\nBangle.js firmware\nto use this clock","animclk"); +} +// Show launcher when middle button pressed +setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); diff --git a/apps/animclk/app.png b/apps/animclk/app.png new file mode 100644 index 0000000000000000000000000000000000000000..63eac03e5ea382874275acb5595292d7ac4bac70 GIT binary patch literal 4797 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 XyIFCj-P>bJ00000NkvXXu0mjf37H@B literal 0 HcmV?d00001 diff --git a/apps/animclk/create_images.js b/apps/animclk/create_images.js new file mode 100644 index 000000000..8436d99b3 --- /dev/null +++ b/apps/animclk/create_images.js @@ -0,0 +1,57 @@ +/* Creates an image and palette based off of +an image from http://www.effectgames.com/demos/canvascycle/ + +You just need to open devtools and find the `CanvasCycle.processImage` +call, then create a file for it. eg. + +http://www.effectgames.com/demos/canvascycle/image.php?file=V29&callback=CanvasCycle.processImage + +Finally cycles just needs adding +*/ +var CanvasCycle = { + processImage : function(info) { + const IMG1_HEIGHT = 55; + const IMG2_HEIGHT = 240-(24+55); + var img1 = Buffer.alloc(240*IMG1_HEIGHT); + var img2 = Buffer.alloc(240*IMG2_HEIGHT); + var n=0; + /* img.writeUInt8(240, n++); + img.writeUInt8(240, n++); + img.writeUInt8(8, n++);*/ + var pal = Buffer.alloc(256*2); + + for (var i=0;i>3); + pal.writeUInt16LE(p, i*2); + } + + function getPixel(x,y) { + return info.pixels[(x+640-240)+((y+480-240)*640)]; + } + + n = 0; + for (var y=0;y Date: Thu, 28 May 2020 14:38:46 +0100 Subject: [PATCH 595/878] fix formatting using eslint --- apps/sleepphasealarm/app.js | 178 ++++++++++++++++++------------------ apps/verticalface/app.js | 40 ++++---- 2 files changed, 109 insertions(+), 109 deletions(-) diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index dbb91c23f..d54ae1307 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -2,7 +2,7 @@ const alarms = require("Storage").readJSON("alarm.json",1)||[]; const active = alarms.filter(a=>a.on); // Sleep/Wake detection with Estimation of Stationary Sleep-segments (ESS): -// Marko Borazio, Eugen Berlin, Nagihan Kücükyildiz, Philipp M. Scholl and Kristof Van Laerhoven, "Towards a Benchmark for Wearable Sleep Analysis with Inertial Wrist-worn Sensing Units", ICHI 2014, Verona, Italy, IEEE Press, 2014. +// Marko Borazio, Eugen Berlin, Nagihan K�c�kyildiz, Philipp M. Scholl and Kristof Van Laerhoven, "Towards a Benchmark for Wearable Sleep Analysis with Inertial Wrist-worn Sensing Units", ICHI 2014, Verona, Italy, IEEE Press, 2014. // https://ubicomp.eti.uni-siegen.de/home/datasets/ichi14/index.html.en // // Function needs to be called for every measurement but returns a value at maximum once a second (see winwidth) @@ -13,124 +13,124 @@ const sleepthresh=600; var ess_values = []; var slsnds = 0; function calc_ess(val) { - ess_values.push(val); + ess_values.push(val); - if (ess_values.length == winwidth) { - // calculate standard deviation over ~1s - const mean = ess_values.reduce((prev,cur) => cur+prev) / ess_values.length; - const stddev = Math.sqrt(ess_values.map(val => Math.pow(val-mean,2)).reduce((prev,cur) => prev+cur)/ess_values.length); - ess_values = []; + if (ess_values.length == winwidth) { + // calculate standard deviation over ~1s + const mean = ess_values.reduce((prev,cur) => cur+prev) / ess_values.length; + const stddev = Math.sqrt(ess_values.map(val => Math.pow(val-mean,2)).reduce((prev,cur) => prev+cur)/ess_values.length); + ess_values = []; - // check for non-movement according to the threshold - const nonmot = stddev < nomothresh; + // check for non-movement according to the threshold + const nonmot = stddev < nomothresh; - // amount of seconds within non-movement sections - if (nonmot) { - slsnds+=1; - if (slsnds >= sleepthresh) { - return true; // awake - } - } else { - slsnds=0; - return false; // sleep - } - } + // amount of seconds within non-movement sections + if (nonmot) { + slsnds+=1; + if (slsnds >= sleepthresh) { + return true; // awake + } + } else { + slsnds=0; + return false; // sleep + } + } } // locate next alarm var nextAlarm; active.forEach(alarm => { - const now = new Date(); - const alarmHour = alarm.hr/1; - const alarmMinute = Math.round((alarm.hr%1)*60); - var dateAlarm = new Date(now.getFullYear(), now.getMonth(), now.getDate(), alarmHour, alarmMinute); - if (dateAlarm < now) { // dateAlarm in the past, add 24h - dateAlarm.setTime(dateAlarm.getTime() + (24*60*60*1000)); - } - if (nextAlarm === undefined || dateAlarm < nextAlarm) { - nextAlarm = dateAlarm; - } + const now = new Date(); + const alarmHour = alarm.hr/1; + const alarmMinute = Math.round((alarm.hr%1)*60); + var dateAlarm = new Date(now.getFullYear(), now.getMonth(), now.getDate(), alarmHour, alarmMinute); + if (dateAlarm < now) { // dateAlarm in the past, add 24h + dateAlarm.setTime(dateAlarm.getTime() + (24*60*60*1000)); + } + if (nextAlarm === undefined || dateAlarm < nextAlarm) { + nextAlarm = dateAlarm; + } }); function drawString(s, x, y) { - g.clearRect(0,y-15,239,y+15); - g.reset(); - g.setFont("Vector",20); - g.setFontAlign(0,0); // align right bottom - g.drawString(s, x, y); + g.clearRect(0,y-15,239,y+15); + g.reset(); + g.setFont("Vector",20); + g.setFontAlign(0,0); // align right bottom + g.drawString(s, x, y); } function drawApp() { - g.clearRect(0,24,239,215); - var alarmHour = nextAlarm.getHours(); - var alarmMinute = nextAlarm.getMinutes(); - if (alarmHour < 10) alarmHour = "0" + alarmHour; - if (alarmMinute < 10) alarmMinute = "0" + alarmMinute; - const s = alarmHour + ":" + alarmMinute + "\n\n"; - E.showMessage(s, "Sleep Phase Alarm"); + g.clearRect(0,24,239,215); + var alarmHour = nextAlarm.getHours(); + var alarmMinute = nextAlarm.getMinutes(); + if (alarmHour < 10) alarmHour = "0" + alarmHour; + if (alarmMinute < 10) alarmMinute = "0" + alarmMinute; + const s = alarmHour + ":" + alarmMinute + "\n\n"; + E.showMessage(s, "Sleep Phase Alarm"); - function drawTime() { - if (Bangle.isLCDOn()) { - const now = new Date(); - var nowHour = now.getHours(); - var nowMinute = now.getMinutes(); - var nowSecond = now.getSeconds(); - if (nowHour < 10) nowHour = "0" + nowHour; - if (nowMinute < 10) nowMinute = "0" + nowMinute; - if (nowSecond < 10) nowSecond = "0" + nowSecond; - const time = nowHour + ":" + nowMinute + ":" + nowSecond; - drawString(time, 120, 140); - } - } + function drawTime() { + if (Bangle.isLCDOn()) { + const now = new Date(); + var nowHour = now.getHours(); + var nowMinute = now.getMinutes(); + var nowSecond = now.getSeconds(); + if (nowHour < 10) nowHour = "0" + nowHour; + if (nowMinute < 10) nowMinute = "0" + nowMinute; + if (nowSecond < 10) nowSecond = "0" + nowSecond; + const time = nowHour + ":" + nowMinute + ":" + nowSecond; + drawString(time, 120, 140); + } + } - setInterval(drawTime, 500); // 2Hz + setInterval(drawTime, 500); // 2Hz } var buzzCount = 19; function buzz() { - Bangle.setLCDPower(1); - Bangle.buzz().then(()=>{ - if (buzzCount--) { - setTimeout(buzz, 500); - } else { - // back to main after finish - setTimeout(load, 1000); - } - }); + Bangle.setLCDPower(1); + Bangle.buzz().then(()=>{ + if (buzzCount--) { + setTimeout(buzz, 500); + } else { + // back to main after finish + setTimeout(load, 1000); + } + }); } // run var minAlarm = new Date(); var measure = true; if (nextAlarm !== undefined) { - Bangle.drawWidgets(); - Bangle.loadWidgets(); + Bangle.drawWidgets(); + Bangle.loadWidgets(); - // minimum alert 30 minutes early - minAlarm.setTime(nextAlarm.getTime() - (30*60*1000)); - setInterval(function() { - const now = new Date(); - const acc = Bangle.getAccel().mag; - const swest = calc_ess(acc); + // minimum alert 30 minutes early + minAlarm.setTime(nextAlarm.getTime() - (30*60*1000)); + setInterval(function() { + const now = new Date(); + const acc = Bangle.getAccel().mag; + const swest = calc_ess(acc); - if (swest !== undefined) { - if (Bangle.isLCDOn()) { - drawString(swest ? "Sleep" : "Awake", 120, 180); - } - } + if (swest !== undefined) { + if (Bangle.isLCDOn()) { + drawString(swest ? "Sleep" : "Awake", 120, 180); + } + } - if (now >= nextAlarm) { - // The alarm widget should handle this one - setTimeout(load, 1000); - } else if (measure && now >= minAlarm && swest === false) { - buzz(); - measure = false; - } - }, 80); // 12.5Hz - drawApp(); + if (now >= nextAlarm) { + // The alarm widget should handle this one + setTimeout(load, 1000); + } else if (measure && now >= minAlarm && swest === false) { + buzz(); + measure = false; + } + }, 80); // 12.5Hz + drawApp(); } else { - E.showMessage('No Alarm'); - setTimeout(load, 1000); + E.showMessage('No Alarm'); + setTimeout(load, 1000); } // BTN2 to menu, BTN3 to main setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); diff --git a/apps/verticalface/app.js b/apps/verticalface/app.js index 3e4650d18..aa6441e79 100644 --- a/apps/verticalface/app.js +++ b/apps/verticalface/app.js @@ -98,8 +98,8 @@ var secondInterval = setInterval(()=>{ Bangle.on('lcdPower',on=>{ if (on) { secondInterval = setInterval(()=>{ - drawTimeDate(); -}, 15000); + drawTimeDate(); + }, 15000); //Screen on drawBPM(HRMstate); drawTimeDate(); @@ -122,29 +122,29 @@ Bangle.on('touch', function(button) { //HRM Controller. setWatch(function(){ if(!HRMstate){ - console.log("Toggled HRM"); - //Turn on. - Bangle.buzz(); - Bangle.setHRMPower(1); - currentHRM = "CALC"; - HRMstate = true; - } else if(HRMstate){ - console.log("Toggled HRM"); - //Turn off. - Bangle.buzz(); - Bangle.setHRMPower(0); - HRMstate = false; - currentHRM = []; - } + console.log("Toggled HRM"); + //Turn on. + Bangle.buzz(); + Bangle.setHRMPower(1); + currentHRM = "CALC"; + HRMstate = true; + } else if(HRMstate){ + console.log("Toggled HRM"); + //Turn off. + Bangle.buzz(); + Bangle.setHRMPower(0); + HRMstate = false; + currentHRM = []; + } drawBPM(HRMstate); }, BTN1, { repeat: true, edge: "falling" }); Bangle.on('HRM', function(hrm) { if(hrm.confidence > 90){ - /*Do more research to determine effect algorithm for heartrate average.*/ - console.log(hrm.bpm); - currentHRM = hrm.bpm; - drawBPM(HRMstate); + /*Do more research to determine effect algorithm for heartrate average.*/ + console.log(hrm.bpm); + currentHRM = hrm.bpm; + drawBPM(HRMstate); } }); From 192ba32a5d9fa0d04daa6a2d017ce70770f7a367 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Thu, 28 May 2020 22:32:53 +0200 Subject: [PATCH 596/878] simpletimer: make BTN2 really return to launcher (only while countdown is not running) --- apps/simpletimer/README.md | 1 + apps/simpletimer/app.js | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/simpletimer/README.md b/apps/simpletimer/README.md index ebe54dbe5..426942034 100644 --- a/apps/simpletimer/README.md +++ b/apps/simpletimer/README.md @@ -15,4 +15,5 @@ Simple timer, useful when playing board games or cooking - Tap on seconds to increase them one by one - Press BTN3 to reset time to 0 - Press BTN1 to start the timer or reset to the original time +- Press BTN2 to return to the launcher (only while countdown is not running) - When the time is up use the [swipeleft](https://github.com/espruino/BangleApps/tree/master/apps/gesture) gesture to reset the timer diff --git a/apps/simpletimer/app.js b/apps/simpletimer/app.js index 0bd7992e2..8c8890af3 100644 --- a/apps/simpletimer/app.js +++ b/apps/simpletimer/app.js @@ -111,7 +111,6 @@ function reset(value) { state = value === 0 ? "unset" : "set"; } -setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); function addWatch() { clearWatch(); setWatch(changeState, BTN1, { @@ -119,6 +118,16 @@ function addWatch() { repeat: true, edge: "falling" }); + setWatch(() => { + if (state !== "started") { + Bangle.showLauncher(); + }}, + BTN2, + { + repeat: false, + edge: "falling", + }, + ); setWatch( () => { reset(0); From 4ab68eb4112bd86fba7dd39e894208f6d18cdd90 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Thu, 28 May 2020 22:29:58 +0200 Subject: [PATCH 597/878] simpletimer: remember last set time --- apps.json | 7 ++++++- apps/simpletimer/ChangeLog | 1 + apps/simpletimer/app.js | 5 ++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 5eede9c05..9779ba5a2 100644 --- a/apps.json +++ b/apps.json @@ -1634,7 +1634,7 @@ "id": "simpletimer", "name": "Timer", "icon": "app.png", - "version": "0.03", + "version": "0.04", "description": "Simple timer, useful when playing board games or cooking", "tags": "timer", "readme": "README.md", @@ -1659,6 +1659,11 @@ "url": "app-icon.js", "evaluate": true } + ], + "data": [ + { + "name": "simpletimer.json" + } ] }, { diff --git a/apps/simpletimer/ChangeLog b/apps/simpletimer/ChangeLog index 3f8d98248..b9a839e7d 100644 --- a/apps/simpletimer/ChangeLog +++ b/apps/simpletimer/ChangeLog @@ -1,3 +1,4 @@ 0.01: Initial version 0.02: Reset with gesture 0.03: BTN2 to open launcher +0.04: Remember last set time \ No newline at end of file diff --git a/apps/simpletimer/app.js b/apps/simpletimer/app.js index 8c8890af3..041535998 100644 --- a/apps/simpletimer/app.js +++ b/apps/simpletimer/app.js @@ -2,6 +2,7 @@ let counter = 0; let setValue = 0; let counterInterval; let state; +let saved = require("Storage").readJSON("simpletimer.json",true) || {}; const DEBOUNCE = 50; @@ -61,6 +62,8 @@ function clearIntervals() { function set(delta) { if (state === "started") return; counter += delta; + saved.counter = counter; + require("Storage").write("simpletimer.json", saved); if (state === "unset") { state = "set"; } @@ -160,5 +163,5 @@ Bangle.on("aiGesture", gesture => { if (gesture === "swipeleft" && state === "stopped") reset(0); }); -reset(0); +reset(saved.counter || 0); addWatch(); From 631abb812e8acdce0cb15ee8947bff2c26acbbe4 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Thu, 28 May 2020 23:27:10 +0200 Subject: [PATCH 598/878] gbridge: Add setting to show/hide icon --- apps.json | 5 ++++- apps/gbridge/ChangeLog | 1 + apps/gbridge/settings.js | 20 +++++++++++++++++++- apps/gbridge/widget.js | 19 +++++++++++++++---- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/apps.json b/apps.json index 5eede9c05..8b950228c 100644 --- a/apps.json +++ b/apps.json @@ -95,7 +95,7 @@ { "id": "gbridge", "name": "Gadgetbridge", "icon": "app.png", - "version":"0.11", + "version":"0.12", "description": "The default notification handler for Gadgetbridge notifications from Android", "tags": "tool,system,android,widget", "type":"widget", @@ -103,6 +103,9 @@ {"name":"gbridge.settings.js","url":"settings.js"}, {"name":"gbridge.img","url":"app-icon.js","evaluate":true}, {"name":"gbridge.wid.js","url":"widget.js"} + ], + "data": [ + {"name":"gbridge.json"} ] }, { "id": "mclock", diff --git a/apps/gbridge/ChangeLog b/apps/gbridge/ChangeLog index f66040388..0676652c7 100644 --- a/apps/gbridge/ChangeLog +++ b/apps/gbridge/ChangeLog @@ -10,3 +10,4 @@ 0.09: Update Bluetooth connection state automatically 0.10: Make widget play well with other Gadgetbridge widgets/apps 0.11: Report battery status on connect and at regular intervals +0.12: Setting to show/hide icon \ No newline at end of file diff --git a/apps/gbridge/settings.js b/apps/gbridge/settings.js index 723c9cae9..1834aa052 100644 --- a/apps/gbridge/settings.js +++ b/apps/gbridge/settings.js @@ -2,10 +2,28 @@ function gb(j) { Bluetooth.println(JSON.stringify(j)); } - + const storage = require('Storage'); + let settings = storage.readJSON("gbridge.json", true) || {}; + if (!("showIcon" in settings)) { + settings.showIcon = true; + } + function updateSettings() { + storage.write('gbridge.json', settings); + } + function toggleIcon() { + settings.showIcon = !settings.showIcon; + updateSettings(); + Bangle.loadWidgets(); + Bangle.drawWidgets(); + } var mainmenu = { "" : { "title" : "Gadgetbridge" }, "Connected" : { value : NRF.getSecurityStatus().connected?"Yes":"No" }, + "Show Icon" : { + value: settings.showIcon, + format: v => v?"Yes":"No", + onchange: toggleIcon + }, "Find Phone" : function() { E.showMenu(findPhone); }, "< Back" : back, }; diff --git a/apps/gbridge/widget.js b/apps/gbridge/widget.js index ae7d0f8fa..987426022 100644 --- a/apps/gbridge/widget.js +++ b/apps/gbridge/widget.js @@ -1,4 +1,5 @@ (() => { + const storage = require('Storage'); const state = { music: "stop", @@ -12,6 +13,11 @@ scrollPos: 0 }; + let settings = storage.readJSON('gbridge.json',1) || {}; + if (!("showIcon" in settings)) { + settings.showIcon = true; + } + function gbSend(message) { Bluetooth.println(""); Bluetooth.println(JSON.stringify(message)); @@ -192,10 +198,15 @@ g.flip(); // turns screen on } - NRF.on("connect", changedConnectionState); - NRF.on("disconnect", changedConnectionState); - - WIDGETS["gbridgew"] = { area: "tl", width: 24, draw: draw }; + if (settings.showIcon) { + WIDGETS["gbridgew"] = {area: "tl", width: 24, draw: draw}; + NRF.on("connect", changedConnectionState); + NRF.on("disconnect", changedConnectionState); + } else { + NRF.removeListener("connect", changedConnectionState); + NRF.removeListener("disconnect", changedConnectionState); + delete WIDGETS["gbridgew"]; + } function sendBattery() { gbSend({ t: "status", bat: E.getBattery() }); From fa692c4d8e64bf22e399d92740ea3d3574290bea Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 29 May 2020 00:05:26 +0200 Subject: [PATCH 599/878] gbridge: Fix setting to show/hide icon Don't reload all widgets: just change this one and redraw --- apps/gbridge/settings.js | 6 ++++-- apps/gbridge/widget.js | 31 +++++++++++++++++++------------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/apps/gbridge/settings.js b/apps/gbridge/settings.js index 1834aa052..8df3f6ab4 100644 --- a/apps/gbridge/settings.js +++ b/apps/gbridge/settings.js @@ -13,7 +13,9 @@ function toggleIcon() { settings.showIcon = !settings.showIcon; updateSettings(); - Bangle.loadWidgets(); + // need to re-layout widgets + WIDGETS["gbridgew"].reload(); + g.clear(); Bangle.drawWidgets(); } var mainmenu = { @@ -35,5 +37,5 @@ "< Back" : function() { E.showMenu(mainmenu); }, }; - E.showMenu(mainmenu); + const menu = E.showMenu(mainmenu); }) diff --git a/apps/gbridge/widget.js b/apps/gbridge/widget.js index 987426022..db6963abb 100644 --- a/apps/gbridge/widget.js +++ b/apps/gbridge/widget.js @@ -1,5 +1,6 @@ (() => { const storage = require('Storage'); + let settings; const state = { music: "stop", @@ -13,10 +14,6 @@ scrollPos: 0 }; - let settings = storage.readJSON('gbridge.json',1) || {}; - if (!("showIcon" in settings)) { - settings.showIcon = true; - } function gbSend(message) { Bluetooth.println(""); @@ -186,6 +183,7 @@ }); function draw() { + if (!settings.showIcon) return; g.setColor(-1); if (NRF.getSecurityStatus().connected) g.drawImage(require("heatshrink").decompress(atob("i0WwgHExAABCIwJCBYwJEBYkIBQ2ACgvzCwoECx/z/AKDD4WD+YLBEIYKCx//+cvnAKCBwU/mc4/8/HYv//Ev+Y4EEAePn43DBQkzn4rCEIoABBIwKHO4cjmczK42I6mqlqEEBQeIBQaDED4IgDUhi6KaBbmIA==")), this.x + 1, this.y + 1); @@ -198,16 +196,25 @@ g.flip(); // turns screen on } - if (settings.showIcon) { - WIDGETS["gbridgew"] = {area: "tl", width: 24, draw: draw}; - NRF.on("connect", changedConnectionState); - NRF.on("disconnect", changedConnectionState); - } else { - NRF.removeListener("connect", changedConnectionState); - NRF.removeListener("disconnect", changedConnectionState); - delete WIDGETS["gbridgew"]; + function reload() { + settings = storage.readJSON('gbridge.json', 1) || {}; + if (!("showIcon" in settings)) { + settings.showIcon = true; + } + if (settings.showIcon) { + WIDGETS["gbridgew"].width = 24; + NRF.on("connect", changedConnectionState); + NRF.on("disconnect", changedConnectionState); + } else { + WIDGETS["gbridgew"].width = 0; + NRF.removeListener("connect", changedConnectionState); + NRF.removeListener("disconnect", changedConnectionState); + } } + WIDGETS["gbridgew"] = {area: "tl", width: 24, draw: draw, reload: reload}; + reload(); + function sendBattery() { gbSend({ t: "status", bat: E.getBattery() }); } From 855186f7c9289d4f3f53e0f053c38fb5f7b5de9e Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 29 May 2020 10:37:44 +0200 Subject: [PATCH 600/878] gbridge: improve settings handling No need to keep them in memory after reload() is done --- apps/gbridge/settings.js | 25 ++++++++++++++----------- apps/gbridge/widget.js | 23 ++++++++++++----------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/apps/gbridge/settings.js b/apps/gbridge/settings.js index 8df3f6ab4..9e2245e66 100644 --- a/apps/gbridge/settings.js +++ b/apps/gbridge/settings.js @@ -2,17 +2,20 @@ function gb(j) { Bluetooth.println(JSON.stringify(j)); } - const storage = require('Storage'); - let settings = storage.readJSON("gbridge.json", true) || {}; - if (!("showIcon" in settings)) { - settings.showIcon = true; + function settings() { + let settings = require('Storage').readJSON("gbridge.json", true) || {}; + if (!("showIcon" in settings)) { + settings.showIcon = true; + } + return settings } - function updateSettings() { - storage.write('gbridge.json', settings); + function updateSetting(setting, value) { + let settings = require('Storage').readJSON("gbridge.json", true) || {}; + settings[setting] = value + require('Storage').write('gbridge.json', settings); } - function toggleIcon() { - settings.showIcon = !settings.showIcon; - updateSettings(); + function setIcon(visible) { + updateSetting('showIcon', visible); // need to re-layout widgets WIDGETS["gbridgew"].reload(); g.clear(); @@ -22,9 +25,9 @@ "" : { "title" : "Gadgetbridge" }, "Connected" : { value : NRF.getSecurityStatus().connected?"Yes":"No" }, "Show Icon" : { - value: settings.showIcon, + value: settings().showIcon, format: v => v?"Yes":"No", - onchange: toggleIcon + onchange: setIcon }, "Find Phone" : function() { E.showMenu(findPhone); }, "< Back" : back, diff --git a/apps/gbridge/widget.js b/apps/gbridge/widget.js index db6963abb..622543d1b 100644 --- a/apps/gbridge/widget.js +++ b/apps/gbridge/widget.js @@ -1,7 +1,4 @@ (() => { - const storage = require('Storage'); - let settings; - const state = { music: "stop", @@ -14,6 +11,13 @@ scrollPos: 0 }; + function settings() { + let settings = require('Storage').readJSON("gbridge.json", true) || {}; + if (!("showIcon" in settings)) { + settings.showIcon = true; + } + return settings + } function gbSend(message) { Bluetooth.println(""); @@ -183,7 +187,6 @@ }); function draw() { - if (!settings.showIcon) return; g.setColor(-1); if (NRF.getSecurityStatus().connected) g.drawImage(require("heatshrink").decompress(atob("i0WwgHExAABCIwJCBYwJEBYkIBQ2ACgvzCwoECx/z/AKDD4WD+YLBEIYKCx//+cvnAKCBwU/mc4/8/HYv//Ev+Y4EEAePn43DBQkzn4rCEIoABBIwKHO4cjmczK42I6mqlqEEBQeIBQaDED4IgDUhi6KaBbmIA==")), this.x + 1, this.y + 1); @@ -197,18 +200,16 @@ } function reload() { - settings = storage.readJSON('gbridge.json', 1) || {}; - if (!("showIcon" in settings)) { - settings.showIcon = true; - } - if (settings.showIcon) { + NRF.removeListener("connect", changedConnectionState); + NRF.removeListener("disconnect", changedConnectionState); + if (settings().showIcon) { WIDGETS["gbridgew"].width = 24; + WIDGETS["gbridgew"].draw = draw; NRF.on("connect", changedConnectionState); NRF.on("disconnect", changedConnectionState); } else { WIDGETS["gbridgew"].width = 0; - NRF.removeListener("connect", changedConnectionState); - NRF.removeListener("disconnect", changedConnectionState); + WIDGETS["gbridgew"].draw = ()=>{}; } } From 03246fdc85fb209e9d23b061eba059b76fcb805e Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 29 May 2020 10:41:19 +0200 Subject: [PATCH 601/878] gbridge: minor fixes IDE kept complaining about unused constant & unsafe comparisons --- apps/gbridge/settings.js | 2 +- apps/gbridge/widget.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/gbridge/settings.js b/apps/gbridge/settings.js index 9e2245e66..d1ecb594b 100644 --- a/apps/gbridge/settings.js +++ b/apps/gbridge/settings.js @@ -40,5 +40,5 @@ "< Back" : function() { E.showMenu(mainmenu); }, }; - const menu = E.showMenu(mainmenu); + E.showMenu(mainmenu); }) diff --git a/apps/gbridge/widget.js b/apps/gbridge/widget.js index 622543d1b..9fe87be03 100644 --- a/apps/gbridge/widget.js +++ b/apps/gbridge/widget.js @@ -76,7 +76,7 @@ var p = MAXCHARS; while (p > MAXCHARS - 8 && !" \t-_".includes(l[p])) p--; - if (p == MAXCHARS - 8) p = MAXCHARS; + if (p === MAXCHARS - 8) p = MAXCHARS; txt[i] = l.substr(0, p); txt.splice(i + 1, 0, l.substr(p)); } @@ -109,7 +109,7 @@ const changed = state.music === event.state state.music = event.state - if (state.music == "play") { + if (state.music === "play") { showNotification(40, (y) => { g.setColor("#ffffff"); g.drawImage(require("heatshrink").decompress(atob("jEYwILI/EAv/8gP/ARcMgOAASN8h+A/kfwP8n4CD/E/gHgjg/HA=")), 8, y + 8); @@ -126,14 +126,14 @@ }, changed); } - if (state.music == "pause") { + if (state.music === "pause") { hideNotification(); } } function handleCallEvent(event) { - if (event.cmd == "accept") { + if (event.cmd === "accept") { showNotification(40, (y) => { g.setColor("#ffffff"); g.drawImage(require("heatshrink").decompress(atob("jEYwIMJj4CCwACJh4CCCIMOAQMGAQMHAQMDAQMBCIMB4PwgHz/EAn4CBj4CBg4CBgACCAAw=")), 8, y + 8); @@ -180,7 +180,7 @@ }); Bangle.on("swipe", (dir) => { - if (state.music == "play") { + if (state.music === "play") { const command = dir > 0 ? "next" : "previous" gbSend({ t: "music", n: command }); } From 7e87bd0c03ba4b012ac22067d91170096178234e Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 29 May 2020 13:23:20 +0100 Subject: [PATCH 602/878] add toast to log --- js/ui.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/ui.js b/js/ui.js index 47016e86b..859954e7f 100644 --- a/js/ui.js +++ b/js/ui.js @@ -83,6 +83,7 @@ Puck.writeProgress = function(charsSent, charsTotal) { /// Show a 'toast' message for status function showToast(message, type) { // toast-primary, toast-success, toast-warning or toast-error + console.log("TOAST["+(type||"-")+"] "+message); let style = "toast-primary"; if (type=="success") style = "toast-success"; else if (type=="error") style = "toast-error"; From 49d504a034ac3f631db538cdc6307e4dcb9de276 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 29 May 2020 13:27:27 +0100 Subject: [PATCH 603/878] Only upload binary files where needed. Assume utf-8 otherwise (Fix #463) --- js/utils.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/js/utils.js b/js/utils.js index 69dcda93b..4716c3f46 100644 --- a/js/utils.js +++ b/js/utils.js @@ -29,11 +29,18 @@ function htmlElement(str) { return div.firstChild; } function httpGet(url) { + let isBinary = !(url.endsWith(".js") || url.endsWith(".json") || url.endsWith(".csv") || url.endsWith(".txt")); return new Promise((resolve,reject) => { let oReq = new XMLHttpRequest(); oReq.addEventListener("load", () => { - // ensure we actually load the data as a raw 8 bit string (not utf-8/etc) - if (oReq.status==200) { + if (oReq.status!=200) { + resolve(oReq.status+" - "+oReq.statusText) + return; + } + if (!isBinary) { + resolve(oReq.responseText) + } else { + // ensure we actually load the data as a raw 8 bit string (not utf-8/etc) let a = new FileReader(); a.onloadend = function() { let bytes = new Uint8Array(a.result); @@ -43,7 +50,7 @@ function httpGet(url) { resolve(str) }; a.readAsArrayBuffer(oReq.response); - } else reject(oReq.status+" - "+oReq.statusText); + } }); oReq.addEventListener("error", () => reject()); oReq.addEventListener("abort", () => reject()); @@ -51,7 +58,8 @@ function httpGet(url) { oReq.onerror = function () { reject("HTTP Request failed"); }; - oReq.responseType = 'blob'; + if (isBinary) + oReq.responseType = 'blob'; oReq.send(); }); } From 889ed82de2e86fb123a8fbcdc4b3b0d2304e65b0 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 29 May 2020 16:18:12 +0100 Subject: [PATCH 604/878] ok so eslint didn't fix it --- apps/sleepphasealarm/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index d54ae1307..1f8bf92ae 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -2,7 +2,7 @@ const alarms = require("Storage").readJSON("alarm.json",1)||[]; const active = alarms.filter(a=>a.on); // Sleep/Wake detection with Estimation of Stationary Sleep-segments (ESS): -// Marko Borazio, Eugen Berlin, Nagihan K�c�kyildiz, Philipp M. Scholl and Kristof Van Laerhoven, "Towards a Benchmark for Wearable Sleep Analysis with Inertial Wrist-worn Sensing Units", ICHI 2014, Verona, Italy, IEEE Press, 2014. +// Marko Borazio, Eugen Berlin, Nagihan Kücükyildiz, Philipp M. Scholl and Kristof Van Laerhoven, "Towards a Benchmark for Wearable Sleep Analysis with Inertial Wrist-worn Sensing Units", ICHI 2014, Verona, Italy, IEEE Press, 2014. // https://ubicomp.eti.uni-siegen.de/home/datasets/ichi14/index.html.en // // Function needs to be called for every measurement but returns a value at maximum once a second (see winwidth) From c83ae5dc7ee86e3a151876ba9696fc9533bc3b97 Mon Sep 17 00:00:00 2001 From: Harrison Asmar <34726416+hasmar04@users.noreply.github.com> Date: Sat, 30 May 2020 20:05:47 +1000 Subject: [PATCH 605/878] Stops the face redrawing and using all memory Removes the clear screen and widget loading from each wake so it only runs the first time. Prevents the watch from running out of memory after approx. 3 wakes. --- apps/cliock/app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/cliock/app.js b/apps/cliock/app.js index 20086464e..a94b7264d 100644 --- a/apps/cliock/app.js +++ b/apps/cliock/app.js @@ -5,9 +5,6 @@ var flag = false; var WeekDays = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]; function drawAll(){ - g.clear(); - Bangle.loadWidgets(); - Bangle.drawWidgets(); updateTime(); updateRest(new Date()); } @@ -42,6 +39,9 @@ function writeLine(str,line){ g.drawString(str,25,marginTop+line*30); } +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); drawAll(); Bangle.on('lcdPower',function(on) { if (on) From 48eea4cc578abd66dc5e7062ccbbd450f4587a28 Mon Sep 17 00:00:00 2001 From: Harrison Asmar <34726416+hasmar04@users.noreply.github.com> Date: Sat, 30 May 2020 20:20:12 +1000 Subject: [PATCH 606/878] Update ChangeLog --- apps/cliock/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/cliock/ChangeLog b/apps/cliock/ChangeLog index 081a638f6..59f07c400 100644 --- a/apps/cliock/ChangeLog +++ b/apps/cliock/ChangeLog @@ -1 +1,2 @@ 0.07: Submitted to App Loader +0.08: Fixes issue where face would redraw on wake leading to all memory being used and watch crashing. From b08d8ce0f41789420e240cef46b449deffda7818 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Sun, 31 May 2020 15:06:31 +0100 Subject: [PATCH 607/878] gpsrec can now graph altitude & speed --- apps.json | 4 +- apps/gpsrec/ChangeLog | 1 + apps/gpsrec/app.js | 92 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 94 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 75f010fcd..e96b19d63 100644 --- a/apps.json +++ b/apps.json @@ -317,7 +317,7 @@ { "id": "gpsrec", "name": "GPS Recorder", "icon": "app.png", - "version":"0.09", + "version":"0.10", "interface": "interface.html", "description": "Application that allows you to record a GPS track. Can run in background", "tags": "tool,outdoors,gps,widget", @@ -1826,7 +1826,7 @@ {"name":"animclk.img","url":"app-icon.js","evaluate":true} ] }, - { + { "id": "verticalface", "name": "Vertical watch face", "shortName":"Vertical Face", diff --git a/apps/gpsrec/ChangeLog b/apps/gpsrec/ChangeLog index 469671b38..489e2d366 100644 --- a/apps/gpsrec/ChangeLog +++ b/apps/gpsrec/ChangeLog @@ -10,3 +10,4 @@ 0.09: Change default GPS period to 10 (1 is overkill for most uses and makes things slow) Added RAM keyword to functions & other tweaks to speed up rendering Going 'back' from track view now doesn't load again +0.10: Can now graph altitude & speed diff --git a/apps/gpsrec/app.js b/apps/gpsrec/app.js index aeea18bc2..10aa0ebbf 100644 --- a/apps/gpsrec/app.js +++ b/apps/gpsrec/app.js @@ -129,9 +129,15 @@ function viewTrack(n, info) { menu[info.time.toISOString().substr(0,16).replace("T"," ")] = function(){}; menu["Duration"] = { value : asTime(info.duration)}; menu["Records"] = { value : ""+info.records }; - menu['Plot'] = function() { + menu['Plot Map'] = function() { plotTrack(info); }; + menu['Plot Alt.'] = function() { + plotGraph(info, "altitude"); + }; + menu['Plot Speed'] = function() { + plotGraph(info, "speed"); + }; menu['Erase'] = function() { E.showPrompt("Delete Track?").then(function(v) { if (v) { @@ -215,6 +221,90 @@ function plotTrack(info) { setWatch(function() { viewTrack(info.fn, info); }, BTN3); + g.flip(); +} + +function plotGraph(info, style) { + "ram" + E.showMenu(); // remove menu + E.showMessage("Calculating...","GPS Track "+info.fn); + var filename = getFN(info.fn); + var infn = new Float32Array(200); + var infc = new Uint16Array(200); + var title; + var lt = 0; // last time + var tn = 0; // count for each time period + var strt, dur = info.duration; + var f = require("Storage").open(filename,"r"); + if (f===undefined) return; + var l = f.readLine(f); + var nl = 0, c, i; + if (l!==undefined) { + c = l.split(","); + strt = c[0]/1000; + } + if (style=="altitude") { + title = "Altitude (m)"; + while(l!==undefined) { + ++nl;c=l.split(","); + i = Math.round(200*(c[0]/1000 - strt)/dur); + infn[i]+=+c[3]; + infc[i]++; + l = f.readLine(f); + } + } else if (style=="speed") { + title = "Speed (m/s)"; + var p,lp = Bangle.project({lat:c[1],lon:c[2]}); + var t,dx,dy,d,lt = c[0]/1000; + while(l!==undefined) { + ++nl;c=l.split(","); + i = Math.round(200*(c[0]/1000 - strt)/dur); + t = c[0]/1000; + p = Bangle.project({lat:c[1],lon:c[2]}); + dx = p.x-lp.x; + dy = p.y-lp.y; + d = Math.sqrt(dx*dx+dy*dy); + if (t!=lt) { + infn[i]+=d / (t-lt); // speed + infc[i]++; + } + lp = p; + lt = t; + l = f.readLine(f); + } + } else throw new Error("Unknown type"); + var min=100000,max=-100000; + for (var i=0;i0) infn[i]/=infc[i]; + var n = infn[i]; + if (n>max) max=n; + if (n 8) { + grid*=2; + } + // draw + g.clear(1).setFont("6x8",1); + var r = require("graph").drawLine(g, infn, { + x:4,y:0, + width: g.getWidth()-24, + height: g.getHeight()-8, + axes : true, + gridy : grid, + gridx : 50, + title: title, + xlabel : x=>Math.round(x*dur/(60*infn.length))+" min" // minutes + }); + g.setFont("6x8",2); + g.setFontAlign(0,0,3); + g.drawString("Back",230,200); + setWatch(function() { + viewTrack(info.fn, info); + }, BTN3); + g.flip(); } showMainMenu(); From 42180a1770376ec1baeb37e433b902598b26784b Mon Sep 17 00:00:00 2001 From: Richard Hopkins Date: Mon, 1 Jun 2020 00:46:27 +0100 Subject: [PATCH 608/878] New screens, buttons and icons --- apps/BLEcontroller/README.md | 30 ++- apps/BLEcontroller/app.js | 369 +++++++++++++++++++++++++++++++++-- 2 files changed, 381 insertions(+), 18 deletions(-) diff --git a/apps/BLEcontroller/README.md b/apps/BLEcontroller/README.md index 049a5f824..237392e1e 100644 --- a/apps/BLEcontroller/README.md +++ b/apps/BLEcontroller/README.md @@ -2,25 +2,43 @@ A highly customisable state machine driven user interface that will communicate with another BLE device. The controller uses the three buttons and the left and right hand side of the watch to provide a flexible and attractive BLE interface. Amaze your friends by controlling your robot from your watch! -Commands are sent from the Controller to the BLE robot in a JSON format. +To keep the messages small, commands are sent from the Controller to the BLE robot in a text string. This is made up of a comma delimited string of the following elements: +* message number (3 characters) +* screen name (3 characters) +* object name (3 characters) +* value/status (3 characters) + +The combination of these variables will uniquely identify the status change requested from the watch to the robot that can then be programmed to respond appropriately. ## Usage -The application can be configured at will by chaning the definitions of the screens, events, icons and buttons. +The application can be configured at will by changing the definitions of the screens, events, icons and buttons. Most changes are possible via data, rather than code change. ## Features -In its default state, it has three screens that provide the ability to: -turn the robot on or off -turn on and off its voice and microphone -make the robot move by spinning left or right and moving forward and backwards +In its default state, it has nine screens that provide the ability to: +* select which robot to interact with (dog or dalek) + * for the dog the following functions are available: + * control movement via a joystick (forwards, backwards, spin left, spin right) + * turn on/off follow mode + * start a game of chess + * wake or sleep the robot + * wag its tail in two directions + * for the dalek, the user can: + * turn on or off face recognition + * make it say random phrases + * control the dalek's iris light and servo + * turn the dalek hover lights on or off + * turn the speaker on or off ## Controls The controls will vary by screen, but I suggest a convention of using BTN3 (the bottom button) for moving backwards up the menu stack. +I have used the convention of red/green for buttons that are switches and blue buttons that provide single function operation (such as navigating a menu or executing a on-off activity) + ## Requests In the first instance, please consult my blog post on this application here. diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 3afae6b4b..6200600f1 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -80,11 +80,11 @@ const icons = [ }, { name: "left", - data: "gEBAP4B/AP4BKa9ojHAC5pfHJKDTUsYdZHb6ZfO+I9dABabdLbIBdHf473PP47NJdY7/ePIB/RJop5Ys7t/AP6PvD7o7fP8Y1zTZoHPf/4B/AP4B+A==" + data: "gEBAP4B/AP4BKa9ojHAC5pfHJKDTUsYdZHb6ZfO+I9dABabdLbIBdHf473PP47NJdY7/ePIB/RJop5Ys7t/AP6PvD7o7fP8Y1zTZoHPf/4B/AP4B+A==" }, { name: "right", - data: "gEBAP4B/AP4BKa+oAXDo45hCaqFbUbLBfbbo7bHMojTR7Y5LHa51ZALo75Ov47/FeY77AP4B5WdbF3dv4B/R94fdHb5/jGuabNA57//AP4B/APw=" + data: "gEBAP4B/AP4BKa+oAXDo45hCaqFbUbLBfbbo7bHMojTR7Y5LHa51ZALo75Ov47/FeY77AP4B5WdbF3dv4B/R94fdHb5/jGuabNA57//AP4B/APw=" }, { name: "forward", @@ -117,8 +117,60 @@ const icons = [ { name: "comms", data: "gEBAP4B+QvbF7ABo7/He49tACI7/Hf47zHtI7jJq47lRqoAVEqY7nHsoAZGJo71HrKxfQaY7bdKo7/Hdqz5B5Y7zHK47RD55FRHao3XHKo7JG7L1NHeJTbHboB/AP4BG" + }, + { + name: "dalek", + data: "gEBAP4B/AP4B/AJMQwQBBGucIoMAkADBhFhAoZBcAAQfJhEgB45BCHYMBjGiB4ZLCK5APDFpphBC5AbEJosY0YfCG4IAEJIYdGFYR5LHJYlEAI0Y4cY8YXMOpQBFlNFlMkOZA7MKII7JOAXkE4T1UERKtFHoxJBABY5QiGiD5kANYTnCiFiWIJVOgDZCOra3FoKxFDKI7hADQ7PkEIaoIHEaKYfJAoKPFAJcIGYIJHkI7UgMY8ZFHC5rVDKIZTCDIJhBA4ILBBoYFHC4QBEBogpBjHDdsJJEAoYAHKoTxWWb5tNWZOiHZRbBHbwtLF5ynBL7wtLjHjd6oAZkHkI5JJKAAZ3TkAjJhALBsJ5K0a/KkLvfkMEFpVhO8hrIU4QLGG4QAzkCdVAP4B/AP4Bb" + }, + { + name: "k9", + data: "gEBAP4B/AP4B/AP4B/AP4B/AKAADIf5N/IaIAJJv5LZLeIARffZNdD5JN/KLYATC65RbAGrHlJ/5P/JuYrRJfovNJf4BdAFJL/Jv5N/Jv5L1Jv5PvJv5L7Jv5PpAGpN/dv5HzAP4B/AP4B/AP4B/AP4B/ALg" + }, + { + name: "pawn", + data: "gEBAP4B/AP4B/AP4BEAA455HuY7/Hf47xAB47/PuI1xPZY7/Hf47/G9Y/zHfIATHPI9nHfYB/AOYAfHf4B/AP4B/APA=" + }, + { + name: "facerecog", + data: "gEBAP4BSLuozNH9YpTHsolXPsYfdDraZhELIZhHeLtJELY1VC4Y7HHqoXJABYdNHa5bJDrLvfHfbrPZJI7nGZpdVNJ4lRIpaznRqp1hCq55ZC6IRPd8oPjW8Y5jSr45dEJppNHcIjLHZY5ja6rrhFK45pVqI5rGI4AHHNpx3ANA=" + }, + { + name: "sleep", + data: "gEBAP4B/AP4B2ACY7/Quq95HP45/HP4APOdY7fACZfnHcaZZAL45/HP45/E7YAHCaZFZHfbh/HP45/HOoAHHf4B/AP4B/AP4BIA=" + }, + { + name: "awake", + data: "gEBAP4B/AKyb7HfIAFHPI77Ov451Hf453Hf453HdoAbHf45/Hf5HrHNY7NHNo7/HO47/HO47HHPJ1/Heo51HfoB/ALg=" + }, + { + name: "wag_h", + data: "gEBAP4B/AP4B/AP4B/AP4B/AMwADD+oAFHb4hTHMIlXHMopTHNItPAG47/WfY9tFKY9lEq49hELY7ja8YB/AP4B/AP4B/AP4B/AP4BCA" + }, + { + name: "wag_v", + data: "gEBAP4B/AP4BOafIAHHPI9xAB45vd449rFZIHLHsonJBKa7rGNo7/Hf47/Hf47/Hf47/Hf4xlBKY7hFIoHLQM4rHApK7rAB71xHOo9LHOI9HHOoB/AP4BYA=" + }, + { + name: "happy", + data: "gEBAP4B/AP4BKa+oAXHNITfHK4ZtD5JZfHOojZaMYlXHMYnXHfI5nFaYPLaaIRNHf47/d/47/HtInTCZrfZHa4vNABYlVKLI3PbLrzfD7qTXDLaphHMIpLAB45hIKY1pAP4B/AMA" + }, + { + name: "sad", + data: "gEBAP4B/AP4BKa+oAXHNITfHK4ZtD5JZfHOojZaMYlXHMYnXHfI5nFaYPLaaIRNHf47/d/47/CK4njCZ4APHcIVJBbbdTecYjZHr4fdSa4ZbEZ4lNCaY9dAB45hIKY1pAP4B/AMA" + }, + { + name: "hover", + data: "gEBAP4B/AP7NedL4fZK7ojNHeJ35DJI7vC5Y7tVMI7XHNYnNYro7hHKI7lAK47/HdoAhHPI7/Hf47/Hf4AtHPI7/Hf47/Hd45LAP4B/ANwA=" + }, + { + name: "light", + data: "gEBAP4B/APi/Na67lfACZ/nNaI9lE6o9jEbI9hD7Y7dDsJZ3D6YRJHdIJHHfaz7Hf5Z/Hf4hZHMIjFEqIVVHsY5hDpI7TEqL1jVsqlTdM55THOJvHOuY7/HfI9JHOI9HHOoBgA==" + }, + { + name: "speak", + data: "gEBAP4B/AP4BIbO4AXG+4/hAEY55HqoArHPI9PHfIAzHf47/Hf47/HeY9xHJI79Hto5NHtY5RHc45THco5VHcI3XHJpHRG7I7LEro5ZG+IB/AP4BwA==" } -]; + ]; /* finds icon data by name in the icon array and returns an image object*/ const drawIcon = (name) => { @@ -163,6 +215,114 @@ var turnRightBtn = { primary_icon: 'right', }; +var k9Btn = { + primary_colour: 0x653E, + primary_text: 'K9', + primary_icon: 'k9', + }; + +var dalekBtn = { + primary_colour: 0x33F9, + primary_text: 'Dalek', + primary_icon: 'dalek', + }; + +var tailHBtn = { + primary_colour: 0x653E, + primary_text: 'Wag Tail', + primary_icon: 'wag_h', + }; + +var tailVBtn = { + primary_colour: 0x33F9, + primary_text: 'Wag Tail', + primary_icon: 'wag_v', + }; + +var happyBtn = { + primary_colour: 0x653E, + primary_text: 'Speak', + primary_icon: 'happy', + }; + +var sadBtn = { + primary_colour: 0x33F9, + primary_text: 'Speak', + primary_icon: 'sad', + }; + +var speakBtn = { + primary_colour: 0x33F9, + primary_text: 'Speak', + primary_icon: 'speak', + }; + +var faceBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'facerecog', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'facerecog', + value: status_face + }; + +var chessBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'pawn', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'pawn', + value: status_chess + }; + +var irisLightBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'light', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'light', + value: status_iris_light + }; + +var irisBtn = { + primary_colour: 0xE9C7, + primary_text: 'Closed', + primary_icon: 'sleep', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'Open', + secondary_icon : 'awake', + value: status_iris + }; + +var wakeBtn = { + primary_colour: 0xE9C7, + primary_text: 'Sleeping', + primary_icon: 'sleep', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'Awake', + secondary_icon : 'awake', + value: status_wake + }; + +var hoverBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'hover', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'hover', + value: status_hover + }; + var autoBtn = { primary_colour: 0xE9C7, primary_text: 'Stop', @@ -207,9 +367,16 @@ are defined as btn1, bt2 and bt3. The values are names from the icon array. */ const menuScreen = { - left: autoBtn, + left: k9Btn, + right: dalekBtn, +}; + +const k9MenuScreen = { + left: wakeBtn, right: joystickBtn, - btn1: "comms" + btn1: "pawn", + btn2: "wag_h", + btn3: "back" }; const joystickScreen = { @@ -220,12 +387,50 @@ const joystickScreen = { btn3: "back" }; +const tailScreen = { + left: tailHBtn, + right: tailVBtn, + btn3: "back" +}; + const commsScreen = { left: micBtn, right: spkBtn, btn3: "back" }; +const dalekMenuScreen = { + left: faceBtn, + right: speakBtn, + btn1: "hover", + btn2: "light", + btn3: "back" +}; + +const speakScreen = { + left: happyBtn, + right: sadBtn, + btn3: "back" +}; + +const irisScreen = { + left: irisBtn, + right: irisBirisLightBtn, + btn3: "back" +}; + +const lightsScreen = { + left: hoverBtn, + right: spkBtn, + btn3: "back" +}; + +const chessScreen = { + left: chessBtn, + right: autoBtn, + btn3: "back" +}; + /* base state definition Each of the screens correspond to a state; this class provides a constuctor for each @@ -270,15 +475,32 @@ const Home = new State({ screen: menuScreen, events: (event) => { if ((event.object == "right") && (event.status == "end")) { - transmit("Joystick", "joystick", "on"); - return Joystick; - } - if ((event.object == "top") && (event.status == "end")) { - return Comms; + return DalekMenu; } if ((event.object == "left") && (event.status == "end")) { - status_auto.value = !status_auto.value; - transmit(this.state, "auto", onOff(status_auto.value)); + //status_auto.value = !status_auto.value; + //transmit(this.state, "auto", onOff(status_auto.value)); + //return this; + return K9Menu; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const K9Menu = new State({ + state: "K9Menu", + screen: k9MenuScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return Home; + } + if ((event.object == "right") && (event.status == "end")) { + return Joystick; + } + if ((event.object == "left") && (event.status == "end")) { + status_wake.value = !status_wake.value; + transmit(this.state, "auto", onOff(status_wake.value)); return this; } transmit(this.state, event.object, event.status); @@ -286,6 +508,129 @@ const Home = new State({ } }); +const DalekMenu = new State({ + state: "DalekMenu", + screen: dalekMenuScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return Home; + } + if ((event.object == "right") && (event.status == "end")) { + return Speak; + } + if ((event.object == "left") && (event.status == "end")) { + status_face.value = !status_face.value; + transmit(this.state, "face", onOff(status_face.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Speak = new State({ + state: "Speak", + screen: speakScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return DalekMenu; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Chess = new State({ + state: "Chess", + screen: chessScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return K9Menu; + } + if ((event.object == "right") && (event.status == "end")) { + status_auto.value = !status_auto.value; + transmit(this.state, "follow", onOff(status_auto.value)); + return this; + } + if ((event.object == "left") && (event.status == "end")) { + status_chess.value = !status_chess.value; + transmit(this.state, "chess", onOff(status_chess.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Tail = new State({ + state: "Tail", + screen: tailScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return K9Menu; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Speak = new State({ + state: "Speak", + screen: speakScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return DalekMenu; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Iris = new State({ + state: "Iris", + screen: irisScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return DalekMenu; + } + if ((event.object == "right") && (event.status == "end")) { + status_iris_light.value = !status_iris_light.value; + transmit(this.state, "iris_light", onOff(status_iris_light.value)); + return this; + } + if ((event.object == "left") && (event.status == "end")) { + status_iris.value = !status_iris.value; + transmit(this.state, "iris_servo", onOff(status_iris.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Lights = new State({ + state: "Lights", + screen: lightsScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return DalekMenu; + } + if ((event.object == "right") && (event.status == "end")) { + status_spk.value = !status_spk.value; + transmit(this.state, "iris_light", onOff(status_spk.value)); + return this; + } + if ((event.object == "left") && (event.status == "end")) { + status_hover.value = !status_hover.value; + transmit(this.state, "hover", onOff(status_hover.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + + /* Joystick page state */ const Joystick = new State({ state: "Joystick", From 207fabeb1d2222a047c1db6ac9838e8ad0b18446 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 1 Jun 2020 08:40:46 +0100 Subject: [PATCH 609/878] version bump --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index e96b19d63..09c7f9390 100644 --- a/apps.json +++ b/apps.json @@ -1024,7 +1024,7 @@ "name": "Commandline-Clock", "shortName":"CLI-Clock", "icon": "app.png", - "version":"0.07", + "version":"0.08", "description": "Simple CLI-Styled Clock", "tags": "clock,cli,command,bash,shell", "type":"clock", From 46121e60a0aa71ffb7aec3d5a7ecb975a2077c9b Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 1 Jun 2020 08:43:33 +0100 Subject: [PATCH 610/878] Fix `marked is not defined` error (and include in repo, just in case) --- CHANGELOG.md | 1 + index.html | 6 +++--- lib/marked.min.js | 6 ++++++ 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 lib/marked.min.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 48bfe74ec..66dc20b5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,3 +20,4 @@ Changed for individual apps are listed in `apps/appname/ChangeLog` * New 'espruinotools' which fixes pretokenise issue when ID follows ID (fix #416) * Improve upload of binary files * App description can now be markdown +* Fix `marked is not defined` error (and include in repo, just in case) diff --git a/index.html b/index.html index 480fdd2e1..f0f54c248 100644 --- a/index.html +++ b/index.html @@ -174,14 +174,14 @@ + + + - - - diff --git a/lib/marked.min.js b/lib/marked.min.js new file mode 100644 index 000000000..b9d0f20e6 --- /dev/null +++ b/lib/marked.min.js @@ -0,0 +1,6 @@ +/** + * marked - a markdown parser + * Copyright (c) 2011-2020, Christopher Jeffrey. (MIT Licensed) + * https://github.com/markedjs/marked + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).marked=t()}(this,function(){"use strict";function s(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[t++]}};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function n(e){return c[e]}var e,t=(function(t){function e(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}t.exports={defaults:e(),getDefaults:e,changeDefaults:function(e){t.exports.defaults=e}}}(e={exports:{}}),e.exports),i=(t.defaults,t.getDefaults,t.changeDefaults,/[&<>"']/),a=/[&<>"']/g,l=/[<>"']|&(?!#?\w+;)/,o=/[<>"']|&(?!#?\w+;)/g,c={"&":"&","<":"<",">":">",'"':""","'":"'"};var h=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function u(e){return e.replace(h,function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""})}var p=/(^|[^\[])\^/g;var f=/[^\w:]/g,d=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;var k={},b=/^[^:]+:\/*[^/]*$/,m=/^([^:]+:)[\s\S]*$/,x=/^([^:]+:\/*[^/]*)[\s\S]*$/;function w(e,t){k[" "+e]||(b.test(e)?k[" "+e]=e+"/":k[" "+e]=v(e,"/",!0));var n=-1===(e=k[" "+e]).indexOf(":");return"//"===t.substring(0,2)?n?t:e.replace(m,"$1")+t:"/"===t.charAt(0)?n?t:e.replace(x,"$1")+t:e+t}function v(e,t,n){var r=e.length;if(0===r)return"";for(var i=0;it)n.splice(t);else for(;n.length=r.length?e.slice(r.length):e}).join("\n")}(n,t[3]||"");return{type:"code",raw:n,lang:t[2]?t[2].trim():t[2],text:r}}},t.heading=function(e){var t=this.rules.block.heading.exec(e);if(t)return{type:"heading",raw:t[0],depth:t[1].length,text:t[2]}},t.nptable=function(e){var t=this.rules.block.nptable.exec(e);if(t){var n={type:"table",header:O(t[1].replace(/^ *| *\| *$/g,"")),align:t[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:t[3]?t[3].replace(/\n$/,"").split("\n"):[],raw:t[0]};if(n.header.length===n.align.length){for(var r=n.align.length,i=0;i ?/gm,"");return{type:"blockquote",raw:t[0],text:n}}},t.list=function(e){var t=this.rules.block.list.exec(e);if(t){for(var n,r,i,s,a,l,o,c=t[0],h=t[2],u=1/i.test(r[0])&&(t=!1),!n&&/^<(pre|code|kbd|script)(\s|>)/i.test(r[0])?n=!0:n&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(r[0])&&(n=!1),{type:this.options.sanitize?"text":"html",raw:r[0],inLink:t,inRawBlock:n,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(r[0]):C(r[0]):r[0]}},t.link=function(e){var t=this.rules.inline.link.exec(e);if(t){var n,r=j(t[2],"()");-1$/,"$1"))?s.replace(this.rules.inline._escapes,"$1"):s,title:a?a.replace(this.rules.inline._escapes,"$1"):a},t[0])}},t.reflink=function(e,t){var n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){var r=(n[2]||n[1]).replace(/\s+/g," ");if((r=t[r.toLowerCase()])&&r.href)return E(n,r,n[0]);var i=n[0].charAt(0);return{type:"text",raw:i,text:i}}},t.strong=function(e){var t=this.rules.inline.strong.exec(e);if(t)return{type:"strong",raw:t[0],text:t[4]||t[3]||t[2]||t[1]}},t.em=function(e){var t=this.rules.inline.em.exec(e);if(t)return{type:"em",raw:t[0],text:t[6]||t[5]||t[4]||t[3]||t[2]||t[1]}},t.codespan=function(e){var t=this.rules.inline.code.exec(e);if(t){var n=t[2].replace(/\n/g," "),r=/[^ ]/.test(n),i=n.startsWith(" ")&&n.endsWith(" ");return r&&i&&(n=n.substring(1,n.length-1)),n=C(n,!0),{type:"codespan",raw:t[0],text:n}}},t.br=function(e){var t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}},t.del=function(e){var t=this.rules.inline.del.exec(e);if(t)return{type:"del",raw:t[0],text:t[1]}},t.autolink=function(e,t){var n=this.rules.inline.autolink.exec(e);if(n){var r,i="@"===n[2]?"mailto:"+(r=C(this.options.mangle?t(n[1]):n[1])):r=C(n[1]);return{type:"link",raw:n[0],text:r,href:i,tokens:[{type:"text",raw:r,text:r}]}}},t.url=function(e,t){var n,r,i,s;if(n=this.rules.inline.url.exec(e)){if("@"===n[2])i="mailto:"+(r=C(this.options.mangle?t(n[0]):n[0]));else{for(;s=n[0],n[0]=this.rules.inline._backpedal.exec(n[0])[0],s!==n[0];);r=C(n[0]),i="www."===n[1]?"http://"+r:r}return{type:"link",raw:n[0],text:r,href:i,tokens:[{type:"text",raw:r,text:r}]}}},t.inlineText=function(e,t,n){var r=this.rules.inline.text.exec(e);if(r){var i=t?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(r[0]):C(r[0]):r[0]:C(this.options.smartypants?n(r[0]):r[0]);return{type:"text",raw:r[0],text:i}}},e}(),L=S,P=z,U=A,B={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6}) +([^\n]*?)(?: +#+)? *(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?\\?>\\n*|\\n*|\\n*|)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,nptable:L,table:L,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/};B.def=P(B.def).replace("label",B._label).replace("title",B._title).getRegex(),B.bullet=/(?:[*+-]|\d{1,9}\.)/,B.item=/^( *)(bull) ?[^\n]*(?:\n(?!\1bull ?)[^\n]*)*/,B.item=P(B.item,"gm").replace(/bull/g,B.bullet).getRegex(),B.list=P(B.list).replace(/bull/g,B.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+B.def.source+")").getRegex(),B._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",B._comment=//,B.html=P(B.html,"i").replace("comment",B._comment).replace("tag",B._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),B.paragraph=P(B._paragraph).replace("hr",B.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|!--)").replace("tag",B._tag).getRegex(),B.blockquote=P(B.blockquote).replace("paragraph",B.paragraph).getRegex(),B.normal=U({},B),B.gfm=U({},B.normal,{nptable:"^ *([^|\\n ].*\\|.*)\\n *([-:]+ *\\|[-| :]*)(?:\\n((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)",table:"^ *\\|(.+)\\n *\\|?( *[-:]+[-| :]*)(?:\\n *((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),B.gfm.nptable=P(B.gfm.nptable).replace("hr",B.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|!--)").replace("tag",B._tag).getRegex(),B.gfm.table=P(B.gfm.table).replace("hr",B.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|!--)").replace("tag",B._tag).getRegex(),B.pedantic=U({},B.normal,{html:P("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",B._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/,fences:L,paragraph:P(B.normal._paragraph).replace("hr",B.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",B.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});var F={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:L,tag:"^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,strong:/^__([^\s_])__(?!_)|^\*\*([^\s*])\*\*(?!\*)|^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)/,em:/^_([^\s_])_(?!_)|^_([^\s_<][\s\S]*?[^\s_])_(?!_|[^\s,punctuation])|^_([^\s_<][\s\S]*?[^\s])_(?!_|[^\s,punctuation])|^\*([^\s*<\[])\*(?!\*)|^\*([^\s<"][\s\S]*?[^\s\[\*])\*(?![\]`punctuation])|^\*([^\s*"<\[][\s\S]*[^\s])\*(?!\*)/,code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:L,text:/^(`+|[^`])(?:[\s\S]*?(?:(?=[\\?@\\[^_{|}~"};F.em=P(F.em).replace(/punctuation/g,F._punctuation).getRegex(),F._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,F._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,F._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,F.autolink=P(F.autolink).replace("scheme",F._scheme).replace("email",F._email).getRegex(),F._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,F.tag=P(F.tag).replace("comment",B._comment).replace("attribute",F._attribute).getRegex(),F._label=/(?:\[[^\[\]]*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,F._href=/<(?:\\[<>]?|[^\s<>\\])*>|[^\s\x00-\x1f]*/,F._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,F.link=P(F.link).replace("label",F._label).replace("href",F._href).replace("title",F._title).getRegex(),F.reflink=P(F.reflink).replace("label",F._label).getRegex(),F.normal=U({},F),F.pedantic=U({},F.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,link:P(/^!?\[(label)\]\((.*?)\)/).replace("label",F._label).getRegex(),reflink:P(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",F._label).getRegex()}),F.gfm=U({},F.normal,{escape:P(F.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^~+(?=\S)([\s\S]*?\S)~+/,text:/^(`+|[^`])(?:[\s\S]*?(?:(?=[\\'+(n?e:Q(e,!0))+"\n":"
"+(n?e:Q(e,!0))+"
\n"},t.blockquote=function(e){return"
\n"+e+"
\n"},t.html=function(e){return e},t.heading=function(e,t,n,r){return this.options.headerIds?"'+e+"\n":""+e+"\n"},t.hr=function(){return this.options.xhtml?"
\n":"
\n"},t.list=function(e,t,n){var r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+"\n"},t.listitem=function(e){return"
  • "+e+"
  • \n"},t.checkbox=function(e){return" "},t.paragraph=function(e){return"

    "+e+"

    \n"},t.table=function(e,t){return"\n\n"+e+"\n"+(t=t&&""+t+"")+"
    \n"},t.tablerow=function(e){return"\n"+e+"\n"},t.tablecell=function(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' align="'+t.align+'">':"<"+n+">")+e+"\n"},t.strong=function(e){return""+e+""},t.em=function(e){return""+e+""},t.codespan=function(e){return""+e+""},t.br=function(){return this.options.xhtml?"
    ":"
    "},t.del=function(e){return""+e+""},t.link=function(e,t,n){if(null===(e=K(this.options.sanitize,this.options.baseUrl,e)))return n;var r='"},t.image=function(e,t,n){if(null===(e=K(this.options.sanitize,this.options.baseUrl,e)))return n;var r=''+n+'":">"},t.text=function(e){return e},e}(),ee=function(){function e(){}var t=e.prototype;return t.strong=function(e){return e},t.em=function(e){return e},t.codespan=function(e){return e},t.del=function(e){return e},t.html=function(e){return e},t.text=function(e){return e},t.link=function(e,t,n){return""+n},t.image=function(e,t,n){return""+n},t.br=function(){return""},e}(),te=function(){function e(){this.seen={}}return e.prototype.slug=function(e){var t=e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-");if(this.seen.hasOwnProperty(t))for(var n=t;this.seen[n]++,t=n+"-"+this.seen[n],this.seen.hasOwnProperty(t););return this.seen[t]=0,t},e}(),ne=t.defaults,re=_,ie=function(){function n(e){this.options=e||ne,this.options.renderer=this.options.renderer||new Y,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new ee,this.slugger=new te}n.parse=function(e,t){return new n(t).parse(e)};var e=n.prototype;return e.parse=function(e,t){void 0===t&&(t=!0);for(var n,r,i,s,a,l,o,c,h,u,p,g,f,d,k,b,m,x="",w=e.length,v=0;vAn error occurred:

    "+le(e.message+"",!0)+"
    ";throw e}}return ue.options=ue.setOptions=function(e){return se(ue.defaults,e),ce(ue.defaults),ue},ue.getDefaults=oe,ue.defaults=he,ue.use=function(l){var t,n=se({},l);l.renderer&&function(){var a=ue.defaults.renderer||new Y;for(var e in l.renderer)!function(i){var s=a[i];a[i]=function(){for(var e=arguments.length,t=new Array(e),n=0;n Date: Mon, 1 Jun 2020 09:32:47 +0100 Subject: [PATCH 611/878] fix travis errors --- .eslintignore | 2 +- apps.json | 2 +- apps/verticalface/ChangeLog | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 apps/verticalface/ChangeLog diff --git a/.eslintignore b/.eslintignore index 544f416aa..550fbda3f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,5 +2,5 @@ lib/espruinotools.js lib/imageconverter.js lib/qrcode.min.js lib/heatshrink.js - +lib/marked.min.js apps/animclk/V29.LBM.js diff --git a/apps.json b/apps.json index 09c7f9390..5eb039b53 100644 --- a/apps.json +++ b/apps.json @@ -1831,7 +1831,7 @@ "name": "Vertical watch face", "shortName":"Vertical Face", "icon": "app.png", - "version":"0.4.1", + "version":"0.04", "description": "A simple vertical watch face with the date.", "tags": "clock", "type":"clock", diff --git a/apps/verticalface/ChangeLog b/apps/verticalface/ChangeLog new file mode 100644 index 000000000..19d763698 --- /dev/null +++ b/apps/verticalface/ChangeLog @@ -0,0 +1 @@ +0.04: Fixed day being displayed From 5bc70b474c0121bc26e7efdf4be07d6a3f876a4f Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 10:42:57 +0100 Subject: [PATCH 612/878] Merge didn't; t work --- apps.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 883a3cdf9..d266cd0c0 100644 --- a/apps.json +++ b/apps.json @@ -1768,11 +1768,10 @@ "storage": [ { "name": "jbm8b.app.js", "url": "app.js" }, { "name": "jbm8b.img", "url": "app-icon.js", "evaluate": true } - ], + ] "version": "0.03" }, -{ - "id": "BLEcontroller", + { "id": "BLEcontroller", "name": "BLE Robot Controller with Joystick", "shortName": "BLE Controller", "icon": "BLEcontroller.png", @@ -1784,6 +1783,8 @@ "storage": [ { "name": "BLEcontroller.app.js", "url": "app.js" }, { "name": "BLEcontroller.img", "url": "app-icon.js", "evaluate": true } + ] + }, { "id": "widviz", "name": "Widget Visibility Widget", "shortName":"Viz Widget", From 6aad4d8f93413c30c3d6b579040920a2c87124b8 Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 11:27:51 +0100 Subject: [PATCH 613/878] Fixing JSON --- apps.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index d266cd0c0..6c0f50eca 100644 --- a/apps.json +++ b/apps.json @@ -1765,11 +1765,11 @@ "icon": "app.png", "description": "A simple fortune telling app", "tags": "game", + "version": "0.03", "storage": [ { "name": "jbm8b.app.js", "url": "app.js" }, { "name": "jbm8b.img", "url": "app-icon.js", "evaluate": true } - ] - "version": "0.03" + ] }, { "id": "BLEcontroller", "name": "BLE Robot Controller with Joystick", From 26d0fd32792b755c012223a982bf6b8b54b43dd1 Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 11:40:59 +0100 Subject: [PATCH 614/878] Adding variable declarations and syntax error --- apps/BLEcontroller/app.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 6200600f1..7ba95589d 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -1,6 +1,6 @@ /* ========================================================== -Simple event based robot controller that enables robot +Simple event based robot controller that enables robot to switch into automatic or manual control modes. Behaviours are controlled via a simple finite state machine. In automatic mode the @@ -19,7 +19,7 @@ bottom_btn = false; msgNum = 0; // message number -/* +/* CONFIGURATION AREA - STATE VARIABLES declare global variables for the toggle button statuses; if you add an additional toggle button @@ -28,6 +28,12 @@ you should declare it and initiase it here */ var status_auto = {value: false}; var status_mic = {value: true}; var status_spk = {value: true}; +var status_face = {value: true}; +var status_chess = {value: false}; +var status_iris_light = {value: false}; +var status_iris = {value: false}; +var status_wake = {value: false}; +var status_hover = {value: false}; /* trsnsmit message where @@ -415,7 +421,7 @@ const speakScreen = { const irisScreen = { left: irisBtn, - right: irisBirisLightBtn, + right: irisLightBtn, btn3: "back" }; @@ -431,9 +437,9 @@ const chessScreen = { btn3: "back" }; -/* base state definition +/* base state definition Each of the screens correspond to a state; -this class provides a constuctor for each +this class provides a constuctor for each of the states */ class State { @@ -605,7 +611,7 @@ const Iris = new State({ } transmit(this.state, event.object, event.status); return this; - } + } }); const Lights = new State({ @@ -627,7 +633,7 @@ const Lights = new State({ } transmit(this.state, event.object, event.status); return this; - } + } }); @@ -676,7 +682,7 @@ const onOff= status => status ? "on" : "off"; /* create watching functions that will change the global -button status when pressed or released +button status when pressed or released This is actuslly the hesrt of the program. When a button is not being pressed, nothing is happening (no loops). This makes the progrsm more battery efficient. @@ -684,7 +690,7 @@ When a setWatch event is raised, the custom callbacks defined here will be called. These then fired as events to the current state/screen of the state mschine. Some events, will result in the stste of the state machine -chsnging, which is why the screen is redrswn after each +chsnging, which is why the screen is redrswn after each button press. */ const setMyWatch = (params) => { @@ -742,4 +748,4 @@ const drawScreen = (params) => { machine = Home; // instantiate the state machine at Home Bangle.drawWidgets(); // draw active widgets -drawScreen(machine.screen); // draw the screen \ No newline at end of file +drawScreen(machine.screen); // draw the screen From a5cc710ef84f053b598fad8eb0c2e3834140d1c9 Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 11:44:27 +0100 Subject: [PATCH 615/878] Syntax error --- apps/BLEcontroller/app.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 7ba95589d..2ad91ba54 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -580,18 +580,6 @@ const Tail = new State({ } }); -const Speak = new State({ - state: "Speak", - screen: speakScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return DalekMenu; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - const Iris = new State({ state: "Iris", screen: irisScreen, From b929b5d0cbe903070f741510f4681e23333e3951 Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 14:19:23 +0100 Subject: [PATCH 616/878] Splitting app into three variants --- apps/BLEcontroller/README.md | 32 +- apps/BLEcontroller/app-big.js | 739 ++++++++++++++++++++++++++++++++++ apps/BLEcontroller/app.js | 520 ++++-------------------- 3 files changed, 824 insertions(+), 467 deletions(-) create mode 100644 apps/BLEcontroller/app-big.js diff --git a/apps/BLEcontroller/README.md b/apps/BLEcontroller/README.md index 237392e1e..56f1a2658 100644 --- a/apps/BLEcontroller/README.md +++ b/apps/BLEcontroller/README.md @@ -1,14 +1,18 @@ -# BLE Robot Controller with Joystick +# BLE Generic Controller with Joystick -A highly customisable state machine driven user interface that will communicate with another BLE device. The controller uses the three buttons and the left and right hand side of the watch to provide a flexible and attractive BLE interface. Amaze your friends by controlling your robot from your watch! +A highly customisable state machine driven user interface that will communicate with another BLE device. The controller uses the three buttons and the left and right hand side of the watch to provide a flexible and attractive BLE interface. -To keep the messages small, commands are sent from the Controller to the BLE robot in a text string. This is made up of a comma delimited string of the following elements: +Amaze your friends by controlling your robot, your house or any other BLE device from your watch! + +To keep the messages small, commands are sent from the Controller to the BLE target in a text string. This is made up of a comma delimited string of the following elements: * message number (3 characters) * screen name (3 characters) * object name (3 characters) * value/status (3 characters) -The combination of these variables will uniquely identify the status change requested from the watch to the robot that can then be programmed to respond appropriately. +The combination of these variables will uniquely identify the status change requested from the watch to the target device that can then be programmed to respond appropriately. + +Gordon Williams' EspruinoHub is an excellent way to transform BLE advertisements into MQTT messages for further processing. ## Usage @@ -18,20 +22,12 @@ Most changes are possible via data, rather than code change. ## Features -In its default state, it has nine screens that provide the ability to: -* select which robot to interact with (dog or dalek) - * for the dog the following functions are available: - * control movement via a joystick (forwards, backwards, spin left, spin right) - * turn on/off follow mode - * start a game of chess - * wake or sleep the robot - * wag its tail in two directions - * for the dalek, the user can: - * turn on or off face recognition - * make it say random phrases - * control the dalek's iris light and servo - * turn the dalek hover lights on or off - * turn the speaker on or off +The default package contains three configurations: +* a simple home light and sockets controller UI (app.js) +* a robot controller UI with joystick (app-joy.js) +* a simple static assistant controller (app-ass.js) + +You can try out the other configurations by deleting app.js and renaming the file you want to app.js. ## Controls diff --git a/apps/BLEcontroller/app-big.js b/apps/BLEcontroller/app-big.js new file mode 100644 index 000000000..2ad91ba54 --- /dev/null +++ b/apps/BLEcontroller/app-big.js @@ -0,0 +1,739 @@ +/* +========================================================== +Simple event based robot controller that enables robot +to switch into automatic or manual control modes. Behaviours +are controlled via a simple finite state machine. +In automatic mode the +robot will look after itself. In manual mode, the watch +will provide simple forward, back, left and right commands. +The messages will be transmitted to a partner BLE Espruino +using BLE +Written by Richard Hopkins, May 2020 +========================================================== +declare global variables for watch button statuses */ +top_btn = false; +middle_btn = false; +left_btn= false; // the left side of the touch screen +right_btn = false; // the right side of the touch screen +bottom_btn = false; + +msgNum = 0; // message number + +/* +CONFIGURATION AREA - STATE VARIABLES +declare global variables for the toggle button +statuses; if you add an additional toggle button +you should declare it and initiase it here */ + +var status_auto = {value: false}; +var status_mic = {value: true}; +var status_spk = {value: true}; +var status_face = {value: true}; +var status_chess = {value: false}; +var status_iris_light = {value: false}; +var status_iris = {value: false}; +var status_wake = {value: false}; +var status_hover = {value: false}; + +/* trsnsmit message +where +s = first character of state, +o = first three character of object name +v = value of state.object +*/ + +const transmit = (state,object,status) => { + msgNum ++; + msg = { + n: msgNum.toString().slice(-4), + s: state.substr(0,4), + o: object.substr(0,4), + v: status.substr(0.4), + }; + message= msg.n + "," + msg.s + "," + msg.o + "," + msg.v; + NRF.setAdvertising({},{ + showName: false, + manufacturer: 0x0590, + manufacturerData: JSON.stringify(message)}); +}; + +/* +CONFIGURATION AREA - ICON DEFINITIONS +Retrieve 30px PNG icons from: +https://icons8.com/icon/set/speak/ios-glyphs +Create icons using: +https://www.espruino.com/Image+Converter +Use compression: true +Transparency: true +Diffusion: flat +Colours: 16bit RGB +Ouput as: Image Object +Add an additional element to the icons array +with a unique name and the data from the Image Object +*/ +const icons = [ + { + name: "walk", + data: "gEBAP4B/ALyh7b/YALHfY9tACY55HfYdNHto7pHpIbXbL5fXAD6VlHuYAjHf47/Hf47tHK47LDa45zHc4NHHeILJHeonTO9o9rHf47/eOoB/ANg=" + }, + { + name: "sit", + data: "gEBAP4B/AP4BacO4ANHPI/rACp1/Hf49rGtI5/He7n3ACY55HcYAZHf45/Hf45rHe4XHGbI7/Va47zZZrpbHfbtXD5Y/vHcYB/AP4BmA" + }, + { + name: "joystick", + data: "gEBAP4B/AP4BMavIALHPI9vHf47/eP45vHpY5xHo451Hf47/FuYAHHNItHABa33AP6xpAD455HqY7/Hf47/Hd49pHKIB/AP4B/AMwA==" + }, + { + name: "left", + data: "gEBAP4B/AP4BKa9ojHAC5pfHJKDTUsYdZHb6ZfO+I9dABabdLbIBdHf473PP47NJdY7/ePIB/RJop5Ys7t/AP6PvD7o7fP8Y1zTZoHPf/4B/AP4B+A==" + }, + { + name: "right", + data: "gEBAP4B/AP4BKa+oAXDo45hCaqFbUbLBfbbo7bHMojTR7Y5LHa51ZALo75Ov47/FeY77AP4B5WdbF3dv4B/R94fdHb5/jGuabNA57//AP4B/APw=" + }, + { + name: "forward", + data: "gEBAP4B/AKSX5avIALHPI9tACY55HsoAbHPI9fHfZFVGMo7/Hf47/Hf47/Hf47/Hf47/Hf47/Hf47/Hf49XHOIB/ALw=" + }, + { + name: "backward", + data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/Hf47/Hf47/Hf47/HfIAfHf491W/L15HMo9THNI9PHNo9LHOI9HHOoB/ALg=" + }, + { + name: "back", + data: "gEBAP4B/AP4B/AKgADHPI71HP45/HP45/HP45/HP45/Hf49/Hv49/Hv49/Hv49/Hv497He4B/AP4B/AJAA==" + }, + { + name: "spk_on", + data: "gEBAP4B/AP4Bic/YAFPP4v1HrYZRVJo7ZDKp5jMJYvZHaYAHVL4LHACZrhADLBTJKI7dPLI7/Hf47/HeZBVFqZHZRJp1lAJ47LOtZTnHbIZDKLpHNAL69ZANp1tQbY5/AP4B/ANQ" + }, + { + name: "spk_off", + data: "gEBAPhB7P/o9rFKI9pFKY9tXNYZNHrZXfMaoAHPOZhNF7LdXHpKpZEJpvPDZK1ZAB49NPLo9jHdI9NHd49PHebvxEJY9NI6I7dHpaDXcKqfPHLKjZHcpTjHbIZDKa73JHa4BXGY45xe5Y7zV+o9/Hv49JHe4BEA=" + }, + { + name: "mic_on", + data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/GbY7TIcY7/Hf47/Hf47/HdY9NCpp5lCb57fOdYvNeJo91HNrlvHf7tVIdY77AP4BiA=" + }, + { + name: "mic_off", + data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/GbY7TIcY7/Wf47/HJZLjHZ45RHrI7NHJYhLHqoZJA54hNHr5lTXL6vPSra5jKbo9REZrLRHa5DTXp47jAA7TTF7INLRqY7fdKavhXKo5te6wA==" + }, + { + name: "comms", + data: "gEBAP4B+QvbF7ABo7/He49tACI7/Hf47zHtI7jJq47lRqoAVEqY7nHsoAZGJo71HrKxfQaY7bdKo7/Hdqz5B5Y7zHK47RD55FRHao3XHKo7JG7L1NHeJTbHboB/AP4BG" + }, + { + name: "dalek", + data: "gEBAP4B/AP4B/AJMQwQBBGucIoMAkADBhFhAoZBcAAQfJhEgB45BCHYMBjGiB4ZLCK5APDFpphBC5AbEJosY0YfCG4IAEJIYdGFYR5LHJYlEAI0Y4cY8YXMOpQBFlNFlMkOZA7MKII7JOAXkE4T1UERKtFHoxJBABY5QiGiD5kANYTnCiFiWIJVOgDZCOra3FoKxFDKI7hADQ7PkEIaoIHEaKYfJAoKPFAJcIGYIJHkI7UgMY8ZFHC5rVDKIZTCDIJhBA4ILBBoYFHC4QBEBogpBjHDdsJJEAoYAHKoTxWWb5tNWZOiHZRbBHbwtLF5ynBL7wtLjHjd6oAZkHkI5JJKAAZ3TkAjJhALBsJ5K0a/KkLvfkMEFpVhO8hrIU4QLGG4QAzkCdVAP4B/AP4Bb" + }, + { + name: "k9", + data: "gEBAP4B/AP4B/AP4B/AP4B/AKAADIf5N/IaIAJJv5LZLeIARffZNdD5JN/KLYATC65RbAGrHlJ/5P/JuYrRJfovNJf4BdAFJL/Jv5N/Jv5L1Jv5PvJv5L7Jv5PpAGpN/dv5HzAP4B/AP4B/AP4B/AP4B/ALg" + }, + { + name: "pawn", + data: "gEBAP4B/AP4B/AP4BEAA455HuY7/Hf47xAB47/PuI1xPZY7/Hf47/G9Y/zHfIATHPI9nHfYB/AOYAfHf4B/AP4B/APA=" + }, + { + name: "facerecog", + data: "gEBAP4BSLuozNH9YpTHsolXPsYfdDraZhELIZhHeLtJELY1VC4Y7HHqoXJABYdNHa5bJDrLvfHfbrPZJI7nGZpdVNJ4lRIpaznRqp1hCq55ZC6IRPd8oPjW8Y5jSr45dEJppNHcIjLHZY5ja6rrhFK45pVqI5rGI4AHHNpx3ANA=" + }, + { + name: "sleep", + data: "gEBAP4B/AP4B2ACY7/Quq95HP45/HP4APOdY7fACZfnHcaZZAL45/HP45/E7YAHCaZFZHfbh/HP45/HOoAHHf4B/AP4B/AP4BIA=" + }, + { + name: "awake", + data: "gEBAP4B/AKyb7HfIAFHPI77Ov451Hf453Hf453HdoAbHf45/Hf5HrHNY7NHNo7/HO47/HO47HHPJ1/Heo51HfoB/ALg=" + }, + { + name: "wag_h", + data: "gEBAP4B/AP4B/AP4B/AP4B/AMwADD+oAFHb4hTHMIlXHMopTHNItPAG47/WfY9tFKY9lEq49hELY7ja8YB/AP4B/AP4B/AP4B/AP4BCA" + }, + { + name: "wag_v", + data: "gEBAP4B/AP4BOafIAHHPI9xAB45vd449rFZIHLHsonJBKa7rGNo7/Hf47/Hf47/Hf47/Hf4xlBKY7hFIoHLQM4rHApK7rAB71xHOo9LHOI9HHOoB/AP4BYA=" + }, + { + name: "happy", + data: "gEBAP4B/AP4BKa+oAXHNITfHK4ZtD5JZfHOojZaMYlXHMYnXHfI5nFaYPLaaIRNHf47/d/47/HtInTCZrfZHa4vNABYlVKLI3PbLrzfD7qTXDLaphHMIpLAB45hIKY1pAP4B/AMA" + }, + { + name: "sad", + data: "gEBAP4B/AP4BKa+oAXHNITfHK4ZtD5JZfHOojZaMYlXHMYnXHfI5nFaYPLaaIRNHf47/d/47/CK4njCZ4APHcIVJBbbdTecYjZHr4fdSa4ZbEZ4lNCaY9dAB45hIKY1pAP4B/AMA" + }, + { + name: "hover", + data: "gEBAP4B/AP7NedL4fZK7ojNHeJ35DJI7vC5Y7tVMI7XHNYnNYro7hHKI7lAK47/HdoAhHPI7/Hf47/Hf4AtHPI7/Hf47/Hd45LAP4B/ANwA=" + }, + { + name: "light", + data: "gEBAP4B/APi/Na67lfACZ/nNaI9lE6o9jEbI9hD7Y7dDsJZ3D6YRJHdIJHHfaz7Hf5Z/Hf4hZHMIjFEqIVVHsY5hDpI7TEqL1jVsqlTdM55THOJvHOuY7/HfI9JHOI9HHOoBgA==" + }, + { + name: "speak", + data: "gEBAP4B/AP4BIbO4AXG+4/hAEY55HqoArHPI9PHfIAzHf47/Hf47/HeY9xHJI79Hto5NHtY5RHc45THco5VHcI3XHJpHRG7I7LEro5ZG+IB/AP4BwA==" + } + ]; + +/* finds icon data by name in the icon array and returns an image object*/ +const drawIcon = (name) => { + for (var icon of icons) { + if (icon.name == name) { + image = { + width : 30, height : 30, bpp : 16, + transparent : 1, + buffer: require("heatshrink").decompress(atob(icon.data)) + }; + return image;} + } +}; + +/* +CONFIGURATION AREA - BUTTON DEFINITIONS +for a simple button, just define a primary colour +and an icon name from the icon array and +the text to display beneath the button +for toggle buttons, additionally provide secondary +colours, icon name and text. Also provide a reference +to a global variable for the value of the button. +The global variable should be declared at the start of +the program and it may be adviable to use the 'status_name' +format to ensure it is clear. +*/ +var joystickBtn = { + primary_colour: 0x653E, + primary_icon: 'joystick', + primary_text: 'Joystick', + }; + +var turnLeftBtn = { + primary_colour: 0x653E, + primary_text: 'Left', + primary_icon: 'left', + }; + +var turnRightBtn = { + primary_colour: 0x33F9, + primary_text: 'Right', + primary_icon: 'right', + }; + +var k9Btn = { + primary_colour: 0x653E, + primary_text: 'K9', + primary_icon: 'k9', + }; + +var dalekBtn = { + primary_colour: 0x33F9, + primary_text: 'Dalek', + primary_icon: 'dalek', + }; + +var tailHBtn = { + primary_colour: 0x653E, + primary_text: 'Wag Tail', + primary_icon: 'wag_h', + }; + +var tailVBtn = { + primary_colour: 0x33F9, + primary_text: 'Wag Tail', + primary_icon: 'wag_v', + }; + +var happyBtn = { + primary_colour: 0x653E, + primary_text: 'Speak', + primary_icon: 'happy', + }; + +var sadBtn = { + primary_colour: 0x33F9, + primary_text: 'Speak', + primary_icon: 'sad', + }; + +var speakBtn = { + primary_colour: 0x33F9, + primary_text: 'Speak', + primary_icon: 'speak', + }; + +var faceBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'facerecog', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'facerecog', + value: status_face + }; + +var chessBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'pawn', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'pawn', + value: status_chess + }; + +var irisLightBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'light', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'light', + value: status_iris_light + }; + +var irisBtn = { + primary_colour: 0xE9C7, + primary_text: 'Closed', + primary_icon: 'sleep', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'Open', + secondary_icon : 'awake', + value: status_iris + }; + +var wakeBtn = { + primary_colour: 0xE9C7, + primary_text: 'Sleeping', + primary_icon: 'sleep', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'Awake', + secondary_icon : 'awake', + value: status_wake + }; + +var hoverBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'hover', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'hover', + value: status_hover + }; + +var autoBtn = { + primary_colour: 0xE9C7, + primary_text: 'Stop', + primary_icon: 'sit', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'Move', + secondary_icon : 'walk', + value: status_auto + }; + +var micBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'mic_off', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'mic_on', + value: status_mic + }; + +var spkBtn = { + primary_colour: 0xE9C7, + primary_text: 'Off', + primary_icon: 'spk_off', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'On', + secondary_icon : 'spk_on', + value: status_spk + }; + +/* +CONFIGURATION AREA - SCREEN DEFINITIONS +a screen can have a button (as defined above) +on the left and/or the right of the screen. +in adddition a screen can optionally have +an icon for each of the three buttons on +the left hand side of the screen. These +are defined as btn1, bt2 and bt3. The +values are names from the icon array. +*/ +const menuScreen = { + left: k9Btn, + right: dalekBtn, +}; + +const k9MenuScreen = { + left: wakeBtn, + right: joystickBtn, + btn1: "pawn", + btn2: "wag_h", + btn3: "back" +}; + +const joystickScreen = { + left: turnLeftBtn, + right: turnRightBtn, + btn1: "forward", + btn2: "backward", + btn3: "back" +}; + +const tailScreen = { + left: tailHBtn, + right: tailVBtn, + btn3: "back" +}; + +const commsScreen = { + left: micBtn, + right: spkBtn, + btn3: "back" +}; + +const dalekMenuScreen = { + left: faceBtn, + right: speakBtn, + btn1: "hover", + btn2: "light", + btn3: "back" +}; + +const speakScreen = { + left: happyBtn, + right: sadBtn, + btn3: "back" +}; + +const irisScreen = { + left: irisBtn, + right: irisLightBtn, + btn3: "back" +}; + +const lightsScreen = { + left: hoverBtn, + right: spkBtn, + btn3: "back" +}; + +const chessScreen = { + left: chessBtn, + right: autoBtn, + btn3: "back" +}; + +/* base state definition +Each of the screens correspond to a state; +this class provides a constuctor for each +of the states +*/ +class State { + constructor(params) { + this.state = params.state; + this.events = params.events; + this.screen = params.screen; + } +} + +/* +CONFIGURATION AREA - BUTTON BEHAVIOURS/STATE TRANSITIONS +This area defines how each screen behaves. +Each screen corresponds to a different State of the +state machine. This makes it much easier to isolate +behaviours between screens. +The state value is transmitted whenever a button is pressed +to provide context (so the receiving device, knows which +button was pressed on which screen). +The screens are defined above. +The events section identifies if a particular button has been +pressed and released on the screen and an action can then be taken. +The events function receives a notification from a mySetWatch which +provides an event object that identifies which button and whether +it has been pressed down or released. Actions can then be taken. +The events function will always return a State object. +If the events function returns different State from the current +one, then the state machine will change to that new State and redrsw +the screen appropriately. +To add in additional capabilities for button presses, simply add +an additional 'if' statement. +For toggle buttons, the value of the sppropiate status object is +inversed and the new value transmitted. +*/ + +/* The Home State/Page is where the application beings */ +const Home = new State({ + state: "Home", + screen: menuScreen, + events: (event) => { + if ((event.object == "right") && (event.status == "end")) { + return DalekMenu; + } + if ((event.object == "left") && (event.status == "end")) { + //status_auto.value = !status_auto.value; + //transmit(this.state, "auto", onOff(status_auto.value)); + //return this; + return K9Menu; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const K9Menu = new State({ + state: "K9Menu", + screen: k9MenuScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return Home; + } + if ((event.object == "right") && (event.status == "end")) { + return Joystick; + } + if ((event.object == "left") && (event.status == "end")) { + status_wake.value = !status_wake.value; + transmit(this.state, "auto", onOff(status_wake.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const DalekMenu = new State({ + state: "DalekMenu", + screen: dalekMenuScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return Home; + } + if ((event.object == "right") && (event.status == "end")) { + return Speak; + } + if ((event.object == "left") && (event.status == "end")) { + status_face.value = !status_face.value; + transmit(this.state, "face", onOff(status_face.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Speak = new State({ + state: "Speak", + screen: speakScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return DalekMenu; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Chess = new State({ + state: "Chess", + screen: chessScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return K9Menu; + } + if ((event.object == "right") && (event.status == "end")) { + status_auto.value = !status_auto.value; + transmit(this.state, "follow", onOff(status_auto.value)); + return this; + } + if ((event.object == "left") && (event.status == "end")) { + status_chess.value = !status_chess.value; + transmit(this.state, "chess", onOff(status_chess.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Tail = new State({ + state: "Tail", + screen: tailScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return K9Menu; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Iris = new State({ + state: "Iris", + screen: irisScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return DalekMenu; + } + if ((event.object == "right") && (event.status == "end")) { + status_iris_light.value = !status_iris_light.value; + transmit(this.state, "iris_light", onOff(status_iris_light.value)); + return this; + } + if ((event.object == "left") && (event.status == "end")) { + status_iris.value = !status_iris.value; + transmit(this.state, "iris_servo", onOff(status_iris.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +const Lights = new State({ + state: "Lights", + screen: lightsScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return DalekMenu; + } + if ((event.object == "right") && (event.status == "end")) { + status_spk.value = !status_spk.value; + transmit(this.state, "iris_light", onOff(status_spk.value)); + return this; + } + if ((event.object == "left") && (event.status == "end")) { + status_hover.value = !status_hover.value; + transmit(this.state, "hover", onOff(status_hover.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + + +/* Joystick page state */ +const Joystick = new State({ + state: "Joystick", + screen: joystickScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + transmit("Joystick", "joystick", "off"); + return Home; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +/* Comms page state */ +const Comms = new State({ + state: "Comms", + screen: commsScreen, + events: (event) => { + if ((event.object == "bottom") && (event.status == "end")) { + return Home; + } + if ((event.object == "left") && (event.status == "end")) { + status_mic.value = !status_mic.value; + transmit(this.state, "mic", onOff(status_mic.value)); + return this; + } + if ((event.object == "right") && (event.status == "end")) { + status_spk.value = !status_spk.value; + transmit(this.state, "spk", onOff(status_spk.value)); + return this; + } + transmit(this.state, event.object, event.status); + return this; + } +}); + +/* translate button status into english */ +const startEnd = status => status ? "start" : "end"; + +/* translate status into english */ +const onOff= status => status ? "on" : "off"; + + +/* create watching functions that will change the global +button status when pressed or released +This is actuslly the hesrt of the program. When a button +is not being pressed, nothing is happening (no loops). +This makes the progrsm more battery efficient. +When a setWatch event is raised, the custom callbacks defined +here will be called. These then fired as events to the current +state/screen of the state mschine. +Some events, will result in the stste of the state machine +chsnging, which is why the screen is redrswn after each +button press. +*/ +const setMyWatch = (params) => { + setWatch(() => { + params.bool=!params.bool; + machine = machine.events({object: params.label, status: startEnd(params.bool)}); + drawScreen(machine.screen); + }, params.btn, {repeat:true, edge:"both"}); +}; + +/* object array used to set up the watching functions +*/ +const buttons = [ + {bool : bottom_btn, label : "bottom",btn : BTN3}, + {bool : middle_btn, label : "middle",btn : BTN2}, + {bool : top_btn, label : "top",btn : BTN1}, + {bool : left_btn, label : "left",btn : BTN4}, + {bool : right_btn, label : "right",btn : BTN5} + ]; + +/* set up watchers for buttons */ +for (var button of buttons) + {setMyWatch(button);} + +/* Draw various kinds of buttons */ +const drawButton = (params,side) => { + g.setFontAlign(0,1); + icon = drawIcon(params.primary_icon); + text = params.primary_text; + g.setColor(params.primary_colour); + const x = (side == "left") ? 0 : 120; + if ((params.toggle) && (params.value.value)) { + g.setColor(params.secondary_colour); + text = params.secondary_text; + icon = drawIcon(params.secondary_icon); + } + g.fillRect(0+x,24,119+x, 239); + g.setColor(0x000); + g.setFont("Vector",15); + g.setFontAlign(0,0.0); + g.drawString(text,60+x,160); + options = {rotate: 0, scale:2}; + g.drawImage(icon,x+60,120,options); +}; + +/* Draw the pages corresponding to the states */ +const drawScreen = (params) => { + drawButton(params.left,'left'); + drawButton(params.right,'right'); + g.setColor(0x000); + if (params.btn1) {g.drawImage(drawIcon(params.btn1),210,40);} + if (params.btn2) {g.drawImage(drawIcon(params.btn2),210,125);} + if (params.btn3) {g.drawImage(drawIcon(params.btn3),210,195);} +}; + +machine = Home; // instantiate the state machine at Home +Bangle.drawWidgets(); // draw active widgets +drawScreen(machine.screen); // draw the screen diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 2ad91ba54..1b4775ef2 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -25,15 +25,10 @@ declare global variables for the toggle button statuses; if you add an additional toggle button you should declare it and initiase it here */ -var status_auto = {value: false}; -var status_mic = {value: true}; -var status_spk = {value: true}; -var status_face = {value: true}; -var status_chess = {value: false}; -var status_iris_light = {value: false}; -var status_iris = {value: false}; -var status_wake = {value: false}; -var status_hover = {value: false}; +var status_printer = {value: false}; +var status_tv = {value: false}; +var status_light_hall = {value: false}; +var status_light_study = {value: false}; /* trsnsmit message where @@ -73,108 +68,12 @@ with a unique name and the data from the Image Object */ const icons = [ { - name: "walk", - data: "gEBAP4B/ALyh7b/YALHfY9tACY55HfYdNHto7pHpIbXbL5fXAD6VlHuYAjHf47/Hf47tHK47LDa45zHc4NHHeILJHeonTO9o9rHf47/eOoB/ANg=" - }, - { - name: "sit", - data: "gEBAP4B/AP4BacO4ANHPI/rACp1/Hf49rGtI5/He7n3ACY55HcYAZHf45/Hf45rHe4XHGbI7/Va47zZZrpbHfbtXD5Y/vHcYB/AP4BmA" - }, - { - name: "joystick", - data: "gEBAP4B/AP4BMavIALHPI9vHf47/eP45vHpY5xHo451Hf47/FuYAHHNItHABa33AP6xpAD455HqY7/Hf47/Hd49pHKIB/AP4B/AMwA==" - }, - { - name: "left", - data: "gEBAP4B/AP4BKa9ojHAC5pfHJKDTUsYdZHb6ZfO+I9dABabdLbIBdHf473PP47NJdY7/ePIB/RJop5Ys7t/AP6PvD7o7fP8Y1zTZoHPf/4B/AP4B+A==" - }, - { - name: "right", - data: "gEBAP4B/AP4BKa+oAXDo45hCaqFbUbLBfbbo7bHMojTR7Y5LHa51ZALo75Ov47/FeY77AP4B5WdbF3dv4B/R94fdHb5/jGuabNA57//AP4B/APw=" - }, - { - name: "forward", - data: "gEBAP4B/AKSX5avIALHPI9tACY55HsoAbHPI9fHfZFVGMo7/Hf47/Hf47/Hf47/Hf47/Hf47/Hf47/Hf49XHOIB/ALw=" - }, - { - name: "backward", - data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/Hf47/Hf47/Hf47/HfIAfHf491W/L15HMo9THNI9PHNo9LHOI9HHOoB/ALg=" - }, - { - name: "back", - data: "gEBAP4B/AP4B/AKgADHPI71HP45/HP45/HP45/HP45/Hf49/Hv49/Hv49/Hv49/Hv497He4B/AP4B/AJAA==" - }, - { - name: "spk_on", - data: "gEBAP4B/AP4Bic/YAFPP4v1HrYZRVJo7ZDKp5jMJYvZHaYAHVL4LHACZrhADLBTJKI7dPLI7/Hf47/HeZBVFqZHZRJp1lAJ47LOtZTnHbIZDKLpHNAL69ZANp1tQbY5/AP4B/ANQ" - }, - { - name: "spk_off", - data: "gEBAPhB7P/o9rFKI9pFKY9tXNYZNHrZXfMaoAHPOZhNF7LdXHpKpZEJpvPDZK1ZAB49NPLo9jHdI9NHd49PHebvxEJY9NI6I7dHpaDXcKqfPHLKjZHcpTjHbIZDKa73JHa4BXGY45xe5Y7zV+o9/Hv49JHe4BEA=" - }, - { - name: "mic_on", - data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/GbY7TIcY7/Hf47/Hf47/HdY9NCpp5lCb57fOdYvNeJo91HNrlvHf7tVIdY77AP4BiA=" - }, - { - name: "mic_off", - data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/GbY7TIcY7/Wf47/HJZLjHZ45RHrI7NHJYhLHqoZJA54hNHr5lTXL6vPSra5jKbo9REZrLRHa5DTXp47jAA7TTF7INLRqY7fdKavhXKo5te6wA==" - }, - { - name: "comms", - data: "gEBAP4B+QvbF7ABo7/He49tACI7/Hf47zHtI7jJq47lRqoAVEqY7nHsoAZGJo71HrKxfQaY7bdKo7/Hdqz5B5Y7zHK47RD55FRHao3XHKo7JG7L1NHeJTbHboB/AP4BG" - }, - { - name: "dalek", - data: "gEBAP4B/AP4B/AJMQwQBBGucIoMAkADBhFhAoZBcAAQfJhEgB45BCHYMBjGiB4ZLCK5APDFpphBC5AbEJosY0YfCG4IAEJIYdGFYR5LHJYlEAI0Y4cY8YXMOpQBFlNFlMkOZA7MKII7JOAXkE4T1UERKtFHoxJBABY5QiGiD5kANYTnCiFiWIJVOgDZCOra3FoKxFDKI7hADQ7PkEIaoIHEaKYfJAoKPFAJcIGYIJHkI7UgMY8ZFHC5rVDKIZTCDIJhBA4ILBBoYFHC4QBEBogpBjHDdsJJEAoYAHKoTxWWb5tNWZOiHZRbBHbwtLF5ynBL7wtLjHjd6oAZkHkI5JJKAAZ3TkAjJhALBsJ5K0a/KkLvfkMEFpVhO8hrIU4QLGG4QAzkCdVAP4B/AP4Bb" - }, - { - name: "k9", - data: "gEBAP4B/AP4B/AP4B/AP4B/AKAADIf5N/IaIAJJv5LZLeIARffZNdD5JN/KLYATC65RbAGrHlJ/5P/JuYrRJfovNJf4BdAFJL/Jv5N/Jv5L1Jv5PvJv5L7Jv5PpAGpN/dv5HzAP4B/AP4B/AP4B/AP4B/ALg" - }, - { - name: "pawn", - data: "gEBAP4B/AP4B/AP4BEAA455HuY7/Hf47xAB47/PuI1xPZY7/Hf47/G9Y/zHfIATHPI9nHfYB/AOYAfHf4B/AP4B/APA=" - }, - { - name: "facerecog", - data: "gEBAP4BSLuozNH9YpTHsolXPsYfdDraZhELIZhHeLtJELY1VC4Y7HHqoXJABYdNHa5bJDrLvfHfbrPZJI7nGZpdVNJ4lRIpaznRqp1hCq55ZC6IRPd8oPjW8Y5jSr45dEJppNHcIjLHZY5ja6rrhFK45pVqI5rGI4AHHNpx3ANA=" - }, - { - name: "sleep", - data: "gEBAP4B/AP4B2ACY7/Quq95HP45/HP4APOdY7fACZfnHcaZZAL45/HP45/E7YAHCaZFZHfbh/HP45/HOoAHHf4B/AP4B/AP4BIA=" - }, - { - name: "awake", - data: "gEBAP4B/AKyb7HfIAFHPI77Ov451Hf453Hf453HdoAbHf45/Hf5HrHNY7NHNo7/HO47/HO47HHPJ1/Heo51HfoB/ALg=" - }, - { - name: "wag_h", - data: "gEBAP4B/AP4B/AP4B/AP4B/AMwADD+oAFHb4hTHMIlXHMopTHNItPAG47/WfY9tFKY9lEq49hELY7ja8YB/AP4B/AP4B/AP4B/AP4BCA" - }, - { - name: "wag_v", - data: "gEBAP4B/AP4BOafIAHHPI9xAB45vd449rFZIHLHsonJBKa7rGNo7/Hf47/Hf47/Hf47/Hf4xlBKY7hFIoHLQM4rHApK7rAB71xHOo9LHOI9HHOoB/AP4BYA=" - }, - { - name: "happy", - data: "gEBAP4B/AP4BKa+oAXHNITfHK4ZtD5JZfHOojZaMYlXHMYnXHfI5nFaYPLaaIRNHf47/d/47/HtInTCZrfZHa4vNABYlVKLI3PbLrzfD7qTXDLaphHMIpLAB45hIKY1pAP4B/AMA" - }, - { - name: "sad", - data: "gEBAP4B/AP4BKa+oAXHNITfHK4ZtD5JZfHOojZaMYlXHMYnXHfI5nFaYPLaaIRNHf47/d/47/CK4njCZ4APHcIVJBbbdTecYjZHr4fdSa4ZbEZ4lNCaY9dAB45hIKY1pAP4B/AMA" - }, - { - name: "hover", - data: "gEBAP4B/AP7NedL4fZK7ojNHeJ35DJI7vC5Y7tVMI7XHNYnNYro7hHKI7lAK47/HdoAhHPI7/Hf47/Hf4AtHPI7/Hf47/Hd45LAP4B/ANwA=" + name: "switch", + data: "gEBAP4B/AP4B/AP4B/AMgA3HPJdlVvI7/Hf47/Hf47/Hf47/Hf47/Hf4AvIPKRXAP4B/AP4B/AP4B/AJgA==" }, { name: "light", data: "gEBAP4B/APi/Na67lfACZ/nNaI9lE6o9jEbI9hD7Y7dDsJZ3D6YRJHdIJHHfaz7Hf5Z/Hf4hZHMIjFEqIVVHsY5hDpI7TEqL1jVsqlTdM55THOJvHOuY7/HfI9JHOI9HHOoBgA==" - }, - { - name: "speak", - data: "gEBAP4B/AP4BIbO4AXG+4/hAEY55HqoArHPI9PHfIAzHf47/Hf47/HeY9xHJI79Hto5NHtY5RHc45THco5VHcI3XHJpHRG7I7LEro5ZG+IB/AP4BwA==" } ]; @@ -203,164 +102,62 @@ The global variable should be declared at the start of the program and it may be adviable to use the 'status_name' format to ensure it is clear. */ -var joystickBtn = { + +var lightBtn = { primary_colour: 0x653E, - primary_icon: 'joystick', - primary_text: 'Joystick', + primary_text: 'Lights', + primary_icon: 'light', }; -var turnLeftBtn = { - primary_colour: 0x653E, - primary_text: 'Left', - primary_icon: 'left', - }; - -var turnRightBtn = { +var socketsBtn = { primary_colour: 0x33F9, - primary_text: 'Right', - primary_icon: 'right', + primary_text: 'Sockets', + primary_icon: 'switch', }; -var k9Btn = { - primary_colour: 0x653E, - primary_text: 'K9', - primary_icon: 'k9', - }; - -var dalekBtn = { - primary_colour: 0x33F9, - primary_text: 'Dalek', - primary_icon: 'dalek', - }; - -var tailHBtn = { - primary_colour: 0x653E, - primary_text: 'Wag Tail', - primary_icon: 'wag_h', - }; - -var tailVBtn = { - primary_colour: 0x33F9, - primary_text: 'Wag Tail', - primary_icon: 'wag_v', - }; - -var happyBtn = { - primary_colour: 0x653E, - primary_text: 'Speak', - primary_icon: 'happy', - }; - -var sadBtn = { - primary_colour: 0x33F9, - primary_text: 'Speak', - primary_icon: 'sad', - }; - -var speakBtn = { - primary_colour: 0x33F9, - primary_text: 'Speak', - primary_icon: 'speak', - }; - -var faceBtn = { +var lightHallBtn = { primary_colour: 0xE9C7, - primary_text: 'Off', - primary_icon: 'facerecog', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'On', - secondary_icon : 'facerecog', - value: status_face - }; - -var chessBtn = { - primary_colour: 0xE9C7, - primary_text: 'Off', - primary_icon: 'pawn', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'On', - secondary_icon : 'pawn', - value: status_chess - }; - -var irisLightBtn = { - primary_colour: 0xE9C7, - primary_text: 'Off', + primary_text: 'Hall Off', primary_icon: 'light', toggle: true, secondary_colour: 0x3F48, - secondary_text: 'On', + secondary_text: 'Hall On', secondary_icon : 'light', - value: status_iris_light + value: status_light_hall }; -var irisBtn = { +var lightStudyBtn = { primary_colour: 0xE9C7, - primary_text: 'Closed', - primary_icon: 'sleep', + primary_text: 'Study Off', + primary_icon: 'light', toggle: true, secondary_colour: 0x3F48, - secondary_text: 'Open', - secondary_icon : 'awake', - value: status_iris + secondary_text: 'Study On', + secondary_icon : 'light', + value: status_light_study +}; + +var socketTVBtn = { + primary_colour: 0xE9C7, + primary_text: 'TV Off', + primary_icon: 'switch', + toggle: true, + secondary_colour: 0x3F48, + secondary_text: 'TV On', + secondary_icon : 'switch', + value: status_tv }; -var wakeBtn = { +var socketPrinterBtn = { primary_colour: 0xE9C7, - primary_text: 'Sleeping', - primary_icon: 'sleep', + primary_text: 'Printer Off', + primary_icon: 'switch', toggle: true, secondary_colour: 0x3F48, - secondary_text: 'Awake', - secondary_icon : 'awake', - value: status_wake - }; - -var hoverBtn = { - primary_colour: 0xE9C7, - primary_text: 'Off', - primary_icon: 'hover', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'On', - secondary_icon : 'hover', - value: status_hover - }; - -var autoBtn = { - primary_colour: 0xE9C7, - primary_text: 'Stop', - primary_icon: 'sit', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'Move', - secondary_icon : 'walk', - value: status_auto - }; - -var micBtn = { - primary_colour: 0xE9C7, - primary_text: 'Off', - primary_icon: 'mic_off', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'On', - secondary_icon : 'mic_on', - value: status_mic - }; - -var spkBtn = { - primary_colour: 0xE9C7, - primary_text: 'Off', - primary_icon: 'spk_off', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'On', - secondary_icon : 'spk_on', - value: status_spk - }; + secondary_text: 'Printer On', + secondary_icon : 'switch', + value: status_printer +}; /* CONFIGURATION AREA - SCREEN DEFINITIONS @@ -372,68 +169,20 @@ the left hand side of the screen. These are defined as btn1, bt2 and bt3. The values are names from the icon array. */ -const menuScreen = { - left: k9Btn, - right: dalekBtn, -}; - -const k9MenuScreen = { - left: wakeBtn, - right: joystickBtn, - btn1: "pawn", - btn2: "wag_h", - btn3: "back" -}; - -const joystickScreen = { - left: turnLeftBtn, - right: turnRightBtn, - btn1: "forward", - btn2: "backward", - btn3: "back" -}; - -const tailScreen = { - left: tailHBtn, - right: tailVBtn, - btn3: "back" -}; - -const commsScreen = { - left: micBtn, - right: spkBtn, - btn3: "back" -}; - -const dalekMenuScreen = { - left: faceBtn, - right: speakBtn, - btn1: "hover", - btn2: "light", - btn3: "back" -}; - -const speakScreen = { - left: happyBtn, - right: sadBtn, - btn3: "back" -}; - -const irisScreen = { - left: irisBtn, - right: irisLightBtn, - btn3: "back" +const homeScreen = { + left: lightsBtn, + right: socketsBtn, }; const lightsScreen = { - left: hoverBtn, - right: spkBtn, + left: lightHallBtn, + right: lightStudyBtn, btn3: "back" }; -const chessScreen = { - left: chessBtn, - right: autoBtn, +const socketsScreen = { + left: socketTVBtn, + right: socketPrinterBtn, btn3: "back" }; @@ -478,145 +227,34 @@ inversed and the new value transmitted. /* The Home State/Page is where the application beings */ const Home = new State({ state: "Home", - screen: menuScreen, + screen: homeScreen, events: (event) => { if ((event.object == "right") && (event.status == "end")) { - return DalekMenu; + return SocketsMenu; } if ((event.object == "left") && (event.status == "end")) { - //status_auto.value = !status_auto.value; - //transmit(this.state, "auto", onOff(status_auto.value)); - //return this; - return K9Menu; + return LightsMenu; } transmit(this.state, event.object, event.status); return this; } }); -const K9Menu = new State({ - state: "K9Menu", - screen: k9MenuScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return Home; - } - if ((event.object == "right") && (event.status == "end")) { - return Joystick; - } - if ((event.object == "left") && (event.status == "end")) { - status_wake.value = !status_wake.value; - transmit(this.state, "auto", onOff(status_wake.value)); - return this; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const DalekMenu = new State({ - state: "DalekMenu", - screen: dalekMenuScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return Home; - } - if ((event.object == "right") && (event.status == "end")) { - return Speak; - } - if ((event.object == "left") && (event.status == "end")) { - status_face.value = !status_face.value; - transmit(this.state, "face", onOff(status_face.value)); - return this; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const Speak = new State({ - state: "Speak", - screen: speakScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return DalekMenu; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const Chess = new State({ - state: "Chess", - screen: chessScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return K9Menu; - } - if ((event.object == "right") && (event.status == "end")) { - status_auto.value = !status_auto.value; - transmit(this.state, "follow", onOff(status_auto.value)); - return this; - } - if ((event.object == "left") && (event.status == "end")) { - status_chess.value = !status_chess.value; - transmit(this.state, "chess", onOff(status_chess.value)); - return this; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const Tail = new State({ - state: "Tail", - screen: tailScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return K9Menu; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const Iris = new State({ - state: "Iris", - screen: irisScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return DalekMenu; - } - if ((event.object == "right") && (event.status == "end")) { - status_iris_light.value = !status_iris_light.value; - transmit(this.state, "iris_light", onOff(status_iris_light.value)); - return this; - } - if ((event.object == "left") && (event.status == "end")) { - status_iris.value = !status_iris.value; - transmit(this.state, "iris_servo", onOff(status_iris.value)); - return this; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const Lights = new State({ - state: "Lights", +const LightsMenu = new State({ + state: "LightsMenu", screen: lightsScreen, events: (event) => { if ((event.object == "bottom") && (event.status == "end")) { - return DalekMenu; + return Home; } if ((event.object == "right") && (event.status == "end")) { - status_spk.value = !status_spk.value; - transmit(this.state, "iris_light", onOff(status_spk.value)); + status_light_study.value = !status_light_study.value; + transmit(this.state, "auto", onOff(status_light_study.value)); return this; } if ((event.object == "left") && (event.status == "end")) { - status_hover.value = !status_hover.value; - transmit(this.state, "hover", onOff(status_hover.value)); + status_light_hall.value = !status_light_hall.value; + transmit(this.state, "auto", onOff(status_light_hall.value)); return this; } transmit(this.state, event.object, event.status); @@ -624,42 +262,26 @@ const Lights = new State({ } }); - -/* Joystick page state */ -const Joystick = new State({ - state: "Joystick", - screen: joystickScreen, +const SocketsMenu = new State({ + state: "SocketsMenu", + screen: lightsScreen, events: (event) => { if ((event.object == "bottom") && (event.status == "end")) { - transmit("Joystick", "joystick", "off"); - return Home; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -/* Comms page state */ -const Comms = new State({ - state: "Comms", - screen: commsScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return Home; - } - if ((event.object == "left") && (event.status == "end")) { - status_mic.value = !status_mic.value; - transmit(this.state, "mic", onOff(status_mic.value)); - return this; + return Home; } if ((event.object == "right") && (event.status == "end")) { - status_spk.value = !status_spk.value; - transmit(this.state, "spk", onOff(status_spk.value)); + status_printer.value = !status_printer.value; + transmit(this.state, "auto", onOff(status_printer.value)); + return this; + } + if ((event.object == "left") && (event.status == "end")) { + status_tv.value = !status_tv.value; + transmit(this.state, "auto", onOff(status_tv.value)); return this; } transmit(this.state, event.object, event.status); return this; - } + } }); /* translate button status into english */ From 0b7200eda7a444030ea02124486fc3a5214e34f6 Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 14:20:46 +0100 Subject: [PATCH 617/878] Minor README change --- apps/BLEcontroller/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/BLEcontroller/README.md b/apps/BLEcontroller/README.md index 56f1a2658..0929a9fd7 100644 --- a/apps/BLEcontroller/README.md +++ b/apps/BLEcontroller/README.md @@ -1,4 +1,4 @@ -# BLE Generic Controller with Joystick +# BLE Customisable Controller with Joystick A highly customisable state machine driven user interface that will communicate with another BLE device. The controller uses the three buttons and the left and right hand side of the watch to provide a flexible and attractive BLE interface. From 60b0fee49d230554b5c09a0e870173b194ec0b61 Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 14:22:38 +0100 Subject: [PATCH 618/878] Change to app description --- apps.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 9ba610101..79923cab2 100644 --- a/apps.json +++ b/apps.json @@ -1772,11 +1772,11 @@ ] }, { "id": "BLEcontroller", - "name": "BLE Robot Controller with Joystick", + "name": "BLE Customisable Controller with Joystick", "shortName": "BLE Controller", "icon": "BLEcontroller.png", "version": "0.01", - "description": "A configurable controller for BLE robots, with a basic four direction joystick. Easy to customise and add your own menus.", + "description": "A configurable controller for BLE devices and robots, with a basic four direction joystick. Designed to be easy to customise so you can add your own menus.", "tags": "tool,bluetooth", "readme": "README.md", "allow_emulator":true, From 03f4f1da8bca0474b371e8bb68728479faf4d09c Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 14:27:02 +0100 Subject: [PATCH 619/878] Bug fix --- apps/BLEcontroller/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 1b4775ef2..96f56efce 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -170,7 +170,7 @@ are defined as btn1, bt2 and bt3. The values are names from the icon array. */ const homeScreen = { - left: lightsBtn, + left: lightBtn, right: socketsBtn, }; From b9f0907e5a1a371038f56e5a57a5d69b015bbc02 Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 14:36:03 +0100 Subject: [PATCH 620/878] Added back icon --- apps/BLEcontroller/README.md | 2 +- apps/BLEcontroller/app.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/BLEcontroller/README.md b/apps/BLEcontroller/README.md index 0929a9fd7..d66ea9557 100644 --- a/apps/BLEcontroller/README.md +++ b/apps/BLEcontroller/README.md @@ -1,4 +1,4 @@ -# BLE Customisable Controller with Joystick +# BLE Customisable Controller with Joystick A A highly customisable state machine driven user interface that will communicate with another BLE device. The controller uses the three buttons and the left and right hand side of the watch to provide a flexible and attractive BLE interface. diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 96f56efce..0ae900b9b 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -74,6 +74,10 @@ const icons = [ { name: "light", data: "gEBAP4B/APi/Na67lfACZ/nNaI9lE6o9jEbI9hD7Y7dDsJZ3D6YRJHdIJHHfaz7Hf5Z/Hf4hZHMIjFEqIVVHsY5hDpI7TEqL1jVsqlTdM55THOJvHOuY7/HfI9JHOI9HHOoBgA==" + }, + { + name: "back", + data: "gEBAP4B/AP4B/AKgADHPI71HP45/HP45/HP45/HP45/Hf49/Hv49/Hv49/Hv49/Hv497He4B/AP4B/AJAA==" } ]; @@ -220,7 +224,7 @@ one, then the state machine will change to that new State and redrsw the screen appropriately. To add in additional capabilities for button presses, simply add an additional 'if' statement. -For toggle buttons, the value of the sppropiate status object is +For toggle buttons, the value of the appropiate status object is inversed and the new value transmitted. */ From 9f1b61d2d9211fed78e5e405023d46fbbfcee876 Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 14:41:52 +0100 Subject: [PATCH 621/878] Minor bug fix --- apps/BLEcontroller/README.md | 2 +- apps/BLEcontroller/app.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/BLEcontroller/README.md b/apps/BLEcontroller/README.md index d66ea9557..0929a9fd7 100644 --- a/apps/BLEcontroller/README.md +++ b/apps/BLEcontroller/README.md @@ -1,4 +1,4 @@ -# BLE Customisable Controller with Joystick A +# BLE Customisable Controller with Joystick A highly customisable state machine driven user interface that will communicate with another BLE device. The controller uses the three buttons and the left and right hand side of the watch to provide a flexible and attractive BLE interface. diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 0ae900b9b..fc7d7dbb7 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -268,7 +268,7 @@ const LightsMenu = new State({ const SocketsMenu = new State({ state: "SocketsMenu", - screen: lightsScreen, + screen: socketsScreen, events: (event) => { if ((event.object == "bottom") && (event.status == "end")) { return Home; From e9e9bf941aca623720b7aefcb68830e0f8981b66 Mon Sep 17 00:00:00 2001 From: Michael Bengfort Date: Mon, 1 Jun 2020 15:53:28 +0200 Subject: [PATCH 622/878] correct string position --- apps.json | 2 +- apps/metronome/ChangeLog | 1 + apps/metronome/metronome.js | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps.json b/apps.json index b478a8f69..00231a835 100644 --- a/apps.json +++ b/apps.json @@ -1403,7 +1403,7 @@ "id": "metronome", "name": "Metronome", "icon": "metronome_icon.png", - "version": "0.05", + "version": "0.06", "readme": "README.md", "description": "Makes the watch blinking and vibrating with a given rate", "tags": "tool", diff --git a/apps/metronome/ChangeLog b/apps/metronome/ChangeLog index 909d6b983..894d62940 100644 --- a/apps/metronome/ChangeLog +++ b/apps/metronome/ChangeLog @@ -3,3 +3,4 @@ 0.03: Uses mean of three time intervalls to calculate bmp 0.04: App shows instructions, Widgets remain visible, color changed 0.05: Buzz intensity and beats per bar can be changed via settings-app +0.06: Correct string position diff --git a/apps/metronome/metronome.js b/apps/metronome/metronome.js index add6fee16..19509f338 100644 --- a/apps/metronome/metronome.js +++ b/apps/metronome/metronome.js @@ -56,8 +56,8 @@ function updateScreen() { } catch(err) { } - g.setFont("Vector",48); - g.drawString(Math.floor(bpm)+"bpm", 5, 60); + g.setFont("Vector",40); + g.drawString(Math.floor(bpm)+"bpm", 100, 100); } @@ -105,7 +105,7 @@ setWatch(() => { interval = setInterval(updateScreen, 60000 / bpm); g.clear(); -g.drawString('Touch the screen to set tempo.\nUse BTN1 to increase, and\nBTN3 to decrease bpm value by 1.', 15, 150); +g.drawString('Touch the screen to set tempo.\nUse BTN1 to increase, and\nBTN3 to decrease bpm value by 1.', 25, 200); Bangle.loadWidgets(); Bangle.drawWidgets(); From 615f8c8fcefc3a1d71c5f63b3be1f0659fb16e56 Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 15:18:48 +0100 Subject: [PATCH 623/878] Update transmitted values --- apps/BLEcontroller/app.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index fc7d7dbb7..fd07d73f9 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -253,12 +253,12 @@ const LightsMenu = new State({ } if ((event.object == "right") && (event.status == "end")) { status_light_study.value = !status_light_study.value; - transmit(this.state, "auto", onOff(status_light_study.value)); + transmit(this.state, "study", onOff(status_light_study.value)); return this; } if ((event.object == "left") && (event.status == "end")) { status_light_hall.value = !status_light_hall.value; - transmit(this.state, "auto", onOff(status_light_hall.value)); + transmit(this.state, "hall", onOff(status_light_hall.value)); return this; } transmit(this.state, event.object, event.status); @@ -275,12 +275,12 @@ const SocketsMenu = new State({ } if ((event.object == "right") && (event.status == "end")) { status_printer.value = !status_printer.value; - transmit(this.state, "auto", onOff(status_printer.value)); + transmit(this.state, "printer", onOff(status_printer.value)); return this; } if ((event.object == "left") && (event.status == "end")) { status_tv.value = !status_tv.value; - transmit(this.state, "auto", onOff(status_tv.value)); + transmit(this.state, "tv", onOff(status_tv.value)); return this; } transmit(this.state, event.object, event.status); From 7cf0154259994b84a9dd5944b8bb8eb42d7c258d Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 15:21:08 +0100 Subject: [PATCH 624/878] Adding widgets back in --- apps/BLEcontroller/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index fd07d73f9..3f18ffa1c 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -313,6 +313,7 @@ const setMyWatch = (params) => { machine = machine.events({object: params.label, status: startEnd(params.bool)}); drawScreen(machine.screen); }, params.btn, {repeat:true, edge:"both"}); + drawWidgets(); }; /* object array used to set up the watching functions From 6962fd01d66b451c986c1a8b3eb43abfd2e9f18c Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 15:24:22 +0100 Subject: [PATCH 625/878] Syntax error --- apps/BLEcontroller/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 3f18ffa1c..01a2c78c8 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -313,7 +313,7 @@ const setMyWatch = (params) => { machine = machine.events({object: params.label, status: startEnd(params.bool)}); drawScreen(machine.screen); }, params.btn, {repeat:true, edge:"both"}); - drawWidgets(); + Bangle.drawWidgets(); }; /* object array used to set up the watching functions From fdbf4300ef20b9060ee4d1759d52c51936d73f7b Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 15:47:00 +0100 Subject: [PATCH 626/878] Change transmission frequency --- apps/BLEcontroller/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 01a2c78c8..8cb611273 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -19,6 +19,7 @@ bottom_btn = false; msgNum = 0; // message number +NRF.setConnectionInterval(100) /* CONFIGURATION AREA - STATE VARIABLES declare global variables for the toggle button From 39f62c1ab7c2c018e288c724ae69fbd5f0084dca Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 15:49:19 +0100 Subject: [PATCH 627/878] Try once at beginning of app --- apps/BLEcontroller/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 8cb611273..7fd908d59 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -20,6 +20,8 @@ bottom_btn = false; msgNum = 0; // message number NRF.setConnectionInterval(100) +Bangle.loadWidgets() +Bangle.drawWidgets() /* CONFIGURATION AREA - STATE VARIABLES declare global variables for the toggle button @@ -314,7 +316,6 @@ const setMyWatch = (params) => { machine = machine.events({object: params.label, status: startEnd(params.bool)}); drawScreen(machine.screen); }, params.btn, {repeat:true, edge:"both"}); - Bangle.drawWidgets(); }; /* object array used to set up the watching functions From 5ca81d9bfbcc0c8351c3bc4ed2f25c186cb4fbdc Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 16:01:50 +0100 Subject: [PATCH 628/878] Tidy up --- apps/BLEcontroller/app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 7fd908d59..6f8b70e1b 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -19,9 +19,9 @@ bottom_btn = false; msgNum = 0; // message number -NRF.setConnectionInterval(100) -Bangle.loadWidgets() -Bangle.drawWidgets() +NRF.setConnectionInterval(100); +Bangle.loadWidgets(); +Bangle.drawWidgets(); /* CONFIGURATION AREA - STATE VARIABLES declare global variables for the toggle button From e8f8703b36cb4688e2b04cddd0480c73ace3bcff Mon Sep 17 00:00:00 2001 From: hopkira Date: Mon, 1 Jun 2020 16:06:10 +0100 Subject: [PATCH 629/878] Cosmetic change to give gap to widgets --- apps/BLEcontroller/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/BLEcontroller/app.js b/apps/BLEcontroller/app.js index 6f8b70e1b..ba172b047 100644 --- a/apps/BLEcontroller/app.js +++ b/apps/BLEcontroller/app.js @@ -344,7 +344,7 @@ const drawButton = (params,side) => { text = params.secondary_text; icon = drawIcon(params.secondary_icon); } - g.fillRect(0+x,24,119+x, 239); + g.fillRect(0+x,28,119+x, 239); g.setColor(0x000); g.setFont("Vector",15); g.setFontAlign(0,0.0); From d9442f2fd077eba216abda3ccd41a8e766e1c3aa Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 1 Jun 2020 17:04:55 +0100 Subject: [PATCH 630/878] locale: Improve handling of non-ASCII characters (fix #469) --- apps.json | 2 +- apps/locale/ChangeLog | 1 + apps/locale/locale.html | 69 ++++++++++++++++++++++++++++++++++++----- apps/locale/locales.js | 52 ++++++++++++++++++++++++------- 4 files changed, 103 insertions(+), 21 deletions(-) diff --git a/apps.json b/apps.json index 5eb039b53..f098e1351 100644 --- a/apps.json +++ b/apps.json @@ -65,7 +65,7 @@ { "id": "locale", "name": "Languages", "icon": "locale.png", - "version":"0.06", + "version":"0.07", "description": "Translations for different countries", "tags": "tool,system,locale,translate", "type": "locale", diff --git a/apps/locale/ChangeLog b/apps/locale/ChangeLog index 3d983150d..8338f9f84 100644 --- a/apps/locale/ChangeLog +++ b/apps/locale/ChangeLog @@ -6,3 +6,4 @@ Add correct scaling for speed/distance/temperature 0.06: Remove translations if not required Ensure 'on' is always supplied for translations +0.07: Improve handling of non-ASCII characters (fix #469) diff --git a/apps/locale/locale.html b/apps/locale/locale.html index 21bf37f29..645d6b2db 100644 --- a/apps/locale/locale.html +++ b/apps/locale/locale.html @@ -1,5 +1,6 @@ + @@ -12,7 +13,7 @@

    Then click

    - + + + + From fa169c3bef6797980ef684dfa8704f0e0a40e840 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 11 Jun 2020 15:06:22 +0100 Subject: [PATCH 714/878] revert accidental commits --- .vscode/launch.json | 17 -- apps.json | 30 +- apps/dalekcontrol/README.md | 50 ---- apps/dalekcontrol/app-icon.js | 1 - apps/dalekcontrol/app.js | 450 ---------------------------- apps/dalekcontrol/dalek_icon_30.png | Bin 7042 -> 0 bytes apps/k9control/README.md | 50 ---- apps/k9control/app-icon.js | 1 - apps/k9control/app.js | 446 --------------------------- apps/k9control/k9_icon_30.png | Bin 4779 -> 0 bytes 10 files changed, 1 insertion(+), 1044 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 apps/dalekcontrol/README.md delete mode 100644 apps/dalekcontrol/app-icon.js delete mode 100644 apps/dalekcontrol/app.js delete mode 100644 apps/dalekcontrol/dalek_icon_30.png delete mode 100644 apps/k9control/README.md delete mode 100644 apps/k9control/app-icon.js delete mode 100644 apps/k9control/app.js delete mode 100644 apps/k9control/k9_icon_30.png diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 771354e66..000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "node", - "request": "launch", - "name": "Launch Program", - "skipFiles": [ - "/**" - ], - "program": "${workspaceFolder}/http-server" - } - ] -} \ No newline at end of file diff --git a/apps.json b/apps.json index 5e4a2b4a5..7aaf66a13 100644 --- a/apps.json +++ b/apps.json @@ -1811,35 +1811,7 @@ { "name": "BLEcontroller.app.js", "url": "app.js" }, { "name": "BLEcontroller.img", "url": "app-icon.js", "evaluate": true } ] - }, - { "id": "k9control", - "name": "K9 BLE Controller with Joystick", - "shortName": "K9 Controller", - "icon": "k9_icon_30.png", - "version": "0.01", - "description": "My private K9 BLE controller", - "tags": "tool,bluetooth", - "readme": "README.md", - "allow_emulator":false, - "storage": [ - { "name": "k9control.app.js", "url": "app.js" }, - { "name": "k9control.img", "url": "app-icon.js", "evaluate": true } - ] - }, - { "id": "dalekcontrol", - "name": "Dalek BLE Controller with Joystick", - "shortName": "Dalek Controller", - "icon": "dalek_icon_30.png", - "version": "0.01", - "description": "My private Dalek BLE controller", - "tags": "tool,bluetooth", - "readme": "README.md", - "allow_emulator":false, - "storage": [ - { "name": "dalekcontrol.app.js", "url": "app.js" }, - { "name": "dalekcontrol.img", "url": "app-icon.js", "evaluate": true } - ] - }, + }, { "id": "widviz", "name": "Widget Visibility Widget", "shortName":"Viz Widget", diff --git a/apps/dalekcontrol/README.md b/apps/dalekcontrol/README.md deleted file mode 100644 index 3ffe7f514..000000000 --- a/apps/dalekcontrol/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Dalek Controller - -A highly customisable state machine driven user interface that will communicate with another BLE device. The controller uses the three buttons and the left and right hand side of the watch to provide a flexible and attractive BLE interface. - -Amaze your friends by controlling your robot, your house or any other BLE device from your watch! - - - -To keep the messages small, commands are sent from the Controller to the BLE target in a text string. This is made up of a comma delimited string of the following elements: -* message number (up to the least significant four digits) -* screen name (up to four characters) -* object name (up to four characters) -* value/status (up to four characters) - -The combination of these variables will uniquely identify the status change requested from the watch to the target device that can then be programmed to respond appropriately. - -Gordon Williams' EspruinoHub is an excellent way to transform thse BLE advertisements into MQTT messages for further processing. They can be subscribed to via the following MQTT topic (change the watchaddress, to the MAC address of your Bangle.js) -/ble/advertise/wa:tc:ha:dd:re:ss/espruino/# - -## Usage - -The application can be configured at will by changing the definitions of the screens, events, icons and buttons. - -Most changes are possible via data, rather than code change. - -## Features - -The default package contains three configurations: -* a simple home light and sockets controller UI (app.js) -* a robot controller UI with joystick (app-joy.js) -* a simple static assistant controller (app-ex2.js) - -You can try out the other configurations by deleting app.js and renaming the file you want to try as app.js. - -I have tested out the application to as many as eight screens without problems, but four screens are usually enough for most situations. - -## Controls - -The controls will vary by screen, but I suggest a convention of using BTN3 (the bottom button) for moving backwards up the menu stack. - -I have used the convention of red/green for buttons that are switches and blue buttons that provide single function operation (such as navigating a menu or executing a on-off activity) - -## Requests - -In the first instance, please consult my blog post on this application [here](https://k9-build.blogspot.com/2020/05/controlling-k9-using-bluetooth-ble-from.html) - -## Creator - -Richard Hopkins, FIET CEng -May 2020 diff --git a/apps/dalekcontrol/app-icon.js b/apps/dalekcontrol/app-icon.js deleted file mode 100644 index b228e290b..000000000 --- a/apps/dalekcontrol/app-icon.js +++ /dev/null @@ -1 +0,0 @@ -E.toArrayBuffer(atob("Hh6EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIAAAAAAAAAAAAAAAACIiIiIAAAAAAAACIgAAIiICICIiAAAiIAACIiAiIiAgAgIiIgIiIAAAIgIiIiAAACIiIiAiAAAAAiIiIiAAACIiIiIgAAAAACIiIiAgAAIiIiIAAAAAAiIiIiICIgIiIiIgAAAAAiIiIiIgAiIiIiIgAAAAAiIiIiIiIiIiIiIgAAAAAiACIAAAAAACIAIgAAAAAgAAIAAAAAAAIAAgAAAAIiIiIiIiIiIiIiIiAAAAIiIiIiIiIiIiIiIiAAAAAAAAIAAAAAAAIAAAAAAAIAAAIAAAAAAAIAACAAAAIAAAIAAAAAAAIAACAAACIiIiIiIiIiIiIiIiIAACIAACIAAAAAACIAACIAAAIAAAIAAAAAAAIAACAAACIAACIAAAAAACIAACIAAiIiIiIiIiIiIiIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==")) diff --git a/apps/dalekcontrol/app.js b/apps/dalekcontrol/app.js deleted file mode 100644 index 27e629d5d..000000000 --- a/apps/dalekcontrol/app.js +++ /dev/null @@ -1,450 +0,0 @@ -/* -========================================================== -Simple event based robot controller that enables robot -to switch into automatic or manual control modes. Behaviours -are controlled via a simple finite state machine. -In automatic mode the -robot will look after itself. In manual mode, the watch -will provide simple forward, back, left and right commands. -The messages will be transmitted to a partner BLE Espruino -using BLE -Written by Richard Hopkins, May 2020 -========================================================== -declare global variables for watch button statuses */ -top_btn = false; -middle_btn = false; -left_btn= false; // the left side of the touch screen -right_btn = false; // the right side of the touch screen -bottom_btn = false; - -msgNum = 0; // message number - -/* -CONFIGURATION AREA - STATE VARIABLES -declare global variables for the toggle button -statuses; if you add an additional toggle button -you should declare it and initiase it here */ - -var status_spk = {value: true}; -var status_face = {value: true}; -var status_iris_light = {value: false}; -var status_iris = {value: false}; -var status_hover = {value: false}; -var status_dome = {value: false}; - -/* trsnsmit message -where -s = first character of state, -o = first three character of object name -v = value of state.object -*/ - -const transmit = (state,object,status) => { - msgNum ++; - msg = { - n: msgNum.toString().slice(-4), - s: state.substr(0,4), - o: object.substr(0,4), - v: status.substr(0,4), - }; - message= msg.n + "," + msg.s + "," + msg.o + "," + msg.v; - NRF.setAdvertising({},{ - showName: false, - manufacturer: 0x0590, - manufacturerData: JSON.stringify(message)}); -}; - -/* -CONFIGURATION AREA - ICON DEFINITIONS -Retrieve 30px PNG icons from: -https://icons8.com/icon/set/speak/ios-glyphs -Create icons using: -https://www.espruino.com/Image+Converter -Use compression: true -Transparency: true -Diffusion: flat -Colours: 16bit RGB -Ouput as: Image Object -Add an additional element to the icons array -with a unique name and the data from the Image Object -*/ -const icons = [ - { - name: "back", - data: "gEBAP4B/AP4B/AKgADHPI71HP45/HP45/HP45/HP45/Hf49/Hv49/Hv49/Hv49/Hv497He4B/AP4B/AJAA==" - }, - { - name: "spk_on", - data: "gEBAP4B/AP4Bic/YAFPP4v1HrYZRVJo7ZDKp5jMJYvZHaYAHVL4LHACZrhADLBTJKI7dPLI7/Hf47/HeZBVFqZHZRJp1lAJ47LOtZTnHbIZDKLpHNAL69ZANp1tQbY5/AP4B/ANQ" - }, - { - name: "spk_off", - data: "gEBAPhB7P/o9rFKI9pFKY9tXNYZNHrZXfMaoAHPOZhNF7LdXHpKpZEJpvPDZK1ZAB49NPLo9jHdI9NHd49PHebvxEJY9NI6I7dHpaDXcKqfPHLKjZHcpTjHbIZDKa73JHa4BXGY45xe5Y7zV+o9/Hv49JHe4BEA=" - }, - { - name: "facerecog", - data: "gEBAP4BSLuozNH9YpTHsolXPsYfdDraZhELIZhHeLtJELY1VC4Y7HHqoXJABYdNHa5bJDrLvfHfbrPZJI7nGZpdVNJ4lRIpaznRqp1hCq55ZC6IRPd8oPjW8Y5jSr45dEJppNHcIjLHZY5ja6rrhFK45pVqI5rGI4AHHNpx3ANA=" - }, - { - name: "sleep", - data: "gEBAP4B/AP4B2ACY7/Quq95HP45/HP4APOdY7fACZfnHcaZZAL45/HP45/E7YAHCaZFZHfbh/HP45/HOoAHHf4B/AP4B/AP4BIA=" - }, - { - name: "awake", - data: "gEBAP4B/AKyb7HfIAFHPI77Ov451Hf453Hf453HdoAbHf45/Hf5HrHNY7NHNo7/HO47/HO47HHPJ1/Heo51HfoB/ALg=" - }, - { - name: "happy", - data: "gEBAP4B/AP4BKa+oAXHNITfHK4ZtD5JZfHOojZaMYlXHMYnXHfI5nFaYPLaaIRNHf47/d/47/HtInTCZrfZHa4vNABYlVKLI3PbLrzfD7qTXDLaphHMIpLAB45hIKY1pAP4B/AMA" - }, - { - name: "sad", - data: "gEBAP4B/AP4BKa+oAXHNITfHK4ZtD5JZfHOojZaMYlXHMYnXHfI5nFaYPLaaIRNHf47/d/47/CK4njCZ4APHcIVJBbbdTecYjZHr4fdSa4ZbEZ4lNCaY9dAB45hIKY1pAP4B/AMA" - }, - { - name: "hover", - data: "gEBAP4B/AP7NedL4fZK7ojNHeJ35DJI7vC5Y7tVMI7XHNYnNYro7hHKI7lAK47/HdoAhHPI7/Hf47/Hf4AtHPI7/Hf47/Hd45LAP4B/ANwA=" - }, - { - name: "light", - data: "gEBAP4B/APi/Na67lfACZ/nNaI9lE6o9jEbI9hD7Y7dDsJZ3D6YRJHdIJHHfaz7Hf5Z/Hf4hZHMIjFEqIVVHsY5hDpI7TEqL1jVsqlTdM55THOJvHOuY7/HfI9JHOI9HHOoBgA==" - }, - { - name: "speak", - data: "gEBAP4B/AP4BIbO4AXG+4/hAEY55HqoArHPI9PHfIAzHf47/Hf47/HeY9xHJI79Hto5NHtY5RHc45THco5VHcI3XHJpHRG7I7LEro5ZG+IB/AP4BwA==" - }, - { - name: "dalek", - data: "gEBAP4B/AP4B/AJMQwQBBGucIoMAkADBhFhAoZBcAAQfJhEgB45BCHYMBjGiB4ZLCK5APDFpphBC5AbEJosY0YfCG4IAEJIYdGFYR5LHJYlEAI0Y4cY8YXMOpQBFlNFlMkOZA7MKII7JOAXkE4T1UERKtFHoxJBABY5QiGiD5kANYTnCiFiWIJVOgDZCOra3FoKxFDKI7hADQ7PkEIaoIHEaKYfJAoKPFAJcIGYIJHkI7UgMY8ZFHC5rVDKIZTCDIJhBA4ILBBoYFHC4QBEBogpBjHDdsJJEAoYAHKoTxWWb5tNWZOiHZRbBHbwtLF5ynBL7wtLjHjd6oAZkHkI5JJKAAZ3TkAjJhALBsJ5K0a/KkLvfkMEFpVhO8hrIU4QLGG4QAzkCdVAP4B/AP4Bb" - } - ]; - -/* finds icon data by name in the icon array and returns an image object*/ -const drawIcon = (name) => { - for (var icon of icons) { - if (icon.name == name) { - image = { - width : 30, height : 30, bpp : 16, - transparent : 1, - buffer: require("heatshrink").decompress(atob(icon.data)) - }; - return image;} - } -}; - -/* -CONFIGURATION AREA - BUTTON DEFINITIONS -for a simple button, just define a primary colour -and an icon name from the icon array and -the text to display beneath the button -for toggle buttons, additionally provide secondary -colours, icon name and text. Also provide a reference -to a global variable for the value of the button. -The global variable should be declared at the start of -the program and it may be adviable to use the 'status_name' -format to ensure it is clear. -*/ - -var happyBtn = { - primary_colour: 0x653E, - primary_text: 'Speak', - primary_icon: 'happy', - }; - -var sadBtn = { - primary_colour: 0x33F9, - primary_text: 'Speak', - primary_icon: 'sad', - }; - -var speakBtn = { - primary_colour: 0x33F9, - primary_text: 'Speak', - primary_icon: 'speak', - }; - -var faceBtn = { - primary_colour: 0xE9C7, - primary_text: 'Off', - primary_icon: 'facerecog', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'On', - secondary_icon : 'facerecog', - value: status_face - }; - -var irisLightBtn = { - primary_colour: 0xE9C7, - primary_text: 'Off', - primary_icon: 'light', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'On', - secondary_icon : 'light', - value: status_iris_light - }; - -var irisBtn = { - primary_colour: 0xE9C7, - primary_text: 'Closed', - primary_icon: 'sleep', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'Open', - secondary_icon : 'awake', - value: status_iris - }; - -var hoverBtn = { - primary_colour: 0xE9C7, - primary_text: 'Off', - primary_icon: 'hover', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'On', - secondary_icon : 'hover', - value: status_hover - }; - - var domeBtn = { - primary_colour: 0xE9C7, - primary_text: 'Off', - primary_icon: 'dalek', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'On', - secondary_icon : 'dalek', - value: status_dome - }; - -/* -CONFIGURATION AREA - SCREEN DEFINITIONS -a screen can have a button (as defined above) -on the left and/or the right of the screen. -in adddition a screen can optionally have -an icon for each of the three buttons on -the left hand side of the screen. These -are defined as btn1, bt2 and bt3. The -values are names from the icon array. -*/ - -const menuScreen = { - left: faceBtn, - right: speakBtn, - btn1: "hover", - btn2: "light", -}; - -const speakScreen = { - left: happyBtn, - right: sadBtn, - btn3: "back" -}; - -const irisScreen = { - left: irisBtn, - right: irisLightBtn, - btn3: "back" -}; - -const lightsScreen = { - left: hoverBtn, - right: domeBtn, - btn3: "back" -}; - -/* base state definition -Each of the screens correspond to a state; -this class provides a constuctor for each -of the states -*/ -class State { - constructor(params) { - this.state = params.state; - this.events = params.events; - this.screen = params.screen; - } -} - -/* -CONFIGURATION AREA - BUTTON BEHAVIOURS/STATE TRANSITIONS -This area defines how each screen behaves. -Each screen corresponds to a different State of the -state machine. This makes it much easier to isolate -behaviours between screens. -The state value is transmitted whenever a button is pressed -to provide context (so the receiving device, knows which -button was pressed on which screen). -The screens are defined above. -The events section identifies if a particular button has been -pressed and released on the screen and an action can then be taken. -The events function receives a notification from a mySetWatch which -provides an event object that identifies which button and whether -it has been pressed down or released. Actions can then be taken. -The events function will always return a State object. -If the events function returns different State from the current -one, then the state machine will change to that new State and redrsw -the screen appropriately. -To add in additional capabilities for button presses, simply add -an additional 'if' statement. -For toggle buttons, the value of the sppropiate status object is -inversed and the new value transmitted. -*/ - -/* The Home State/Page is where the application beings */ - -const Home = new State({ - state: "DalekMenu", - screen: menuScreen, - events: (event) => { - if ((event.object == "top") && (event.status == "end")) { - return Lights; - } - if ((event.object == "middle") && (event.status == "end")) { - return Iris; - } - if ((event.object == "right") && (event.status == "end")) { - return Speak; - } - if ((event.object == "left") && (event.status == "end")) { - status_face.value = !status_face.value; - transmit(this.state, "face", onOff(status_face.value)); - return this; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const Speak = new State({ - state: "Speak", - screen: speakScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return Home; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const Iris = new State({ - state: "Iris", - screen: irisScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return Home; - } - if ((event.object == "right") && (event.status == "end")) { - status_iris_light.value = !status_iris_light.value; - transmit(this.state, "light", onOff(status_iris_light.value)); - return this; - } - if ((event.object == "left") && (event.status == "end")) { - status_iris.value = !status_iris.value; - transmit(this.state, "servo", onOff(status_iris.value)); - return this; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const Lights = new State({ - state: "Lights", - screen: lightsScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return Home; - } - if ((event.object == "right") && (event.status == "end")) { - status_dome.value = !status_dome.value; - transmit(this.state, "dome", onOff(status_dome.value)); - return this; - } - if ((event.object == "left") && (event.status == "end")) { - status_hover.value = !status_hover.value; - transmit(this.state, "hover", onOff(status_hover.value)); - return this; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -/* translate button status into english */ -const startEnd = status => status ? "start" : "end"; - -/* translate status into english */ -const onOff= status => status ? "on" : "off"; - - -/* create watching functions that will change the global -button status when pressed or released -This is actuslly the hesrt of the program. When a button -is not being pressed, nothing is happening (no loops). -This makes the progrsm more battery efficient. -When a setWatch event is raised, the custom callbacks defined -here will be called. These then fired as events to the current -state/screen of the state mschine. -Some events, will result in the stste of the state machine -chsnging, which is why the screen is redrswn after each -button press. -*/ -const setMyWatch = (params) => { - setWatch(() => { - params.bool=!params.bool; - machine = machine.events({object: params.label, status: startEnd(params.bool)}); - drawScreen(machine.screen); - }, params.btn, {repeat:true, edge:"both"}); -}; - -/* object array used to set up the watching functions -*/ -const buttons = [ - {bool : bottom_btn, label : "bottom",btn : BTN3}, - {bool : middle_btn, label : "middle",btn : BTN2}, - {bool : top_btn, label : "top",btn : BTN1}, - {bool : left_btn, label : "left",btn : BTN4}, - {bool : right_btn, label : "right",btn : BTN5} - ]; - -/* set up watchers for buttons */ -for (var button of buttons) - {setMyWatch(button);} - -/* Draw various kinds of buttons */ -const drawButton = (params,side) => { - g.setFontAlign(0,1); - icon = drawIcon(params.primary_icon); - text = params.primary_text; - g.setColor(params.primary_colour); - const x = (side == "left") ? 0 : 120; - if ((params.toggle) && (params.value.value)) { - g.setColor(params.secondary_colour); - text = params.secondary_text; - icon = drawIcon(params.secondary_icon); - } - g.fillRect(0+x,24,119+x, 239); - g.setColor(0x000); - g.setFont("Vector",15); - g.setFontAlign(0,0.0); - g.drawString(text,60+x,160); - options = {rotate: 0, scale:2}; - g.drawImage(icon,x+60,120,options); -}; - -/* Draw the pages corresponding to the states */ -const drawScreen = (params) => { - drawButton(params.left,'left'); - drawButton(params.right,'right'); - g.setColor(0x000); - if (params.btn1) {g.drawImage(drawIcon(params.btn1),210,40);} - if (params.btn2) {g.drawImage(drawIcon(params.btn2),210,125);} - if (params.btn3) {g.drawImage(drawIcon(params.btn3),210,195);} -}; - -machine = Home; // instantiate the state machine at Home -Bangle.drawWidgets(); // draw active widgets -drawScreen(machine.screen); // draw the screen diff --git a/apps/dalekcontrol/dalek_icon_30.png b/apps/dalekcontrol/dalek_icon_30.png deleted file mode 100644 index b59750e9d716d2f67290004367bb3a746f9e6f8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7042 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 - -To keep the messages small, commands are sent from the Controller to the BLE target in a text string. This is made up of a comma delimited string of the following elements: -* message number (up to the least significant four digits) -* screen name (up to four characters) -* object name (up to four characters) -* value/status (up to four characters) - -The combination of these variables will uniquely identify the status change requested from the watch to the target device that can then be programmed to respond appropriately. - -Gordon Williams' EspruinoHub is an excellent way to transform thse BLE advertisements into MQTT messages for further processing. They can be subscribed to via the following MQTT topic (change the watchaddress, to the MAC address of your Bangle.js) -/ble/advertise/wa:tc:ha:dd:re:ss/espruino/# - -## Usage - -The application can be configured at will by changing the definitions of the screens, events, icons and buttons. - -Most changes are possible via data, rather than code change. - -## Features - -The default package contains three configurations: -* a simple home light and sockets controller UI (app.js) -* a robot controller UI with joystick (app-joy.js) -* a simple static assistant controller (app-ex2.js) - -You can try out the other configurations by deleting app.js and renaming the file you want to try as app.js. - -I have tested out the application to as many as eight screens without problems, but four screens are usually enough for most situations. - -## Controls - -The controls will vary by screen, but I suggest a convention of using BTN3 (the bottom button) for moving backwards up the menu stack. - -I have used the convention of red/green for buttons that are switches and blue buttons that provide single function operation (such as navigating a menu or executing a on-off activity) - -## Requests - -In the first instance, please consult my blog post on this application [here](https://k9-build.blogspot.com/2020/05/controlling-k9-using-bluetooth-ble-from.html) - -## Creator - -Richard Hopkins, FIET CEng -May 2020 diff --git a/apps/k9control/app-icon.js b/apps/k9control/app-icon.js deleted file mode 100644 index 55d7fb3cc..000000000 --- a/apps/k9control/app-icon.js +++ /dev/null @@ -1 +0,0 @@ -E.toArrayBuffer(atob("JyeEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiAAAAAAAAAAAAAAAAAAAAAAAAAiAAAAAAAAAAAAAAAAAAAAACIiIiAAAAAAAAAAAAAAAAAAAAACIiIgAAAAIAAAAAAAAAAAAAAAAiIiIiIAAAAiAAAAAAAAAAAAAAAiIiIiIAAAACIiAAAAAAAAAAAAAiIiIiIAAAAAAiIgAAAiIiIiIgAiIiIiIiAAAAAAIiIiIiIiIiIiIiIiIiIiIAAAAAACIiIiIiIiIiIiIiIiIiIgAAAAAAIiIiIiIiIiIiIiIiIiIiAAAAAAIiIiIiIiIiIiIgAiIiIgAAAAACIiIiIiIiIiIiIAACIiIAAAAAAiIiIiIiIiIiIiAAAAAAAAAAAAIiIiIiIiIiIiIiAAAAAAAAAAACIiIiIiIiIiIiIiAAAAAAAAAAACIiIiIiIiIiIiIiAAAAAAAAAAACIiIiIiIiIiIiIiAAAAAAAAAAAiIiIiIiIiIiIiIiAAAAAAAAAAAiIiIiIiIiIiIiIiIAAAAAAAAAAiIiIiIiIiIiIiIiIAAAAAAAAAIiIiIiIiIiIiIiIiIAAAAAAAAAIiIiIiIiIiIiIiIiIgAAAAAAACIiIiIiIiIiIiIiIiIgAAAAAAACIiIiIiIiIiIiIiIiIiAAAAAAAAACIiIiIiIiIiIiIiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")) diff --git a/apps/k9control/app.js b/apps/k9control/app.js deleted file mode 100644 index 0735aeee6..000000000 --- a/apps/k9control/app.js +++ /dev/null @@ -1,446 +0,0 @@ -/* -========================================================== -Simple event based robot controller that enables robot -to switch into automatic or manual control modes. Behaviours -are controlled via a simple finite state machine. -In automatic mode the -robot will look after itself. In manual mode, the watch -will provide simple forward, back, left and right commands. -The messages will be transmitted to a partner BLE Espruino -using BLE -Written by Richard Hopkins, May 2020 -========================================================== -declare global variables for watch button statuses */ -top_btn = false; -middle_btn = false; -left_btn= false; // the left side of the touch screen -right_btn = false; // the right side of the touch screen -bottom_btn = false; - -msgNum = 0; // message number - -NRF.setConnectionInterval(100); -Bangle.loadWidgets(); -Bangle.drawWidgets(); -/* -CONFIGURATION AREA - STATE VARIABLES -declare global variables for the toggle button -statuses; if you add an additional toggle button -you should declare it and initiase it here */ - -var status_auto = {value: false}; -var status_chess = {value: false}; -var status_wake = {value: false}; - -/* trsnsmit message -where -s = first character of state, -o = first three character of object name -v = value of state.object -*/ - -const transmit = (state,object,status) => { - msgNum ++; - msg = { - n: msgNum.toString().slice(-4), - s: state.substr(0,4), - o: object.substr(0,4), - v: status.substr(0,4), - }; - message= msg.n + "," + msg.s + "," + msg.o + "," + msg.v; - NRF.setAdvertising({},{ - showName: false, - manufacturer: 0x0590, - manufacturerData: JSON.stringify(message)}); -}; - -/* -CONFIGURATION AREA - ICON DEFINITIONS -Retrieve 30px PNG icons from: -https://icons8.com/icon/set/speak/ios-glyphs -Create icons using: -https://www.espruino.com/Image+Converter -Use compression: true -Transparency: true -Diffusion: flat -Colours: 16bit RGB -Ouput as: Image Object -Add an additional element to the icons array -with a unique name and the data from the Image Object -*/ -const icons = [ - { - name: "walk", - data: "gEBAP4B/ALyh7b/YALHfY9tACY55HfYdNHto7pHpIbXbL5fXAD6VlHuYAjHf47/Hf47tHK47LDa45zHc4NHHeILJHeonTO9o9rHf47/eOoB/ANg=" - }, - { - name: "sit", - data: "gEBAP4B/AP4BacO4ANHPI/rACp1/Hf49rGtI5/He7n3ACY55HcYAZHf45/Hf45rHe4XHGbI7/Va47zZZrpbHfbtXD5Y/vHcYB/AP4BmA" - }, - { - name: "joystick", - data: "gEBAP4B/AP4BMavIALHPI9vHf47/eP45vHpY5xHo451Hf47/FuYAHHNItHABa33AP6xpAD455HqY7/Hf47/Hd49pHKIB/AP4B/AMwA==" - }, - { - name: "left", - data: "gEBAP4B/AP4BKa9ojHAC5pfHJKDTUsYdZHb6ZfO+I9dABabdLbIBdHf473PP47NJdY7/ePIB/RJop5Ys7t/AP6PvD7o7fP8Y1zTZoHPf/4B/AP4B+A==" - }, - { - name: "right", - data: "gEBAP4B/AP4BKa+oAXDo45hCaqFbUbLBfbbo7bHMojTR7Y5LHa51ZALo75Ov47/FeY77AP4B5WdbF3dv4B/R94fdHb5/jGuabNA57//AP4B/APw=" - }, - { - name: "forward", - data: "gEBAP4B/AKSX5avIALHPI9tACY55HsoAbHPI9fHfZFVGMo7/Hf47/Hf47/Hf47/Hf47/Hf47/Hf47/Hf49XHOIB/ALw=" - }, - { - name: "backward", - data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/Hf47/Hf47/Hf47/HfIAfHf491W/L15HMo9THNI9PHNo9LHOI9HHOoB/ALg=" - }, - { - name: "back", - data: "gEBAP4B/AP4B/AKgADHPI71HP45/HP45/HP45/HP45/Hf49/Hv49/Hv49/Hv49/Hv497He4B/AP4B/AJAA==" - }, - { - name: "mic_on", - data: "gEBAP4B/AKCZ5a/Y7/Hf47/Hf47/Hf47/GbY7TIcY7/Hf47/Hf47/HdY9NCpp5lCb57fOdYvNeJo91HNrlvHf7tVIdY77AP4BiA=" - }, - { - name: "comms", - data: "gEBAP4B+QvbF7ABo7/He49tACI7/Hf47zHtI7jJq47lRqoAVEqY7nHsoAZGJo71HrKxfQaY7bdKo7/Hdqz5B5Y7zHK47RD55FRHao3XHKo7JG7L1NHeJTbHboB/AP4BG" - }, - { - name: "pawn", - data: "gEBAP4B/AP4B/AP4BEAA455HuY7/Hf47xAB47/PuI1xPZY7/Hf47/G9Y/zHfIATHPI9nHfYB/AOYAfHf4B/AP4B/APA=" - }, - { - name: "sleep", - data: "gEBAP4B/AP4B2ACY7/Quq95HP45/HP4APOdY7fACZfnHcaZZAL45/HP45/E7YAHCaZFZHfbh/HP45/HOoAHHf4B/AP4B/AP4BIA=" - }, - { - name: "awake", - data: "gEBAP4B/AKyb7HfIAFHPI77Ov451Hf453Hf453HdoAbHf45/Hf5HrHNY7NHNo7/HO47/HO47HHPJ1/Heo51HfoB/ALg=" - }, - { - name: "wag_h", - data: "gEBAP4B/AP4B/AP4B/AP4B/AMwADD+oAFHb4hTHMIlXHMopTHNItPAG47/WfY9tFKY9lEq49hELY7ja8YB/AP4B/AP4B/AP4B/AP4BCA" - }, - { - name: "wag_v", - data: "gEBAP4B/AP4BOafIAHHPI9xAB45vd449rFZIHLHsonJBKa7rGNo7/Hf47/Hf47/Hf47/Hf4xlBKY7hFIoHLQM4rHApK7rAB71xHOo9LHOI9HHOoB/AP4BYA=" - } - ]; - -/* finds icon data by name in the icon array and returns an image object*/ -const drawIcon = (name) => { - for (var icon of icons) { - if (icon.name == name) { - image = { - width : 30, height : 30, bpp : 16, - transparent : 1, - buffer: require("heatshrink").decompress(atob(icon.data)) - }; - return image;} - } -}; - -/* -CONFIGURATION AREA - BUTTON DEFINITIONS -for a simple button, just define a primary colour -and an icon name from the icon array and -the text to display beneath the button -for toggle buttons, additionally provide secondary -colours, icon name and text. Also provide a reference -to a global variable for the value of the button. -The global variable should be declared at the start of -the program and it may be adviable to use the 'status_name' -format to ensure it is clear. -*/ - -var joystickBtn = { - primary_colour: 0x653E, - primary_icon: 'joystick', - primary_text: 'Joystick', - }; - -var turnLeftBtn = { - primary_colour: 0x653E, - primary_text: 'Left', - primary_icon: 'left', - }; - -var turnRightBtn = { - primary_colour: 0x33F9, - primary_text: 'Right', - primary_icon: 'right', - }; - -var tailHBtn = { - primary_colour: 0x653E, - primary_text: 'Wag Tail', - primary_icon: 'wag_h', - }; - -var tailVBtn = { - primary_colour: 0x33F9, - primary_text: 'Wag Tail', - primary_icon: 'wag_v', - }; - -var chessBtn = { - primary_colour: 0xE9C7, - primary_text: 'Off', - primary_icon: 'pawn', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'On', - secondary_icon : 'pawn', - value: status_chess - }; - -var wakeBtn = { - primary_colour: 0xE9C7, - primary_text: 'Sleeping', - primary_icon: 'sleep', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'Awake', - secondary_icon : 'awake', - value: status_wake - }; - -var autoBtn = { - primary_colour: 0xE9C7, - primary_text: 'Stop', - primary_icon: 'sit', - toggle: true, - secondary_colour: 0x3F48, - secondary_text: 'Move', - secondary_icon : 'walk', - value: status_auto - }; - -/* -CONFIGURATION AREA - SCREEN DEFINITIONS -a screen can have a button (as defined above) -on the left and/or the right of the screen. -in adddition a screen can optionally have -an icon for each of the three buttons on -the left hand side of the screen. These -are defined as btn1, bt2 and bt3. The -values are names from the icon array. -*/ -const menuScreen = { - left: wakeBtn, - right: joystickBtn, - btn1: "pawn", - btn2: "wag_v", -}; - -const joystickScreen = { - left: turnLeftBtn, - right: turnRightBtn, - btn1: "forward", - btn2: "backward", - btn3: "back" -}; - -const tailScreen = { - left: tailHBtn, - right: tailVBtn, - btn3: "back" -}; - -const chessScreen = { - left: chessBtn, - right: autoBtn, - btn3: "back" -}; - - -/* base state definition -Each of the screens correspond to a state; -this class provides a constuctor for each -of the states -*/ -class State { - constructor(params) { - this.state = params.state; - this.events = params.events; - this.screen = params.screen; - } -} - -/* -CONFIGURATION AREA - BUTTON BEHAVIOURS/STATE TRANSITIONS -This area defines how each screen behaves. -Each screen corresponds to a different State of the -state machine. This makes it much easier to isolate -behaviours between screens. -The state value is transmitted whenever a button is pressed -to provide context (so the receiving device, knows which -button was pressed on which screen). -The screens are defined above. -The events section identifies if a particular button has been -pressed and released on the screen and an action can then be taken. -The events function receives a notification from a mySetWatch which -provides an event object that identifies which button and whether -it has been pressed down or released. Actions can then be taken. -The events function will always return a State object. -If the events function returns different State from the current -one, then the state machine will change to that new State and redrsw -the screen appropriately. -To add in additional capabilities for button presses, simply add -an additional 'if' statement. -For toggle buttons, the value of the appropiate status object is -inversed and the new value transmitted. -*/ - -/* The Home State/Page is where the application beings */ - -const Home = new State({ - state: "K9Menu", - screen: menuScreen, - events: (event) => { - if ((event.object == "top") && (event.status == "end")) { - return Chess; - } - if ((event.object == "middle") && (event.status == "end")) { - return Tail; - } - if ((event.object == "right") && (event.status == "end")) { - return Joystick; - } - if ((event.object == "left") && (event.status == "end")) { - status_wake.value = !status_wake.value; - transmit(this.state, "wake", onOff(status_wake.value)); - return this; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const Chess = new State({ - state: "Chess", - screen: chessScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return Home; - } - if ((event.object == "right") && (event.status == "end")) { - status_auto.value = !status_auto.value; - transmit(this.state, "follow", onOff(status_auto.value)); - return this; - } - if ((event.object == "left") && (event.status == "end")) { - status_chess.value = !status_chess.value; - transmit(this.state, "chess", onOff(status_chess.value)); - return this; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -const Tail = new State({ - state: "Tail", - screen: tailScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - return Home; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -/* Joystick page state */ -const Joystick = new State({ - state: "Joystick", - screen: joystickScreen, - events: (event) => { - if ((event.object == "bottom") && (event.status == "end")) { - transmit("Joystick", "joystick", "off"); - return Home; - } - transmit(this.state, event.object, event.status); - return this; - } -}); - -/* translate button status into english */ -const startEnd = status => status ? "start" : "end"; - -/* translate status into english */ -const onOff= status => status ? "on" : "off"; - - -/* create watching functions that will change the global -button status when pressed or released -This is actuslly the hesrt of the program. When a button -is not being pressed, nothing is happening (no loops). -This makes the progrsm more battery efficient. -When a setWatch event is raised, the custom callbacks defined -here will be called. These then fired as events to the current -state/screen of the state mschine. -Some events, will result in the stste of the state machine -chsnging, which is why the screen is redrswn after each -button press. -*/ -const setMyWatch = (params) => { - setWatch(() => { - params.bool=!params.bool; - machine = machine.events({object: params.label, status: startEnd(params.bool)}); - drawScreen(machine.screen); - }, params.btn, {repeat:true, edge:"both"}); -}; - -/* object array used to set up the watching functions -*/ -const buttons = [ - {bool : bottom_btn, label : "bottom",btn : BTN3}, - {bool : middle_btn, label : "middle",btn : BTN2}, - {bool : top_btn, label : "top",btn : BTN1}, - {bool : left_btn, label : "left",btn : BTN4}, - {bool : right_btn, label : "right",btn : BTN5} - ]; - -/* set up watchers for buttons */ -for (var button of buttons) - {setMyWatch(button);} - -/* Draw various kinds of buttons */ -const drawButton = (params,side) => { - g.setFontAlign(0,1); - icon = drawIcon(params.primary_icon); - text = params.primary_text; - g.setColor(params.primary_colour); - const x = (side == "left") ? 0 : 120; - if ((params.toggle) && (params.value.value)) { - g.setColor(params.secondary_colour); - text = params.secondary_text; - icon = drawIcon(params.secondary_icon); - } - g.fillRect(0+x,28,119+x, 239); - g.setColor(0x000); - g.setFont("Vector",15); - g.setFontAlign(0,0.0); - g.drawString(text,60+x,160); - options = {rotate: 0, scale:2}; - g.drawImage(icon,x+60,120,options); -}; - -/* Draw the pages corresponding to the states */ -const drawScreen = (params) => { - drawButton(params.left,'left'); - drawButton(params.right,'right'); - g.setColor(0x000); - if (params.btn1) {g.drawImage(drawIcon(params.btn1),210,40);} - if (params.btn2) {g.drawImage(drawIcon(params.btn2),210,125);} - if (params.btn3) {g.drawImage(drawIcon(params.btn3),210,195);} -}; - -machine = Home; // instantiate the state machine at Home -Bangle.drawWidgets(); // draw active widgets -drawScreen(machine.screen); // draw the screen diff --git a/apps/k9control/k9_icon_30.png b/apps/k9control/k9_icon_30.png deleted file mode 100644 index f8ecae2b85dc24a11aaa4cb4e0dedba20c92e5cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4779 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 Z9FxZ=hg`FO|9t`gll|tDyZT2@{R^8<=kNdk From 1658b5f035f9141d0a226b6763e900c5404c1589 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 12 Jun 2020 15:10:08 +0100 Subject: [PATCH 715/878] new pixels --- apps.json | 2 +- apps/about/ChangeLog | 1 + apps/about/app.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 7aaf66a13..a09aa6c6b 100644 --- a/apps.json +++ b/apps.json @@ -53,7 +53,7 @@ { "id": "about", "name": "About", "icon": "app.png", - "version":"0.05", + "version":"0.06", "description": "Bangle.js About page - showing software version, stats, and a collaborative mural from the Bangle.js KickStarter backers", "tags": "tool,system", "allow_emulator":true, diff --git a/apps/about/ChangeLog b/apps/about/ChangeLog index 16aea0610..2a050c91e 100644 --- a/apps/about/ChangeLog +++ b/apps/about/ChangeLog @@ -3,3 +3,4 @@ 0.03: Actual pixels as of 5 Mar 2020 0.04: Actual pixels as of 9 Mar 2020 0.05: Actual pixels as of 27 Apr 2020 +0.06: Actual pixels as of 12 Jun 2020 diff --git a/apps/about/app.js b/apps/about/app.js index 57c85563d..4b4589262 100644 --- a/apps/about/app.js +++ b/apps/about/app.js @@ -29,5 +29,5 @@ g.drawString(NRF.getAddress(),120,232); g.flip(); // Pixel chooser image -g.drawImage(require("heatshrink").decompress(atob("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")),0,135); +g.drawImage(require("heatshrink").decompress(atob("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")),0,135); g.flip(); From a1820b7e7ec5f60002567e74ff49c1b4fe7ca66e Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Sat, 13 Jun 2020 08:15:43 +0200 Subject: [PATCH 716/878] Added Mixed Clock 2 fork of original mixed clock Differences to original Mixed Clock: - Color is all white for better readability in the bright sunlight - Thicker clock hands for better readability in the bright sunlight - Extra space under the clock for widgets - Seconds in the digital clock --- apps.json | 13 ++++ apps/miclock2/clock-mixed-icon.js | 1 + apps/miclock2/clock-mixed.js | 113 ++++++++++++++++++++++++++++++ apps/miclock2/clock-mixed.png | Bin 0 -> 707 bytes 4 files changed, 127 insertions(+) create mode 100644 apps/miclock2/clock-mixed-icon.js create mode 100644 apps/miclock2/clock-mixed.js create mode 100755 apps/miclock2/clock-mixed.png diff --git a/apps.json b/apps.json index a09aa6c6b..55d70fe34 100644 --- a/apps.json +++ b/apps.json @@ -1945,5 +1945,18 @@ {"name":"gpspoilog.app.js","url":"app.js"}, {"name":"gpspoilog.img","url":"app-icon.js","evaluate":true} ] + }, + { "id": "miclock2", + "name": "Mixed Clock 2", + "icon": "clock-mixed.png", + "version":"0.01", + "description": "White color variant of the Mixed Clock with thicker clock hands for better readability in the bright sunlight, extra space under the clock for widgets and seconds in the digital clock.", + "tags": "clock", + "type":"clock", + "allow_emulator":true, + "storage": [ + {"name":"miclock.app.js","url":"clock-mixed.js"}, + {"name":"miclock.img","url":"clock-mixed-icon.js","evaluate":true} + ] } ] diff --git a/apps/miclock2/clock-mixed-icon.js b/apps/miclock2/clock-mixed-icon.js new file mode 100644 index 000000000..3ca3b0612 --- /dev/null +++ b/apps/miclock2/clock-mixed-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AH4ATiwAGFdYzlFp4xeFyYwZD49kxGs2fX6+z1mIsgxcDQtAxArCAA+zxFAGDAYFxAsJAAuIGCxcF1omHgEABI+sGCouERRIvJSgKTEFzovLGAJgRCIiMIF5ySGF57qMF5nXsgvORoggLF5yRPLyAvO6+IF6LsKF6JgEF5lkD5gvPYIiOaF6CQMBYesD5oAP1gvPXxpfDAQIAFYCILDJ5wvP64veACCPeAB6PQd4p9EQQ4MLd6GIF7uIF5YwDsgiNAY4vHsguLYBJfXXxiQKL66ONF4lAL7dAF5pgIF6y9DFxYvEi2sF6+sDwgvLGAryEACLsEFxrCGGCmzXh5gJSQYAPRgovQGA1kMR7qEFyQwHi2IGJWzxCLEFygwIMYOI1gzC2esxBbGFywxKABotXGCwuaGKQtdGZorjAH4A/AF4=")) diff --git a/apps/miclock2/clock-mixed.js b/apps/miclock2/clock-mixed.js new file mode 100644 index 000000000..d928a5185 --- /dev/null +++ b/apps/miclock2/clock-mixed.js @@ -0,0 +1,113 @@ +// Code based on the original Mixed Clock + +/* jshint esversion: 6 */ +var locale = require("locale"); +const Radius = { "center": 7, "hour": 60, "min": 80, "dots": 88 }; +const Center = { "x": 120, "y": 96 }; +const Widths = { hour: 2, minute: 2 }; +var buf = Graphics.createArrayBuffer(240,192,1,{msb:true}); + +function rotatePoint(x, y, d) { + rad = -1 * d / 180 * Math.PI; + var sin = Math.sin(rad); + var cos = Math.cos(rad); + xn = ((Center.x + x * cos - y * sin) + 0.5) | 0; + yn = ((Center.y + x * sin - y * cos) + 0.5) | 0; + p = [xn, yn]; + return p; +} + + +// from https://github.com/espruino/Espruino/issues/1702 +function setLineWidth(x1, y1, x2, y2, lw) { + var dx = x2 - x1; + var dy = y2 - y1; + var d = Math.sqrt(dx * dx + dy * dy); + dx = dx * lw / d; + dy = dy * lw / d; + + return [ + // rounding + x1 - (dx + dy) / 2, y1 - (dy - dx) / 2, + x1 - dx, y1 -dy, + x1 + (dy - dx) / 2, y1 - (dx + dy) / 2, + + x1 + dy, y1 - dx, + x2 + dy, y2 - dx, + + // rounding + x2 + (dx + dy) / 2, y2 + (dy - dx) / 2, + x2 + dx, y2 + dy, + x2 - (dy - dx) / 2, y2 + (dx + dy) / 2, + + x2 - dy, y2 + dx, + x1 - dy, y1 + dx + ]; +} + + +function drawMixedClock(force) { + if ((force || Bangle.isLCDOn()) && buf.buffer) { + var date = new Date(); + var dateArray = date.toString().split(" "); + var isEn = locale.name.startsWith("en"); + var point = []; + var minute = date.getMinutes(); + var hour = date.getHours(); + var radius; + + g.reset(); + buf.clear(); + + // draw date + buf.setFont("6x8", 2); + buf.setFontAlign(-1, 0); + buf.drawString(locale.dow(date,true) + ' ', 4, 16, true); + buf.drawString(isEn?(' ' + dateArray[2]):locale.month(date,true), 4, 176, true); + buf.setFontAlign(1, 0); + buf.drawString(isEn?locale.month(date,true):(' ' + dateArray[2]), 237, 16, true); + buf.drawString(dateArray[3], 237, 176, true); + + // draw hour and minute dots + for (i = 0; i < 60; i++) { + radius = (i % 5) ? 2 : 4; + point = rotatePoint(0, Radius.dots, i * 6); + buf.fillCircle(point[0], point[1], radius); + } + + // draw digital time + buf.setFont("6x8", 3); + buf.setFontAlign(0, 0); + buf.drawString(dateArray[4], 120, 120, true); + + // draw new minute hand + point = rotatePoint(0, Radius.min, minute * 6); + buf.drawLine(Center.x, Center.y, point[0], point[1]); + buf.fillPoly(setLineWidth(Center.x, Center.y, point[0], point[1], Widths.minute)); + // draw new hour hand + point = rotatePoint(0, Radius.hour, hour % 12 * 30 + date.getMinutes() / 2 | 0); + buf.fillPoly(setLineWidth(Center.x, Center.y, point[0], point[1], Widths.hour)); + + // draw center + buf.fillCircle(Center.x, Center.y, Radius.center); + + g.drawImage({width:buf.getWidth(),height:buf.getHeight(),bpp:1,buffer:buf.buffer},0,24); + } +} + +Bangle.on('lcdPower', function(on) { + if (on) + drawMixedClock(true); + Bangle.drawWidgets(); +}); + +setInterval(() => drawMixedClock(true), 30000); // force an update every 30s even screen is off + +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +drawMixedClock(); // immediately draw +setInterval(drawMixedClock, 500); // update twice a second + +// Show launcher when middle button pressed after freeing memory first +setWatch(() => {delete buf.buffer; Bangle.showLauncher()}, BTN2, {repeat:false,edge:"falling"}); diff --git a/apps/miclock2/clock-mixed.png b/apps/miclock2/clock-mixed.png new file mode 100755 index 0000000000000000000000000000000000000000..f02ad5e9ee3a0bf215beed0d8cf9d8765015b314 GIT binary patch literal 707 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sa{_!qT!A#h<|7Pi4ua5HFbQJp zXIKqmL!}Nu)d0C0Pcy7Jz_11^0@Skh5J>T=0}N|{f(PHddk0d?KpYl@w4E=7yS=i zxccJNmV1x&cAi=$dl2LS>5?G7UISE7D(w3b_%UOgE( z!JUDDakr<7V~EG`yP-FyH5u@PGO{{49xq+BhH24`GiUz)zdd0UuRzrOz0Y4P%*~r^ z^3wOc^2PfW$F^^ch$ue%@mKy?_tOv8wJo#`nl<}Y!u3NA#!tV+Ut7og%jMagZw4Ro zD+SXcBV3mLpK;O3d1mj=M~eJ2945&Bcv5j~qy6^p{*u`W)<5Ssp1<(p+x6)W>;C`p z3VJ8nDW3M<$&K?(MdQ}6C(HPLH`@wLU`&6ZR(N8+k=Fwa1-{)A<4;`gJjwBfM{>>c z8cx2{A}0pFom;hAf1Q+6R8U%>z2_FMi@*vFMwf@2O~Ji+KCTI=sgF3C8s!3+ex-06 z+9M_U_34bQ6GPO39UE5ho#gzj{==f>4kuHJVwiB!2^Pf@jV!N(Sa-QJv#~!|Z+c+C z$0%h{#`U7Y;n#AH_zS$7dNNADCQfRTuuEo+=SNS!1CN9YDl1R>cR1RFJz@0Zc*HnS zebxyM&iX|mESHpDAK~wE@J`d4(r9#9Gv%fJEz{OB%YrfsR@$(yU1ZI@a!N;`)YYRF zPKIG8Y9&<@W!gPU>QC*}eH|kldpAJCXZALo+aczz+i!}5FaDl;y|`zksYFC@^4_=K b?F9c{ecS$I?dMmTpw#H;>gTe~DWM4f>^e@f literal 0 HcmV?d00001 From 687db8904f37410462d22b23fc12ce4d942a87fa Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Sat, 13 Jun 2020 08:25:48 +0200 Subject: [PATCH 717/878] Mixed Clock 2: Fix apps.json entry --- apps.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 55d70fe34..6c7ede88f 100644 --- a/apps.json +++ b/apps.json @@ -1955,8 +1955,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"miclock.app.js","url":"clock-mixed.js"}, - {"name":"miclock.img","url":"clock-mixed-icon.js","evaluate":true} + {"name":"miclock2.app.js","url":"clock-mixed.js"}, + {"name":"miclock2.img","url":"clock-mixed-icon.js","evaluate":true} ] } ] From 3404d244b66735cecfeaa91ea8d6be4289744d1b Mon Sep 17 00:00:00 2001 From: Ben Whittaker Date: Sat, 13 Jun 2020 16:29:17 -0400 Subject: [PATCH 718/878] App Manager: reduce memory usage --- apps.json | 2 +- apps/files/ChangeLog | 1 + apps/files/files.js | 29 ++++++++++++++--------------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/apps.json b/apps.json index a09aa6c6b..2cddea678 100644 --- a/apps.json +++ b/apps.json @@ -403,7 +403,7 @@ { "id": "files", "name": "App Manager", "icon": "files.png", - "version":"0.05", + "version":"0.06", "description": "Show currently installed apps, free space, and allow their deletion from the watch", "tags": "tool,system,files", "storage": [ diff --git a/apps/files/ChangeLog b/apps/files/ChangeLog index f2e5f64f5..b4037a733 100644 --- a/apps/files/ChangeLog +++ b/apps/files/ChangeLog @@ -2,3 +2,4 @@ 0.03: Add support for data files 0.04: Add functionality to sort apps manually or alphabetically ascending/descending. 0.05: Tweaks to help with memory usage +0.06: Reduce memory usage \ No newline at end of file diff --git a/apps/files/files.js b/apps/files/files.js index ab259d6df..e240a8e68 100644 --- a/apps/files/files.js +++ b/apps/files/files.js @@ -45,13 +45,13 @@ function globToRegex(pattern) { return new RegExp('^'+regex+'$'); } -function eraseFiles(app) { - app.files.split(",").forEach(f=>store.erase(f)); +function eraseFiles(info) { + info.files.split(",").forEach(f=>store.erase(f)); } -function eraseData(app) { - if(!app.data) return; - const d=app.data.split(';'), +function eraseData(info) { + if(!info.data) return; + const d=info.data.split(';'), files=d[0].split(','), sFiles=(d[1]||'').split(','); let erase = f=>store.erase(f); @@ -68,8 +68,9 @@ function eraseData(app) { } function eraseApp(app, files,data) { E.showMessage('Erasing\n' + app.name + '...'); - if (files) eraseFiles(app); - if (data) eraseData(app); + var info = store.readJSON(app.id + ".info", 1)||{}; + if (files) eraseFiles(info); + if (data) eraseData(info); } function eraseOne(app, files,data){ E.showPrompt('Erase\n'+app.name+'?').then((v) => { @@ -86,8 +87,7 @@ function eraseAll(apps, files,data) { E.showPrompt('Erase all?').then((v) => { if (v) { Bangle.buzz(100, 1); - for(var n = 0; n eraseApp(app, files, data)); } showApps(); }); @@ -100,7 +100,7 @@ function showAppMenu(app) { }, '< Back': () => showApps(), }; - if (app.data) { + if (app.hasData) { appmenu['Erase Completely'] = () => eraseOne(app, true, true); appmenu['Erase App,Keep Data'] = () => eraseOne(app, true, false); appmenu['Only Erase Data'] = () => eraseOne(app, false, true); @@ -120,11 +120,10 @@ function showApps() { var list = store.list(/\.info$/).filter((a)=> { return a !== 'setting.info'; - }).sort().map((app) => { - var ret = store.readJSON(app,1)||{}; - ret[''] = app; - return ret; - }); + }).map((a)=> { + let app = store.readJSON(a, 1) || {}; + return {id: app.id, name: app.name, hasData: !!app.data}; + }).sort(sortHelper());; if (list.length > 0) { list.reduce((menu, app) => { From 30864632a626dc66c7f41bd0d6993f640f6055a2 Mon Sep 17 00:00:00 2001 From: Ben Whittaker Date: Sat, 13 Jun 2020 17:10:42 -0400 Subject: [PATCH 719/878] largeclock: Adjust layout to account for new font --- apps.json | 2 +- apps/largeclock/ChangeLog | 1 + apps/largeclock/largeclock.js | 10 +++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps.json b/apps.json index a09aa6c6b..563e7fd70 100644 --- a/apps.json +++ b/apps.json @@ -1605,7 +1605,7 @@ "id": "largeclock", "name": "Large Clock", "icon": "largeclock.png", - "version": "0.03", + "version": "0.04", "description": "A readable and informational digital watch, with date, seconds and moon phase", "readme": "README.md", "tags": "clock", diff --git a/apps/largeclock/ChangeLog b/apps/largeclock/ChangeLog index fe44e5078..15dcd269e 100644 --- a/apps/largeclock/ChangeLog +++ b/apps/largeclock/ChangeLog @@ -1,3 +1,4 @@ 0.01: Init 0.02: fix 3/4 moon orientation 0.03: Change `largeclock.json` to 'data' file to allow settings to be preserved +0.04: Adjust layout to account for new vector font diff --git a/apps/largeclock/largeclock.js b/apps/largeclock/largeclock.js index 9975775fb..913040557 100644 --- a/apps/largeclock/largeclock.js +++ b/apps/largeclock/largeclock.js @@ -8,7 +8,7 @@ const moonR = 12; const moonX = 215; const moonY = 50; -const settings = require("Storage").readJSON("largeclock.json", 1); +const settings = require("Storage").readJSON("largeclock.json", 1)||{}; const BTN1app = settings.BTN1 || ""; const BTN3app = settings.BTN3 || ""; @@ -131,12 +131,12 @@ function drawTime(d) { g.setColor(1, 1, 1); g.setFontAlign(-1, -1); g.setFont("Vector", 100); - g.drawString(hours, 50, 24, true); + g.drawString(hours, 40, 24, true); g.setColor(1, 50, 1); - g.drawString(minutes, 50, 135, true); + g.drawString(minutes, 40, 135, true); g.setFont("Vector", 20); g.setRotation(3); - g.drawString(`${dow} ${day} ${month}`, 50, 15, true); + g.drawString(`${dow} ${day} ${month}`, 50, 10, true); g.drawString(year, 75, 205, true); lastMinutes = minutes; } @@ -144,7 +144,7 @@ function drawTime(d) { g.setFont("Vector", 20); g.setColor(1, 1, 1); g.setFontAlign(0, -1); - g.clearRect(200, 210, 240, 240); + g.clearRect(195, 210, 240, 240); g.drawString(seconds, 215, 215); } From 86bb7da3524a3266fe86f1d2a88387f3978bda43 Mon Sep 17 00:00:00 2001 From: Ben Whittaker Date: Sat, 13 Jun 2020 17:49:45 -0400 Subject: [PATCH 720/878] largeclock: Support 12 hour time --- apps.json | 2 +- apps/largeclock/ChangeLog | 1 + apps/largeclock/largeclock.js | 20 +++++++++++++++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/apps.json b/apps.json index 563e7fd70..ec757c96e 100644 --- a/apps.json +++ b/apps.json @@ -1605,7 +1605,7 @@ "id": "largeclock", "name": "Large Clock", "icon": "largeclock.png", - "version": "0.04", + "version": "0.05", "description": "A readable and informational digital watch, with date, seconds and moon phase", "readme": "README.md", "tags": "clock", diff --git a/apps/largeclock/ChangeLog b/apps/largeclock/ChangeLog index 15dcd269e..494002e0e 100644 --- a/apps/largeclock/ChangeLog +++ b/apps/largeclock/ChangeLog @@ -2,3 +2,4 @@ 0.02: fix 3/4 moon orientation 0.03: Change `largeclock.json` to 'data' file to allow settings to be preserved 0.04: Adjust layout to account for new vector font +0.05: Add support for 12 hour time \ No newline at end of file diff --git a/apps/largeclock/largeclock.js b/apps/largeclock/largeclock.js index 913040557..6f3d638fa 100644 --- a/apps/largeclock/largeclock.js +++ b/apps/largeclock/largeclock.js @@ -4,9 +4,11 @@ let interval; let lastMoonPhase; let lastMinutes; +const is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]; + const moonR = 12; const moonX = 215; -const moonY = 50; +const moonY = is12Hour ? 90 : 50; const settings = require("Storage").readJSON("largeclock.json", 1)||{}; const BTN1app = settings.BTN1 || ""; @@ -118,15 +120,23 @@ function drawMoon(d) { function drawTime(d) { const da = d.toString().split(" "); - const time = da[4].substr(0, 5).split(":"); + const time = da[4].split(":"); const dow = da[0]; const month = da[1]; const day = da[2]; const year = da[3]; - const hours = time[0]; + const hours = is12Hour ? ("0" + (((d.getHours() + 11) % 12) + 1)).substr(-2) : time[0]; + const meridian = d.getHours() < 12 ? "AM" : "PM"; const minutes = time[1]; - const seconds = d.getSeconds(); + const seconds = time[2]; if (minutes != lastMinutes) { + if (is12Hour) { + g.setFont("Vector", 18); + g.setColor(1, 1, 1); + g.setFontAlign(0, -1); + g.clearRect(195, 34, 240, 44); + g.drawString(meridian, 217, 34); + } g.clearRect(0, 24, moonX - moonR - 10, 239); g.setColor(1, 1, 1); g.setFontAlign(-1, -1); @@ -137,7 +147,7 @@ function drawTime(d) { g.setFont("Vector", 20); g.setRotation(3); g.drawString(`${dow} ${day} ${month}`, 50, 10, true); - g.drawString(year, 75, 205, true); + g.drawString(year, is12Hour ? 46 : 75, 205, true); lastMinutes = minutes; } g.setRotation(0); From 5805329248b80518f01f4272c0285102f16018ed Mon Sep 17 00:00:00 2001 From: Ben Whittaker Date: Sat, 13 Jun 2020 21:20:47 -0400 Subject: [PATCH 721/878] blobclk: Adapt to fillPoly changes --- apps.json | 2 +- apps/blobclk/ChangeLog | 1 + apps/blobclk/clock-blob.js | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps.json b/apps.json index a09aa6c6b..ab08ea051 100644 --- a/apps.json +++ b/apps.json @@ -869,7 +869,7 @@ "name": "Large Digit Blob Clock", "shortName" : "Blob Clock", "icon": "clock-blob.png", - "version":"0.03", + "version":"0.04", "description": "A clock with big digits", "tags": "clock", "type":"clock", diff --git a/apps/blobclk/ChangeLog b/apps/blobclk/ChangeLog index 1cfc59015..9715fc4ab 100644 --- a/apps/blobclk/ChangeLog +++ b/apps/blobclk/ChangeLog @@ -2,3 +2,4 @@ Only draw widgets after clearing screen - they update automatically Remove 'faceUp' check as it's automatic 0.03: Modified for use with new bootloader and firmware +0.04: Modified to account for changes in the behavior of Graphics.fillPoly diff --git a/apps/blobclk/clock-blob.js b/apps/blobclk/clock-blob.js index 1d85bc65e..76f10865f 100644 --- a/apps/blobclk/clock-blob.js +++ b/apps/blobclk/clock-blob.js @@ -18,8 +18,8 @@ function flip() { g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},55,26); } function drawPixel(ox,oy,x,y,r,p) { - let x1 = ox+x*(r*2+1); - let y1 = oy+y*(r*2+1); + let x1 = ox+x*(r*2); + let y1 = oy+y*(r*2); let xmid = x1+r; let ymid = y1+r; let x2 = xmid+r; @@ -27,14 +27,14 @@ function drawPixel(ox,oy,x,y,r,p) { if (p > 0) { if (p > 1) { buf.setColor(0,0,0); - buf.fillRect(x1,y1,x2,y2); + buf.fillPoly([x1,y1,x2,y1,x2,y2,x1,y2]); } buf.setColor(1,1,1); } else { buf.setColor(0,0,0); } if (p < 2) { - buf.fillRect(x1,y1,x2,y2); + buf.fillPoly([x1,y1,x2,y1,x2,y2,x1,y2]); } else if (p === 2) { buf.fillPoly([xmid,y1,x2,y1,x2,y2,x1,y2,x1,ymid]); } else if (p === 3) { From 36e1b6b61e02789bf33722bb4d7233a5e6022829 Mon Sep 17 00:00:00 2001 From: Ben Whittaker Date: Sat, 13 Jun 2020 21:27:54 -0400 Subject: [PATCH 722/878] App Manager: remove extra semicolon --- apps/files/files.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/files.js b/apps/files/files.js index e240a8e68..9e6c97702 100644 --- a/apps/files/files.js +++ b/apps/files/files.js @@ -123,7 +123,7 @@ function showApps() { }).map((a)=> { let app = store.readJSON(a, 1) || {}; return {id: app.id, name: app.name, hasData: !!app.data}; - }).sort(sortHelper());; + }).sort(sortHelper()); if (list.length > 0) { list.reduce((menu, app) => { From 2ffdd2d2829417572b102280b2ee3d7570dba418 Mon Sep 17 00:00:00 2001 From: Francesco Bedussi Date: Sun, 14 Jun 2020 16:15:59 +0200 Subject: [PATCH 723/878] feat: allow to disable BTN1 and BTN3 buttons --- apps.json | 2 +- apps/largeclock/ChangeLog | 1 + apps/largeclock/README.md | 2 +- apps/largeclock/largeclock.js | 4 ++-- apps/largeclock/largeclock.json | 4 ++-- apps/largeclock/settings.js | 4 ++++ 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/apps.json b/apps.json index a09aa6c6b..563e7fd70 100644 --- a/apps.json +++ b/apps.json @@ -1605,7 +1605,7 @@ "id": "largeclock", "name": "Large Clock", "icon": "largeclock.png", - "version": "0.03", + "version": "0.04", "description": "A readable and informational digital watch, with date, seconds and moon phase", "readme": "README.md", "tags": "clock", diff --git a/apps/largeclock/ChangeLog b/apps/largeclock/ChangeLog index fe44e5078..39ab5d629 100644 --- a/apps/largeclock/ChangeLog +++ b/apps/largeclock/ChangeLog @@ -1,3 +1,4 @@ 0.01: Init 0.02: fix 3/4 moon orientation 0.03: Change `largeclock.json` to 'data' file to allow settings to be preserved +0.04: Allow to disable BTN1 and BTN3 buttons diff --git a/apps/largeclock/README.md b/apps/largeclock/README.md index c9a325823..5c2ad42c2 100644 --- a/apps/largeclock/README.md +++ b/apps/largeclock/README.md @@ -11,7 +11,7 @@ A readable and informational digital watch, with date, seconds and moon phase an ## How to use it - The clock can be used as any other one, if you like it just set it as the default clock app in settings > select clock -- In setting > large clock you can select which app is to be open by BTN1 and BTN3 +- In setting > large clock you can select which app, if any, is to be open by BTN1 and BTN3 ## Credits diff --git a/apps/largeclock/largeclock.js b/apps/largeclock/largeclock.js index 9975775fb..fb4835146 100644 --- a/apps/largeclock/largeclock.js +++ b/apps/largeclock/largeclock.js @@ -9,8 +9,8 @@ const moonX = 215; const moonY = 50; const settings = require("Storage").readJSON("largeclock.json", 1); -const BTN1app = settings.BTN1 || ""; -const BTN3app = settings.BTN3 || ""; +const BTN1app = settings && settings.BTN1 || ""; +const BTN3app = settings && settings.BTN3 || ""; function drawMoon(d) { const BLACK = 0, diff --git a/apps/largeclock/largeclock.json b/apps/largeclock/largeclock.json index 7c38d59de..58c981197 100644 --- a/apps/largeclock/largeclock.json +++ b/apps/largeclock/largeclock.json @@ -1,4 +1,4 @@ { - "BTN1": "timer.app.js", - "BTN3": "calendar.app.js" + "BTN1": "", + "BTN3": "" } diff --git a/apps/largeclock/settings.js b/apps/largeclock/settings.js index a33f3c438..293f66677 100644 --- a/apps/largeclock/settings.js +++ b/apps/largeclock/settings.js @@ -21,6 +21,10 @@ if (a.n > b.n) return 1; return 0; }); + apps.push({ + n: "NONE", + src: "" + }); const settings = s.readJSON("largeclock.json", 1) || { BTN1: "", From 4635cd92bc8c2a612103e2774bbf059ded1795c0 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Sun, 14 Jun 2020 19:00:02 +0200 Subject: [PATCH 724/878] Pong: Keep display on during game --- apps.json | 2 +- apps/pong/ChangeLog | 1 + apps/pong/app.js | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 94c13ef9e..48b2fa4fc 100644 --- a/apps.json +++ b/apps.json @@ -1541,7 +1541,7 @@ "name": "Pong", "shortName": "Pong", "icon": "pong.png", - "version": "0.02", + "version": "0.03", "description": "A clone of the Atari game Pong", "tags": "game", "type": "app", diff --git a/apps/pong/ChangeLog b/apps/pong/ChangeLog index 6433ebce4..198d7bbde 100644 --- a/apps/pong/ChangeLog +++ b/apps/pong/ChangeLog @@ -1,2 +1,3 @@ 0.01: New App! 0.02: 2 players local + improve ai +0.03: Keep display on during gameplay diff --git a/apps/pong/app.js b/apps/pong/app.js index ba34d60b5..012cd8f81 100644 --- a/apps/pong/app.js +++ b/apps/pong/app.js @@ -337,6 +337,7 @@ function onFrame() { ai.show(); net(); ball.show(); + g.flip() } else if (state === 3) { g.clear(); g.setColor(0); From 223668faa069bd3eb8a0500183e8c11ff657073b Mon Sep 17 00:00:00 2001 From: Bastian Greshake Tzovaras Date: Wed, 17 Jun 2020 12:07:47 +0200 Subject: [PATCH 725/878] first add of 1button --- apps.json | 16 ++++++ apps/1button/ChangeLog | 1 + apps/1button/README.md | 25 +++++++++ apps/1button/interface.html | 107 ++++++++++++++++++++++++++++++++++++ apps/1button/widget.js | 36 ++++++++++++ apps/1button/widget.png | Bin 0 -> 4433 bytes 6 files changed, 185 insertions(+) create mode 100644 apps/1button/ChangeLog create mode 100644 apps/1button/README.md create mode 100644 apps/1button/interface.html create mode 100644 apps/1button/widget.js create mode 100644 apps/1button/widget.png diff --git a/apps.json b/apps.json index 94c13ef9e..a228723cd 100644 --- a/apps.json +++ b/apps.json @@ -1958,5 +1958,21 @@ {"name":"miclock2.app.js","url":"clock-mixed.js"}, {"name":"miclock2.img","url":"clock-mixed-icon.js","evaluate":true} ] + }, + { "id": "1button", + "name": "One-Button-Tracker", + "icon": "widget.png", + "version":"0.01", + "interface": "interface.html", + "description": "A widget that turns BTN1 into a tracker, records time of button press/release.", + "tags": "tool,quantifiedself,widget", + "type": "widget", + "readme": "README.md", + "storage": [ + {"name":"1button.wid.js","url":"widget.js"} + ], + "data": [ + {"name":"one_button_presses.csv","storageFile": true} + ] } ] diff --git a/apps/1button/ChangeLog b/apps/1button/ChangeLog new file mode 100644 index 000000000..4c21f3ace --- /dev/null +++ b/apps/1button/ChangeLog @@ -0,0 +1 @@ +0.01: New Widget! diff --git a/apps/1button/README.md b/apps/1button/README.md new file mode 100644 index 000000000..a909e9e7e --- /dev/null +++ b/apps/1button/README.md @@ -0,0 +1,25 @@ +# Widget Name + +Describe the app... + +Add screen shots (if possible) to the app folder and link then into this file with ![](.png) + +## Usage + +Describe how to use it + +## Features + +Name the function + +## Controls + +Name the buttons and what they are used for + +## Requests + +Name who should be contacted for support/update requests + +## Creator + +Your name diff --git a/apps/1button/interface.html b/apps/1button/interface.html new file mode 100644 index 000000000..42e8dcb1a --- /dev/null +++ b/apps/1button/interface.html @@ -0,0 +1,107 @@ + + + + + +
    + + + + + diff --git a/apps/1button/widget.js b/apps/1button/widget.js new file mode 100644 index 000000000..e0542137e --- /dev/null +++ b/apps/1button/widget.js @@ -0,0 +1,36 @@ +(() => { + var press_time = new Date(); + recFile = require("Storage").open("one_button_presses.csv","a"); + + // set widget text + function draw() { + g.reset(); // reset the graphics context to defaults (color/font/etc) + // add your code + g.fillCircle(this.x+6,this.y+6,4); + g.drawString("1BUTTON", this.x+13, this.y+4); + } + + // listen to button press to get start time + setWatch(function(e) { + console.log("Button pressed"); + digitalWrite(LED2,1); + press_time = new Date(); + Bangle.buzz(); + }, BTN1, { repeat: true, edge: 'rising', debounce: 50 }); + + // listen to button go to get end time & write data + setWatch(function(e) { + console.log("Button let go"); + digitalWrite(LED2,0); + var unpress_time = new Date(); + recFile.write([press_time.getTime(),unpress_time.getTime()].join(",")+"\n"); + }, BTN1, { repeat: true, edge: 'falling', debounce: 50 }); + + + // add your widget + WIDGETS["1button"]={ + area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right) + width: 100, // how wide is the widget? You can change this and call Bangle.drawWidgets() to re-layout + draw:draw // called to draw the widget + }; +})() diff --git a/apps/1button/widget.png b/apps/1button/widget.png new file mode 100644 index 0000000000000000000000000000000000000000..6a827c392eb485bfb870d1cdbb06dbb26bba9f5a GIT binary patch literal 4433 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 Q`OiOxnvyoOQo$ztKO4MhlK=n! literal 0 HcmV?d00001 From b6afd43b326c032254eed2911b46c7b4d7d4c19c Mon Sep 17 00:00:00 2001 From: Bastian Greshake Tzovaras Date: Wed, 17 Jun 2020 12:27:39 +0200 Subject: [PATCH 726/878] tweak interface --- apps/1button/interface.html | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/apps/1button/interface.html b/apps/1button/interface.html index 42e8dcb1a..56020bb12 100644 --- a/apps/1button/interface.html +++ b/apps/1button/interface.html @@ -10,28 +10,25 @@ var domRecords = document.getElementById("records"); function saveRecord(record,name) { - var csv = `${record.map(rec=>[rec.time, rec.bpm, rec.confidence].join(",")).join("\n")}`; + var csv = `${record.map(rec=>[rec.start_time, rec.end_time].join(",")).join("\n")}`; Util.saveCSV(name, csv); } -function recordLineToObject(l, hasRecordNbr) { +function recordLineToObject(l) { var t = l.trim().split(","); - var n = hasRecordNbr?1:0; var o = { - start_time: parseFloat(t[n+0]), - end_time: parseFloat(t[n+1]), + start_time: parseFloat(t[0]), + end_time: parseFloat(t[1]), }; - if (hasRecordNbr) - o.number = t[0]; return o; } -function downloadRecord(recordNbr, callback) { +function downloadRecord(callback) { Util.showModal("Downloading one-button tracker data..."); Util.readStorageFile(`one_button_presses.csv`,data=>{ Util.hideModal(); - var record = data.trim().split("\n").map(l=>recordLineToObject(l,false)); + var record = data.trim().split("\n").map(l=>recordLineToObject(l)); callback(record); }); } @@ -40,24 +37,24 @@ function getRecordList() { Util.showModal("Loading one button tracker records..."); domRecords.innerHTML = ""; Puck.write(`\x10(function() { - var f = require("Storage").open("one_button_presses.csv,"r"); - var l = f.readLine(); + var f = require("Storage").open("one_button_presses.csv,"r"); + var l = f.readLine(); })()\n`,recordList=>{ var recordLines = recordList.trim().split("\n"); var html = `
    \n`; recordLines.forEach(l => { - var record = recordLineToObject(l, true /*has record number*/); + var record = recordLineToObject(l); html += `
    -
    Heart Rate Record ${record.number}
    -
    ${(new Date(record.time*1000)).toString().substr(0,24)}
    +
    One-Button Presses
    +
    ${(new Date(record.start_time*1000)).toString().substr(0,24)}
    `; @@ -85,13 +82,13 @@ function getRecordList() { var task = button.getAttribute("task"); if (task=="delete") { Util.showModal("Deleting record..."); - Util.eraseStorageFile(`.heart${recordNbr.toString(36)}`,()=>{ + Util.eraseStorageFile(`one_button_presses.csv`,()=>{ Util.hideModal(); getRecordList(); }); } if (task=="download") { - downloadRecord(recordNbr, record => saveRecord(record, `HeartRateRecord${recordNbr}`)); + downloadRecord(record => saveRecord(record, `one_button_presses`)); } }); } From e8f09cb61d593276baa42fbb23dcedfeeef219c1 Mon Sep 17 00:00:00 2001 From: Bastian Greshake Tzovaras Date: Wed, 17 Jun 2020 12:36:41 +0200 Subject: [PATCH 727/878] remove looping in interface --- apps/1button/interface.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/1button/interface.html b/apps/1button/interface.html index 56020bb12..47ed9bd2c 100644 --- a/apps/1button/interface.html +++ b/apps/1button/interface.html @@ -43,8 +43,6 @@ function getRecordList() { var recordLines = recordList.trim().split("\n"); var html = `
    \n`; - recordLines.forEach(l => { - var record = recordLineToObject(l); html += `
    @@ -58,7 +56,6 @@ function getRecordList() {
    `; - }); if (recordLines.length==0) { html += `
    From df44962aeb1e7bcb76206ee4a175e347a98f648f Mon Sep 17 00:00:00 2001 From: Bastian Greshake Tzovaras Date: Wed, 17 Jun 2020 12:44:31 +0200 Subject: [PATCH 728/878] whops, undefined error --- apps/1button/interface.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/1button/interface.html b/apps/1button/interface.html index 47ed9bd2c..081e0bf2a 100644 --- a/apps/1button/interface.html +++ b/apps/1button/interface.html @@ -47,7 +47,7 @@ function getRecordList() {
    One-Button Presses
    -
    ${(new Date(record.start_time*1000)).toString().substr(0,24)}
    +
    Get all of your button presses