Created
November 7, 2014 19:41
-
-
Save kripken/57f7ab59c6fc5c2d44ed to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en-us"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<title>Emscripten-Generated Code</title> | |
<style> | |
body { | |
font-family: arial; | |
margin: 0; | |
padding: none; | |
} | |
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } | |
div.emscripten { text-align: center; } | |
div.emscripten_border { border: 1px solid black; } | |
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */ | |
canvas.emscripten { border: 0px none; } | |
#emscripten_logo { | |
display: inline-block; | |
margin: 0; | |
} | |
.spinner { | |
height: 30px; | |
width: 30px; | |
margin: 0; | |
margin-top: 20px; | |
margin-left: 20px; | |
display: inline-block; | |
vertical-align: top; | |
-webkit-animation: rotation .8s linear infinite; | |
-moz-animation: rotation .8s linear infinite; | |
-o-animation: rotation .8s linear infinite; | |
animation: rotation 0.8s linear infinite; | |
border-left: 5px solid rgb(235, 235, 235); | |
border-right: 5px solid rgb(235, 235, 235); | |
border-bottom: 5px solid rgb(235, 235, 235); | |
border-top: 5px solid rgb(120, 120, 120); | |
border-radius: 100%; | |
background-color: rgb(189, 215, 46); | |
} | |
@-webkit-keyframes rotation { | |
from {-webkit-transform: rotate(0deg);} | |
to {-webkit-transform: rotate(360deg);} | |
} | |
@-moz-keyframes rotation { | |
from {-moz-transform: rotate(0deg);} | |
to {-moz-transform: rotate(360deg);} | |
} | |
@-o-keyframes rotation { | |
from {-o-transform: rotate(0deg);} | |
to {-o-transform: rotate(360deg);} | |
} | |
@keyframes rotation { | |
from {transform: rotate(0deg);} | |
to {transform: rotate(360deg);} | |
} | |
#status { | |
display: inline-block; | |
vertical-align: top; | |
margin-top: 30px; | |
margin-left: 20px; | |
font-weight: bold; | |
color: rgb(120, 120, 120); | |
} | |
#progress { | |
height: 20px; | |
width: 30px; | |
} | |
#controls { | |
display: inline-block; | |
float: right; | |
vertical-align: top; | |
margin-top: 30px; | |
margin-right: 20px; | |
} | |
#output { | |
width: 100%; | |
height: 200px; | |
margin: 0 auto; | |
margin-top: 10px; | |
display: block; | |
background-color: black; | |
color: white; | |
font-family: 'Lucida Console', Monaco, monospace; | |
outline: none; | |
} | |
</style> | |
</head> | |
<body> | |
<script src="w.js"></script> | |
<a href="http://emscripten.org"> | |
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg | |
version="1.1" | |
id="Layer_1" | |
x="0px" | |
y="0px" | |
width="296px" | |
height="78px" | |
viewBox="420 120 100 170" | |
enable-background="new 0 0 900 400" | |
xml:space="preserve" | |
inkscape:version="0.48.4 r9939" | |
sodipodi:docname="emscripten_powered_by_logo.svg"><metadata | |
id="metadata345"><rdf:RDF><cc:Work | |
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type | |
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs | |
id="defs343"><linearGradient | |
y2="247.6265" | |
x2="225.1929" | |
y1="152.499" | |
x1="225.1929" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient5104"><stop | |
id="stop5106" | |
style="stop-color:#C1D72F" | |
offset="0.3227531" /><stop | |
id="stop5108" | |
style="stop-color:#BCD631" | |
offset="0.45119295" /><stop | |
id="stop5110" | |
style="stop-color:#AFD136" | |
offset="0.64491969" /><stop | |
id="stop5112" | |
style="stop-color:#ABD037" | |
offset="1" /><a:midPointStop | |
style="stop-color:#C1D72F" | |
offset="0.0123" /><a:midPointStop | |
style="stop-color:#C1D72F" | |
offset="0.3086" /><a:midPointStop | |
style="stop-color:#ABD037" | |
offset="1" /></linearGradient><linearGradient | |
inkscape:collect="always" | |
xlink:href="#SVGID_2_" | |
id="linearGradient5120" | |
x1="397.56918" | |
y1="128.12726" | |
x2="397.56918" | |
y2="166.25996" | |
gradientUnits="userSpaceOnUse" | |
gradientTransform="matrix(1.103059,0,0,1.103059,-38.997823,3.1312145)" /><filter | |
inkscape:collect="always" | |
id="filter5126"><feGaussianBlur | |
inkscape:collect="always" | |
stdDeviation="0.56377237" | |
id="feGaussianBlur5128" /></filter><linearGradient | |
inkscape:collect="always" | |
xlink:href="#SVGID_2_" | |
id="linearGradient5134" | |
gradientUnits="userSpaceOnUse" | |
gradientTransform="matrix(1.103059,0,0,1.103059,-38.997823,3.1312145)" | |
x1="397.56918" | |
y1="128.12726" | |
x2="397.56918" | |
y2="166.25996" /></defs><sodipodi:namedview | |
pagecolor="#ffffff" | |
bordercolor="#666666" | |
borderopacity="1" | |
objecttolerance="10" | |
gridtolerance="10" | |
guidetolerance="10" | |
inkscape:pageopacity="0" | |
inkscape:pageshadow="2" | |
inkscape:window-width="1440" | |
inkscape:window-height="838" | |
id="namedview341" | |
showgrid="false" | |
inkscape:zoom="0.63555556" | |
inkscape:cx="224.82424" | |
inkscape:cy="-52.085109" | |
inkscape:window-x="-8" | |
inkscape:window-y="-8" | |
inkscape:window-maximized="1" | |
inkscape:current-layer="Layer_1" /><g | |
id="g5130" | |
transform="matrix(0.91591318,0,0,0.91591318,28.176953,14.143571)"><path | |
transform="matrix(1.103059,0,0,1.103059,-35.073492,-16.03923)" | |
id="path5122" | |
style="fill:#383838;fill-opacity:0.34705882;stroke:none;filter:url(#filter5126)" | |
d="m 494.39333,173.6323 c 0.57407,0.28703 1.87073,1.00226 2.89426,1.02855 0.55732,0.0143 1.14006,-0.1672 1.60262,-0.4784 1.20466,-0.81046 2.23561,-2.03031 2.72683,-3.39661 0.19424,-0.54027 0.0238,-1.72222 0.0238,-1.72222 l -3.82713,-14.06478 -1.98533,0 0.50231,-2.67891 6.36261,0 2.55939,12.22285 4.78392,-9.68746 -2.00924,0 0,-2.65498 7.19979,0 -11.00301,22.38875 -1.69829,1.91358 -2.29628,1.3395 -2.46371,0.26312 -2.29628,-0.21528 -2.79859,-1.36342 z m -12.0637,-14.56445 c -0.93698,1.88565 -1.70261,4.35262 -0.81842,6.26333 0.36549,0.78976 1.35098,1.19428 2.192,1.41737 0.60934,0.16133 1.29167,0.0999 1.88775,-0.10468 0.48126,-0.1655 0.8829,-0.5224 1.255,-0.8697 0.40341,-0.3768 0.77723,-0.80461 1.03505,-1.29262 0.21864,-0.41395 0.40236,-0.84786 0.49325,-1.30698 0.20667,-1.0485 0.35879,-2.1079 0.33583,-3.17631 -0.0184,-0.87403 -0.0789,-1.87107 -0.47711,-2.64959 -0.26344,-0.51379 -0.77017,-0.71849 -1.33113,-0.85633 -0.42395,-0.10479 -0.81432,-0.0626 -1.21773,0.10517 -0.65479,0.27273 -1.2544,0.5311 -1.82112,0.95764 -0.57331,0.4317 -1.21403,0.86959 -1.53337,1.5127 z m 0.65588,-4.31208 c 0,0 2.19341,-1.80738 3.45549,-2.27082 0.71718,-0.26365 3.45363,-0.65258 4.15,-0.3378 1.47292,0.66633 2.26103,1.57529 2.7222,2.60001 0.46118,1.02472 0.69944,2.59956 0.79701,3.73627 0.13278,1.55027 -0.13682,3.77629 -0.53404,5.74843 -0.30079,1.49256 -1.01883,2.74423 -1.83478,3.92156 -1.06526,1.5373 -1.82382,2.15116 -3.66756,2.46594 -0.98864,0.16889 -1.93845,0.46787 -3.25466,0.0928 -1.4384,-0.40963 -2.35273,-0.81244 -3.39599,-1.63337 -0.72524,-0.57054 -1.16043,-1.54043 -1.16043,-1.54043 l 0,2.82636 -4.8903,0 3.39872,-23.01602 -1.92242,-0.85888 0.0403,-2.38127 7.25847,0.0534 z m -23.77803,2.20447 c 0.29175,1.49273 0.0813,4.83252 -0.86111,6.69751 -0.3062,0.60617 -0.94813,1.32967 -1.55479,1.6983 -1.01515,0.61713 -2.21688,1.21322 -3.3966,1.07639 -0.47944,-0.0541 -0.97036,-0.34348 -1.24383,-0.74151 -0.47686,-0.69328 -0.43621,-1.55032 -0.45448,-2.39198 -0.024,-1.06873 0.13137,-2.23775 0.38272,-3.277 0.18705,-0.7744 0.4229,-1.58254 0.86111,-2.24844 0.39037,-0.59323 0.92628,-1.12617 1.55478,-1.45909 0.54854,-0.29014 1.19695,-0.38467 1.81791,-0.40664 0.63637,-0.0231 1.3031,0.0385 1.88966,0.28704 0.3875,0.16453 0.92361,0.3524 1.00463,0.76542 z m 1.29312,-9.69052 -0.64254,6.12262 c 0,0 -1.68393,-0.96858 -2.605,-1.25148 -0.73032,-0.22434 -1.50312,-0.36654 -2.26624,-0.33838 -0.97069,0.0345 -1.91182,0.22099 -2.81751,0.57088 -0.9185,0.35497 -1.78344,0.94565 -2.49338,1.62792 -0.88025,0.84538 -1.51404,1.90455 -2.02977,3.0106 -0.39653,0.84993 -0.69517,1.75284 -0.87975,2.67232 -0.22875,1.14241 -0.44415,2.38719 -0.43937,3.55197 0.01,1.44865 0.0623,2.89489 0.54092,4.26214 0.25525,0.72907 0.71643,1.40578 1.28572,1.9283 0.56835,0.52207 1.29566,0.87604 2.02935,1.11621 0.41072,0.13491 0.85346,0.17274 1.28579,0.16935 1.00285,-0.01 2.03715,-0.0883 2.97671,-0.43999 0.66497,-0.2489 1.21759,-0.73399 1.79298,-1.1502 0.75304,-0.54475 2.16476,-1.86006 2.16476,-1.86006 l 0,1.62374 -0.5751,0 0,1.48807 6.86709,0 0,-2.84135 -1.92841,0 3.21374,-23.57782 -7.37422,0 0,2.33412 z m -93.60062,7.55781 2.33363,15.57933 6.23084,0 4.04243,-11.34169 1.62654,11.34169 5.88425,0 7.05633,-16.38872 0,-2.0141 -6.1713,0 0,2.82349 1.88966,0 -4.04243,10.16973 -0.74151,0 -1.29167,-12.55773 -5.38194,0 -4.7361,12.50989 -1.55478,-12.94538 -6.86496,0 0,2.82349 z m -12.15,0.72146 c -0.56264,0.0892 -1.03524,0.17358 -1.53086,0.45447 -0.737,0.41808 -1.46132,0.95771 -1.91357,1.67437 -0.44123,0.70048 -0.53204,1.57581 -0.66975,2.39196 -0.1751,1.04003 -0.20064,2.10306 -0.19136,3.15741 0.01,0.81614 -0.0138,1.66577 0.35879,2.39197 0.1904,0.37315 0.52874,0.80945 0.88503,1.02855 0.56015,0.34453 1.06632,0.55494 1.72222,0.598 0.72597,0.0483 1.48801,-0.18852 2.10493,-0.57408 0.59422,-0.37072 1.03334,-0.97401 1.38735,-1.5787 0.46117,-0.78744 0.70905,-1.69257 0.90895,-2.58334 0.20377,-0.90704 0.33579,-1.84565 0.28703,-2.77468 -0.0491,-0.92714 -0.18211,-1.88434 -0.57407,-2.72684 -0.2728,-0.58681 -0.70954,-1.00753 -1.29166,-1.29165 -0.44403,-0.21628 -0.99455,-0.24402 -1.48303,-0.16744 z m -6.62442,-0.73581 c 0.65404,-0.6664 1.4072,-1.25479 2.23273,-1.69161 1.0305,-0.54505 2.16429,-0.92749 3.31518,-1.11604 1.51307,-0.24806 3.09342,-0.2847 4.60036,0 0.88055,0.16632 1.78322,0.44742 2.50307,0.98113 0.77409,0.57312 1.35279,1.40936 1.79291,2.26639 0.42901,0.83457 0.6828,1.77223 0.77798,2.70605 0.16564,1.61985 0.024,3.29135 -0.37201,4.87103 -0.33328,1.33759 -0.88436,2.64754 -1.65745,3.78889 -0.67549,0.99679 -1.52894,1.91262 -2.53721,2.5709 -0.89957,0.58746 -1.9718,0.87641 -3.01035,1.15006 -0.87153,0.22963 -1.77166,0.4095 -2.67235,0.40576 -1.21068,-0.01 -2.47998,-0.0817 -3.58589,-0.57511 -1.09854,-0.48896 -1.89728,-1.32739 -2.60455,-2.30013 -0.61123,-0.83995 -1.02561,-1.59975 -1.31932,-2.87516 -0.2125,-0.9233 -0.40006,-2.19912 -0.37215,-3.14592 0.0335,-1.16537 0.3568,-2.74121 0.83416,-3.80434 0.52547,-1.17098 1.17609,-2.3161 2.07489,-3.2319 z m 94.95184,13.82318 c -2.20516,1.01761 -4.61429,1.69636 -7.02343,1.69636 -5.32726,0 -7.22678,-3.12145 -7.22678,-7.22678 0,-7.1251 4.54685,-11.19645 10.0772,-11.19645 3.7324,0 5.56453,1.69625 5.56453,4.47856 0,4.85189 -5.12329,6.27735 -10.41633,6.82001 0.10168,1.73076 0.81446,3.32485 3.3592,3.32485 1.2218,0 2.88401,-0.37315 4.91982,-1.22099 z m -3.22292,-11.77374 c 0,-0.81423 -0.57695,-1.28891 -1.62876,-1.28891 -1.89988,0 -3.46041,1.66212 -3.96978,4.34287 1.45897,-0.20368 5.59854,-0.91613 5.59854,-3.05396 z m -30.33408,11.77374 c -2.2054,1.01761 -4.61457,1.69636 -7.02371,1.69636 -5.32653,0 -7.22671,-3.12145 -7.22671,-7.22678 0,-7.1251 4.54679,-11.19645 10.07785,-11.19645 3.73175,0 5.56382,1.69625 5.56382,4.47856 0,4.85189 -5.12273,6.27735 -10.41568,6.82001 0.10142,1.73076 0.81422,3.32485 3.35884,3.32485 1.22158,0 2.8842,-0.37315 4.91994,-1.22099 z m -3.22305,-11.77374 c 0,-0.81423 -0.57638,-1.28891 -1.62883,-1.28891 -1.89959,0 -3.46023,1.66212 -3.96971,4.34287 1.4591,-0.20368 5.59854,-0.91613 5.59854,-3.05396 z m -82.36051,20.5268 -0.0679,-0.13571 0.98406,-5.66614 2.10303,-15.16698 c 0.0687,-0.40664 -0.0332,-0.61046 -0.30522,-0.71214 l -1.66259,-0.61111 0.37379,-2.57855 6.78556,0 -0.40663,2.71427 0.10142,0.0335 c 2.0016,-1.86631 4.10566,-3.08743 6.24306,-3.08743 2.91821,0 4.95366,1.86577 4.95366,6.78561 0,4.68241 -1.83206,11.6379 -8.14271,11.6379 -2.20534,0 -3.42694,-0.84825 -4.68256,-1.73039 l -0.74621,5.08917 c -0.0341,0.37361 0.0326,0.50898 0.47457,0.54273 l 3.42697,0.33969 -0.37385,2.5447 -9.0589,0 z m 6.78613,-12.04485 c 0.84787,0.71258 1.96788,1.32305 3.22348,1.32305 2.74798,0 3.76601,-3.86811 3.76601,-6.85368 0,-2.002 -0.47476,-3.32542 -1.76432,-3.32542 -1.35696,0 -3.08763,1.4591 -4.30913,2.54506 z m 81.08934,4.85147 0.33969,-2.54464 1.56064,-0.2038 c 0.47498,-0.0683 0.5429,-0.1695 0.61084,-0.67837 l 1.42466,-10.34864 c 0.0335,-0.37315 -0.0335,-0.61046 -0.33914,-0.71214 l -1.69691,-0.61111 0.37365,-2.57855 6.71797,0 -0.44097,3.05395 0.10191,0.0679 c 1.32326,-1.89982 3.22359,-3.46042 5.39485,-3.46042 0.7463,0 2.0359,0.13582 2.61295,0.30538 l -0.84863,6.17508 -3.96972,-0.13582 -0.10157,-1.76443 c -0.0335,-0.30537 -0.10223,-0.40701 -0.37391,-0.40701 -0.64452,0 -1.69636,0.78027 -2.64651,1.76455 l -1.18674,8.61817 c -0.0687,0.54303 -0.0334,0.64474 0.47477,0.67874 l 3.22351,0.27142 -0.37384,2.51081 -10.8575,0 z" | |
inkscape:connector-curvature="0" | |
sodipodi:nodetypes="cssscccccccccccccccccssssssssccssscssssscsssccccccccsssssssssccsccsssssssssscsscccccccccccccccccccccccccccccccsssscsssssscscsssssssscsssssssssscsssscsccsscscsssscsccsscsccccccccccsssccccccccssscccccccccccccsccccsccccccc" /><path | |
sodipodi:nodetypes="cssscccccccccccccccccssssssssccssscssssscsssccccccccsssssssssccsccsssssssssscsscccccccccccccccccccccccccccccccsssscsssssscscsssssssscsssssssssscsssscsccsscscsssscsccsscsccccccccccsssccccccccssscccccccccccccsccccsccccccc" | |
inkscape:connector-curvature="0" | |
d="m 509.55935,174.26011 c 0.63327,0.31663 2.06355,1.10555 3.19256,1.13455 0.61476,0.0158 1.25757,-0.18443 1.76781,-0.5277 1.3288,-0.89397 2.46618,-2.23946 3.00784,-3.74661 0.21419,-0.59598 0.0258,-1.89972 0.0258,-1.89972 l -4.22153,-15.51428 -2.18993,0 0.55406,-2.95501 7.01835,0 2.82313,13.48255 5.27696,-10.68586 -2.21631,0 0,-2.92858 7.94179,0 -12.13698,24.69605 -1.87332,2.11078 -2.5329,1.4776 -2.71762,0.29022 -2.53295,-0.23748 -3.08699,-1.50392 z m -13.30698,-16.06545 c -1.0335,2.08005 -1.87803,4.80122 -0.90274,6.90883 0.4032,0.87116 1.49018,1.31738 2.4179,1.56347 0.67214,0.17793 1.42477,0.1102 2.08233,-0.11548 0.53084,-0.1826 0.97383,-0.5762 1.38432,-0.9593 0.44502,-0.4157 0.85733,-0.8875 1.14176,-1.42582 0.24113,-0.45665 0.44375,-0.93526 0.54404,-1.44168 0.22797,-1.1566 0.3958,-2.3252 0.37043,-3.50371 -0.0204,-0.96413 -0.0869,-2.06387 -0.52631,-2.92259 -0.29054,-0.56679 -0.84946,-0.79259 -1.46826,-0.94463 -0.46761,-0.11559 -0.89829,-0.0686 -1.34322,0.11597 -0.72226,0.30083 -1.38368,0.5859 -2.00879,1.05634 -0.63242,0.4762 -1.33915,0.9593 -1.69146,1.6686 z m 0.72346,-4.75648 c 0,0 2.41951,-1.99358 3.81169,-2.50482 0.79109,-0.29085 3.80953,-0.71977 4.57766,-0.3726 1.6247,0.73503 2.49408,1.73759 3.00274,2.86791 0.50868,1.13043 0.77154,2.86756 0.87911,4.12137 0.14648,1.71007 -0.15092,4.16549 -0.58904,6.34083 -0.33179,1.64636 -1.12383,3.02703 -2.02388,4.32576 -1.17506,1.6957 -2.01178,2.37286 -4.04556,2.72004 -1.09051,0.18629 -2.13814,0.51607 -3.59006,0.10268 -1.5866,-0.45183 -2.59522,-0.89615 -3.74599,-1.8017 -0.79994,-0.62933 -1.28003,-1.6992 -1.28003,-1.6992 l 0,3.11766 -5.39426,0 3.74898,-25.38802 -2.12052,-0.94738 0.0443,-2.62669 8.00657,0.0587 z m -26.22853,2.43167 c 0.32185,1.64663 0.0893,5.33062 -0.9498,7.38781 -0.33781,0.66857 -1.04588,1.46667 -1.7151,1.8733 -1.11975,0.68073 -2.44527,1.33822 -3.7466,1.18729 -0.52883,-0.0601 -1.07036,-0.37888 -1.37203,-0.81791 -0.52601,-0.76478 -0.48121,-1.71012 -0.50128,-2.63848 -0.0263,-1.17893 0.14487,-2.46835 0.42212,-3.6147 0.20635,-0.8543 0.4665,-1.74564 0.94981,-2.48024 0.43067,-0.65433 1.02178,-1.24217 1.71508,-1.60939 0.60504,-0.32004 1.32025,-0.42437 2.00521,-0.44854 0.70197,-0.0251 1.4374,0.0425 2.08446,0.31654 0.4274,0.18153 1.01882,0.3888 1.10813,0.84432 z m 1.42642,-10.68922 -0.70874,6.75362 c 0,0 -1.85753,-1.06838 -2.8735,-1.38048 -0.80562,-0.24744 -1.65802,-0.40424 -2.49984,-0.37318 -1.07069,0.0382 -2.10882,0.24369 -3.1078,0.62968 -1.01321,0.39157 -1.96724,1.04315 -2.75039,1.79572 -0.97095,0.93248 -1.67003,2.10085 -2.23897,3.3208 -0.43738,0.93753 -0.76677,1.93354 -0.9704,2.94777 -0.2523,1.26016 -0.4899,2.63324 -0.48461,3.91802 0.011,1.59795 0.0683,3.19329 0.59661,4.70144 0.28155,0.80417 0.79028,1.55058 1.41822,2.127 0.62695,0.57587 1.4292,0.96634 2.23856,1.23121 0.45301,0.14881 0.94135,0.19054 1.41828,0.18685 1.10615,-0.011 2.24705,-0.0973 3.28346,-0.48539 0.73352,-0.2745 1.34304,-0.80959 1.97773,-1.2687 0.83064,-0.60085 2.38786,-2.05176 2.38786,-2.05176 l 0,1.79104 -0.63429,0 0,1.64147 7.57478,0 0,-3.13415 -2.12721,0 3.54494,-26.00772 -8.13411,0 0,2.57462 z m -103.24702,8.33671 2.57413,17.18493 6.87304,0 4.45903,-12.51049 1.79414,12.51049 6.49065,0 7.78353,-18.07772 0,-2.2217 -6.8073,0 0,3.11449 2.08446,0 -4.45903,11.21783 -0.8179,0 -1.42488,-13.85193 -5.93654,0 -5.2242,13.79919 -1.71497,-14.27958 -7.57246,0 0,3.11449 z m -13.4021,0.79586 c -0.62064,0.0982 -1.14194,0.19148 -1.68866,0.50127 -0.813,0.46118 -1.61192,1.05641 -2.11077,1.84697 -0.48673,0.77268 -0.58683,1.73821 -0.73875,2.63846 -0.1932,1.14723 -0.22134,2.31976 -0.21116,3.48281 0.011,0.90024 -0.0148,1.83747 0.39579,2.63847 0.21,0.41165 0.58324,0.89285 0.97623,1.13455 0.61796,0.38003 1.17622,0.61214 1.89972,0.6596 0.80077,0.0533 1.64141,-0.20792 2.32189,-0.63318 0.65546,-0.40892 1.13978,-1.07441 1.53029,-1.7414 0.50878,-0.86864 0.78215,-1.86707 1.00265,-2.84964 0.22477,-1.00044 0.37039,-2.03585 0.31663,-3.06058 -0.0541,-1.02274 -0.20091,-2.07854 -0.63327,-3.00784 -0.3009,-0.64731 -0.78264,-1.11143 -1.42476,-1.42485 -0.48983,-0.23858 -1.09705,-0.26912 -1.63583,-0.18464 z m -7.30711,-0.81171 c 0.72143,-0.735 1.55219,-1.38409 2.46282,-1.86591 1.1367,-0.60125 2.38729,-1.02309 3.65678,-1.23104 1.66908,-0.27366 3.41222,-0.314 5.07446,0 0.97135,0.18342 1.96702,0.49352 2.76107,1.08223 0.85389,0.63222 1.49219,1.55466 1.97771,2.49999 0.47321,0.92057 0.7531,1.95483 0.85808,2.98495 0.18274,1.78675 0.0263,3.63055 -0.41031,5.37303 -0.36757,1.47539 -0.97545,2.92034 -1.82825,4.17929 -0.74509,1.09959 -1.68654,2.10982 -2.79871,2.8359 -0.99227,0.64796 -2.175,0.96671 -3.32055,1.26856 -0.96139,0.25333 -1.95426,0.4517 -2.94774,0.44756 -1.33549,-0.011 -2.73559,-0.0897 -3.9555,-0.63431 -1.21174,-0.53936 -2.09278,-1.46419 -2.87295,-2.53723 -0.67423,-0.92645 -1.13131,-1.76457 -1.45532,-3.17146 -0.2344,-1.0184 -0.44126,-2.42572 -0.41044,-3.47012 0.0365,-1.28547 0.39349,-3.02371 0.92005,-4.19644 0.57967,-1.29168 1.29729,-2.5548 2.2888,-3.565 z m 104.73744,15.24778 c -2.43247,1.12251 -5.0899,1.87126 -7.74734,1.87126 -5.87626,0 -7.97147,-3.44315 -7.97147,-7.97158 0,-7.8594 5.0154,-12.35035 11.11569,-12.35035 4.11711,0 6.13803,1.87105 6.13803,4.94016 0,5.35189 -5.65129,6.92425 -11.48983,7.52281 0.11219,1.90916 0.89836,3.66755 3.7054,3.66755 1.3477,0 3.18121,-0.41165 5.42682,-1.34689 z m -3.55513,-12.98704 c 0,-0.89823 -0.63635,-1.42181 -1.79655,-1.42181 -2.09568,0 -3.81712,1.83342 -4.37899,4.79047 1.60937,-0.22468 6.17554,-1.01053 6.17554,-3.36866 z m -33.46028,12.98704 c -2.4327,1.12251 -5.09006,1.87126 -7.74751,1.87126 -5.87553,0 -7.97151,-3.44315 -7.97151,-7.97158 0,-7.8594 5.01539,-12.35035 11.11645,-12.35035 4.11635,0 6.13722,1.87105 6.13722,4.94016 0,5.35189 -5.65062,6.92425 -11.48908,7.52281 0.11182,1.90916 0.89812,3.66755 3.70494,3.66755 1.34748,0 3.1815,-0.41165 5.42704,-1.34689 z m -3.55514,-12.98704 c 0,-0.89823 -0.63578,-1.42181 -1.79674,-1.42181 -2.09539,0 -3.81683,1.83342 -4.37881,4.79047 1.60951,-0.22468 6.17555,-1.01053 6.17555,-3.36866 z m -90.84852,22.6422 -0.0749,-0.14971 1.08546,-6.25004 2.31984,-16.73008 c 0.0757,-0.44854 -0.0367,-0.67336 -0.33673,-0.78554 l -1.83388,-0.67411 0.41228,-2.84425 7.48486,0 -0.44853,2.99397 0.11182,0.0371 c 2.2079,-2.05871 4.52887,-3.40563 6.88646,-3.40563 3.21901,0 5.46427,2.05807 5.46427,7.48491 0,5.16501 -2.02094,12.8373 -8.98192,12.8373 -2.43264,0 -3.78014,-0.93565 -5.16516,-1.90869 l -0.82311,5.61357 c -0.0376,0.41212 0.0356,0.56148 0.52347,0.59873 l 3.78017,0.37469 -0.41234,2.8069 -9.9925,0 z m 7.48553,-13.28615 c 0.93528,0.78598 2.17068,1.45946 3.55568,1.45946 3.03118,0 4.15411,-4.26682 4.15411,-7.56009 0,-2.2083 -0.52366,-3.66812 -1.94612,-3.66812 -1.49686,0 -3.40583,1.6095 -4.75323,2.80736 z m 89.44624,5.35147 0.37469,-2.80694 1.72154,-0.2248 c 0.52388,-0.0753 0.5988,-0.1869 0.67374,-0.74827 l 1.57152,-11.41514 c 0.0365,-0.41155 -0.0368,-0.67336 -0.3741,-0.78554 l -1.87181,-0.67411 0.41215,-2.84425 7.41037,0 -0.48647,3.36865 0.11241,0.0749 c 1.45966,-2.09562 3.55581,-3.81702 5.95085,-3.81702 0.8232,0 2.2457,0.14982 2.88225,0.33688 l -0.93613,6.81148 -4.37882,-0.14982 -0.11196,-1.94633 c -0.0371,-0.33677 -0.11284,-0.44891 -0.41252,-0.44891 -0.71092,0 -1.87116,0.86067 -2.91921,1.94635 l -1.30904,9.50637 c -0.0757,0.59903 -0.0368,0.71124 0.52367,0.74874 l 3.55571,0.29932 -0.41234,2.76961 -11.9765,0 z" | |
style="fill:url(#linearGradient5134);fill-opacity:1;stroke:none" | |
id="path5080" /></g><path | |
fill="#E2E2E2" | |
d="M256.023,135.437H196.36c-16.432,0-29.8,13.368-29.8,29.8v73.527c0,16.432,13.368,29.8,29.8,29.8h59.663 c16.433,0,29.801-13.368,29.801-29.8v-73.527C285.824,148.805,272.456,135.437,256.023,135.437z M191.561,165.236 c0-2.646,2.153-4.8,4.8-4.8h59.663c2.647,0,4.801,2.153,4.801,4.8v73.527c0,2.646-2.153,4.8-4.801,4.8H196.36 c-2.646,0-4.8-2.153-4.8-4.8V165.236z" | |
id="path3" /><path | |
d="m 531.664,250.155 h 18.498 l -2.809,18.064 h 5.59 37.586 l 2.6,-17.718 c 4.98,-1.091 9.133,-3.455 12.512,-6.693 3.084,4.075 8.566,7.37 18.252,7.37 6.338,0 12.775,-1.807 17.174,-3.687 4.254,2.399 9.463,3.687 15.459,3.687 3.088,0 6.236,-0.355 9.426,-1.023 h 67.135 l 3.354,-24.827 -5.445,-0.764 1.879,-13.356 c 0.371,-2.386 0.449,-4.66 0.449,-6.156 l -0.008,-0.375 c -0.457,-12.191 -8.139,-19.765 -20.045,-19.765 -2.404,0 -4.623,0.314 -6.676,0.852 h -34.189 l -0.035,0.244 c -2.527,-0.701 -5.41,-1.096 -8.686,-1.096 -3.801,0 -7.406,0.555 -10.76,1.598 l 0.105,-0.746 h -12.467 l 1.826,-12.951 H 615.08 l -1.846,7.658 c -1.373,5.704 -2.213,5.793 -4.453,6.03 l -4.508,0.477 c -3.049,-1.424 -6.357,-2.065 -9.602,-2.065 -2.135,0 -4.275,0.284 -6.416,0.852 h -19.291 c 0.502,-1.772 0.775,-3.674 0.775,-5.678 0,-9.601 -6.846,-16.305 -16.646,-16.305 -11.055,0 -18.775,7.721 -18.775,18.776 0,0.951 0.082,1.869 0.219,2.764 -2.135,-0.288 -4.277,-0.409 -5.553,-0.409 -2.053,0 -4.072,0.288 -6.045,0.852 h -31.342 c -2.74,-0.553 -5.641,-0.852 -8.537,-0.852 -7.138,0 -13.492,1.674 -18.808,4.723 l -3.451,-1.461 c -3.711,-1.571 -11.232,-3.262 -18.979,-3.262 -8.933,0 -16.383,2.56 -21.576,7.016 -3.265,-4.473 -8.523,-7.016 -15.228,-7.016 -4.822,0 -9.021,1.477 -12.572,3.44 -2.996,-2.204 -6.796,-3.44 -11.115,-3.44 -2.327,0 -4.48,0.315 -6.476,0.852 h -33.963 l -0.035,0.245 c -2.526,-0.702 -5.41,-1.097 -8.687,-1.097 -20.458,0 -35.307,16.031 -35.307,38.117 0,17.363 10.785,28.149 28.148,28.149 3.087,0 6.236,-0.356 9.426,-1.023 h 88.816 c 3.706,0.676 7.669,1.023 11.154,1.023 8.907,0 16.278,-2.375 21.51,-6.593 4.872,4.252 11.585,6.593 19.728,6.593 3.053,0 6.206,-0.368 9.286,-1.023 h 44.664 2.069 z" | |
id="path5" | |
inkscape:connector-curvature="0" | |
style="fill:#e2e2e2" /><path | |
fill="#F5F5F5" | |
d="M255.023,133.437H195.36c-16.432,0-29.8,13.368-29.8,29.8v73.527c0,16.432,13.368,29.8,29.8,29.8h59.663 c16.433,0,29.801-13.368,29.801-29.8v-73.527C284.824,146.805,271.456,133.437,255.023,133.437z M190.561,163.236 c0-2.646,2.153-4.8,4.8-4.8h59.663c2.647,0,4.801,2.153,4.801,4.8v73.527c0,2.646-2.153,4.8-4.801,4.8H195.36 c-2.646,0-4.8-2.153-4.8-4.8V163.236z" | |
id="path7" /><g | |
id="g9"><g | |
id="g11"><path | |
fill="#FBFDF8" | |
d="M195.361,251.626c-8.161,0-14.8-6.64-14.8-14.8v-73.527c0-8.161,6.639-14.8,14.8-14.8h59.663 c8.161,0,14.8,6.639,14.8,14.8v73.527c0,8.16-6.639,14.8-14.8,14.8H195.361z" | |
id="path13" /><path | |
fill="#F0F4E1" | |
d="M255.024,152.499c5.964,0,10.8,4.835,10.8,10.8v73.527c0,5.965-4.835,10.8-10.8,10.8h-59.663 c-5.964,0-10.8-4.835-10.8-10.8v-73.527c0-5.964,4.835-10.8,10.8-10.8H255.024 M255.024,144.499h-59.663 c-10.366,0-18.8,8.434-18.8,18.8v73.527c0,10.366,8.434,18.8,18.8,18.8h59.663c10.366,0,18.8-8.434,18.8-18.8v-73.527 C273.824,152.933,265.391,144.499,255.024,144.499L255.024,144.499z" | |
id="path15" /></g><defs | |
id="defs17"><filter | |
id="Adobe_OpacityMaskFilter" | |
filterUnits="userSpaceOnUse" | |
x="176.562" | |
y="144.499" | |
width="97.263" | |
height="111.127"><feColorMatrix | |
type="matrix" | |
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" | |
color-interpolation-filters="sRGB" | |
result="source" | |
id="feColorMatrix20" /></filter></defs><mask | |
maskUnits="userSpaceOnUse" | |
x="176.562" | |
y="144.499" | |
width="97.263" | |
height="111.127" | |
id="SVGID_1_"><g | |
filter="url(#Adobe_OpacityMaskFilter)" | |
id="g23"><image | |
overflow="visible" | |
width="422" | |
height="480" | |
xlink:href="data:image/jpeg;base64,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 7fGT6fI+nyPp8j6fI+nyPp8j6fI+nyPp8j6fI+nyPp8D7x8fJtxp1m7Tp5jbw/MfWIjbXTk5SHsH j/sBQ63ZK2AdthqO8vXbUZWrJ0V/oJ7ZB7Sa+ofJMIkS6IySyJRLIkSyJEsiRLIkSyJEsiRLIkSy JVLYiRLYicEr8xfwSemN0kjy8PIdkfxQp0xWEAPYPH/YCh1uyVsAAz08ome2si37qZkumaULspIu 2aRkuyki7KSLspIuyki7KSLspIuyki7KSLtilC6qSLtilC6fNNFu5qz8k7wcI+vkAAHsHj/sBWoQ AAAAAAAAAAAAAAAAAAAAAAAAAHpAf//aAAgBAgABBQD/ACi//9oACAEDAAEFAP8AKL//2gAIAQEA AQUA6w6rz/LM+776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvv qs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qz vvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++ qzvvqs776rMfLPYHlHyRFUbivuDeUv1FOSVKJkRwE4CcAOAHADgBwA4AcAOAHADgBwA4AcAOAHAD gBwA4AcAOAHADgBwA4AcAOAnARciFyRUK8ndQcgyGxaaqf4fYHlHwRFUjZe68RsqbpGoKIUQkKYY kISEYJDAmBMCYEwJgTAmBMCYEwJgTAmBMCYEwJgTAmBMCYEwJgTAmCQWELCKoSFcNByEhIyxusk5 VVQV0VUL8vYHlGltupyqDlaIMREQaijcUoilMUSKgkZDDIYZDDIYZDDIYZDDIYZDDIYZDDIYZDDI YZDDIYZDDIYZDDIYZDDIYZDDIYZDDIYZDDILGQWKVRSuKORR2KPRCZltDiSYrjFXx9geUaG26nKs vy9KEjxhmONRxuOUMFLAjIjJdF0XRdIXSF0hdF0XRdF0XRdF0XRdF0XRdF0XRdIXSF0hdIXRdCsi sisFTBXHHY49GH4xMhU10y4tTFfw9geUCJ9rlcL6SNHGGBlgbZKGilsShDZQ+kPr/wBX0fSGygtC CtoVNDjI6wPsElgzCGjlLrdTden2B5QZfGvnYbCIkdkYZGmihsSn61ItJXQOtD7JIZJTBm0X6+Hs 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 DNdYwcM11jBwzXWMHDNdYwcM11jBwzXWMHDNdYwcM11jBwzXWMHDP+z/AEd/2MzUhXbvz7H6XVO/ Y7vFJSkpSUpKUlKSlJSkpSUpKUlKSlJSkpSUpKUlKSlJSkpSUpKUlKSlJSkpSUpKUlKSlJSkp+le p3d6ndOn4OZqQrt349EOqp0QT9PVfzGDBgwYMGDBgwYMGDBgwYMGDBgwYMGDBgwYMGDBgwYMGC9X RVh9/wAjo8nRfnmakK7d+H+LqdVEefTqonYYMGDBgwYMGDBgwYMGDBgwYMGDBgwYMGDBgwYMGDBg wYMGDBeqd/uKip2+/wAszUhXbsqOutURVT9SidhgwYMlZ/XsGDBgvYVFQVOnb6fHM1IV27J0QR95 O6idhOwyaWC9hU6d/oK6v0+GZqQrt2RFVOyCdhBJrUU/cRO6N+GZqQrt06CL07qIJNiijydGjzsu ZqQrt0dd/MRBBJsUUU/y+8uZqQrt06/YQQSbFFFOv2WXM1IV26KIJNyij0uZqQrt0e8iCTcoo/Lm akK7dHvIggk2KKKPy5mpCu3R7yIJNyij8uZqQrt0e8iCTcoo/LmakK7dHvIgk3KKPy5mpCu3R7yI JNyij8uZqQrt0e8iCTaooo/LmakK7dHvIgk3KKPy5mpCu3R7yIJNyij8uZqQrt0e8iCCTaoo/Lma kK7dHvIggk2qKPy5mpCu3R7yIIJNqij8uZqQrt0e8iCCTaoo/LmakK7dHvIggk2qKPy5mpCu3R7y IIJNqij8uZqQrt0e8iCCTaoo/LmakK7dHvIggk2qKPy5mpCu3R7yIIJNqij8uZqQrt0e8iCCTaoo /LmakK7dHvIggk2qKPy5mpCu3R7yIIJNqij8uZqQrt0e8iCCTaoo/LmakK7dHvIggk2qKPy5mpCu 3R7yIIJNqij8uZqQrt0e8iCCTaoo/LmakK7dHvIggk2qKPy5mpCu3R7yIIJNqij8uZqQrt0e8iCC Taoo/LmakK7dHvIggk2qKPy5mpCu3R7yIIJNqij8uZqQrt0e8iCTcoo/LmakK7dHvIgk2qKKPy5m pCu3R7yIJNyij8uZqQrt0e8iCTcoo/LmakK7dHvIgk3KKPy5mpCu3R7yIJNyij8uZqQrt0e8iCCT aoo/LmakK7dHvIgk3KKPy5mpCu3R4QSblFHpczUhXboqfcQQSbVFFT7y5mpCu3RPzEEEmxRRRHZc zUhXbojyfRR1RBJsUUUX7JLmakK7dk/bVfAgk2KKL37qwVV+suZqQrt2RHk+giook2L3F7i9GJ8M zUhXbsqItFRFRRO40aNmVo0aL3FhuL5+OZqQrt34I69REVFGjRo0aNGjf6po0aNGjRo0XuK5DXv9 zqrV+OZqQrt349UXt9hEVeijRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0Xq9/YVH V6OnVflmakK7d+XVOw3qh0e7FM7PJ7KQ0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRpSKaH6V6nR 3sh1eXr+BmakK7d/C7KqFJfZTX2U19lNfZTX2U19lN72U3vZTe9lN72U3vZTe9lN72U3vZTe9lN7 2U3vZTe9lN72U3vZTe9lN72U3vZTe9lN72U19lNfZTX2U19lNfZSX2d3l/Ej/wAj/wCf+7/jD6/y f5/7tBOnX+L/AMfr+5tPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPK m08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptP Km08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKn/jan//Z" | |
transform="matrix(0.24 0 0 0.24 174.5615 142.499)" | |
id="image25"></image></g></mask><g | |
opacity="0.09" | |
mask="url(#SVGID_1_)" | |
a:adobe-blending-mode="multiply" | |
a:adobe-opacity-share="1" | |
id="g27"><path | |
fill="#1D2915" | |
a:adobe-blending-mode="normal" | |
a:adobe-opacity-share="0" | |
d="M195.361,251.626 c-8.161,0-14.8-6.64-14.8-14.8v-73.527c0-8.161,6.639-14.8,14.8-14.8h59.663c8.161,0,14.8,6.639,14.8,14.8v73.527 c0,8.16-6.639,14.8-14.8,14.8H195.361z" | |
id="path29" /><path | |
fill="#1D2915" | |
a:adobe-blending-mode="normal" | |
a:adobe-opacity-share="0" | |
d="M255.024,152.499 c5.964,0,10.8,4.835,10.8,10.8v73.527c0,5.965-4.835,10.8-10.8,10.8h-59.663c-5.964,0-10.8-4.835-10.8-10.8v-73.527 c0-5.964,4.835-10.8,10.8-10.8H255.024 M255.024,144.499h-59.663c-10.366,0-18.8,8.434-18.8,18.8v73.527 c0,10.366,8.434,18.8,18.8,18.8h59.663c10.366,0,18.8-8.434,18.8-18.8v-73.527C273.824,152.933,265.391,144.499,255.024,144.499 L255.024,144.499z" | |
id="path31" /></g></g><g | |
id="g33"><g | |
id="g35"><linearGradient | |
id="SVGID_2_" | |
gradientUnits="userSpaceOnUse" | |
x1="225.1929" | |
y1="152.499" | |
x2="225.1929" | |
y2="247.6265"><stop | |
offset="0.0123" | |
style="stop-color:#C1D72F" | |
id="stop38" /><stop | |
offset="0.1394" | |
style="stop-color:#BCD631" | |
id="stop40" /><stop | |
offset="0.5859" | |
style="stop-color:#AFD136" | |
id="stop42" /><stop | |
offset="1" | |
style="stop-color:#ABD037" | |
id="stop44" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#C1D72F" /><a:midPointStop | |
offset="0.3086" | |
style="stop-color:#C1D72F" /><a:midPointStop | |
offset="1" | |
style="stop-color:#ABD037" /></linearGradient><path | |
d="M184.562,236.826c0,5.965,4.835,10.8,10.8,10.8h59.663c5.964,0,10.8-4.835,10.8-10.8v-73.527 c0-5.964-4.835-10.8-10.8-10.8h-59.663c-5.964,0-10.8,4.835-10.8,10.8V236.826z" | |
id="path46" | |
fill="url(#SVGID_2_)" /></g><defs | |
id="defs48"><filter | |
id="Adobe_OpacityMaskFilter_1_" | |
filterUnits="userSpaceOnUse" | |
x="184.562" | |
y="152.499" | |
width="81.263" | |
height="95.127"><feColorMatrix | |
type="matrix" | |
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" | |
color-interpolation-filters="sRGB" | |
result="source" | |
id="feColorMatrix51" /></filter></defs><mask | |
maskUnits="userSpaceOnUse" | |
x="184.562" | |
y="152.499" | |
width="81.263" | |
height="95.127" | |
id="SVGID_3_"><g | |
filter="url(#Adobe_OpacityMaskFilter_1_)" | |
id="g54"><image | |
overflow="visible" | |
width="356" | |
height="414" | |
xlink:href="data:image/jpeg;base64,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 zFhO7bfhcyUttpzKJlCjZiwndtvwuZKW205lEyhRsxYTu234XMlLbacyiZQo2YsJ3bb8LmSlttOZ RMoUbMWE7tt+FzJS22nMomUKNmLCd22/C5kpbbTmUTKFGzFhO7bfhcyUttpzKJlCjZiwndtvwuZK W205lEyhRsxYTu234XMlLbacyiZQo2YsJ3bb8LmSlttOZRMoUbMWE7tt+FzJS22nMomUKNmLCd22 /C5kpbbTmUTKFGzFhO7bfhcyUttpzKJlCjZiwndtvwuZKW205lEyhRsxYTu234XMlLbacyiZQo2Y sJ3bb8LmSlttOZRMoUbMWE7tt+FzJS22nMomUKNmLCd22/C5kpbbTmUTKFGzFhO7bfhcyUttpzKJ lCjZiwndtvwuZKW205lEyhRsxYTu234XMlLbacyiZQo2YsJ3bb8LmSlttOZRMoUbMWE7tt+FzJS2 2nMomUKNmLCd22/C5kpbbTmUTKFGzFhO7bfhcyUttpzCZQo38SwndtvwuZKW20dTVfvQQ+cmUXiI xFhxUsJ3bb8LmSlttGVPp8/C/go1fkTjky8RyqsB9T6KvD8CwndtvwuZKW23BKNR3wqftX+qCcRO JwyLiLxF4i0Ka8V/cuFhO7bfhcyUttuCKi/CpBRtOs74cnBF/qJ+oiRIkSJEiRIkSJEiRIkSJEiR IkSJEiRIkSJEiRIkReIv6hadFfl31d9EFc5flViuFhO7bfhcyUttv2ERrvzNT/VT4qIrf+TqIdVD qodVDqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTq pqdVNTqpqdVNTqpqdVDqodVDqC/xorl0F/O74av+qfYsJ3bb8LmSlttyywndtvzD/9k=" | |
transform="matrix(0.24 0 0 0.24 182.5615 150.499)" | |
id="image56"></image></g></mask><g | |
opacity="0.35" | |
mask="url(#SVGID_3_)" | |
a:adobe-opacity-share="1" | |
id="g58"><path | |
a:adobe-opacity-share="0" | |
d="M184.562,236.826c0,5.965,4.835,10.8,10.8,10.8h59.663 c5.964,0,10.8-4.835,10.8-10.8v-73.527c0-5.964-4.835-10.8-10.8-10.8h-59.663c-5.964,0-10.8,4.835-10.8,10.8V236.826z" | |
id="path60" | |
fill="#1D2915" /></g></g><linearGradient | |
id="SVGID_4_" | |
gradientUnits="userSpaceOnUse" | |
x1="226.1924" | |
y1="159.7139" | |
x2="226.1924" | |
y2="200"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" | |
id="stop63" /><stop | |
offset="0.3788" | |
style="stop-color:#F8FBF3" | |
id="stop65" /><stop | |
offset="1" | |
style="stop-color:#F2F7E8" | |
id="stop67" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="0.4383" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="1" | |
style="stop-color:#F2F7E8" /></linearGradient><polygon | |
fill="url(#SVGID_4_)" | |
points="221.189,159.714 214.142,180.951 224.048,180.951 214.142,200 238.243,173.61 227.655,173.61 236.978,159.714 " | |
id="polygon69" /><g | |
id="g71"><g | |
id="g73"><g | |
id="g75"><image | |
overflow="visible" | |
opacity="0.75" | |
a:adobe-blending-mode="multiply" | |
a:adobe-opacity-share="1" | |
width="392" | |
height="242" | |
xlink:href="data:image/png;base64,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 SUVORK5CYII=" | |
transform="matrix(0.24 0 0 0.24 179.2061 198.1514)" | |
id="image77"></image><g | |
id="g79"><radialGradient | |
id="SVGID_5_" | |
cx="225.1929" | |
cy="226.1387" | |
r="30.8299" | |
gradientTransform="matrix(1 0 0 0.75 0 56.5347)" | |
gradientUnits="userSpaceOnUse"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" | |
id="stop82" /><stop | |
offset="0.4828" | |
style="stop-color:#FDFEFB" | |
id="stop84" /><stop | |
offset="0.7611" | |
style="stop-color:#F8FBF3" | |
id="stop86" /><stop | |
offset="0.989" | |
style="stop-color:#F2F8E8" | |
id="stop88" /><stop | |
offset="1" | |
style="stop-color:#F2F7E8" | |
id="stop90" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="0.8025" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="1" | |
style="stop-color:#F2F7E8" /></radialGradient><path | |
fill="url(#SVGID_5_)" | |
d="M186.706,235.825c0,5.965,4.835,10.801,10.799,10.801h55.374c5.965,0,10.801-4.836,10.801-10.801 v-19.373c0-5.965-4.836-10.801-10.801-10.801h-55.374c-5.964,0-10.799,4.836-10.799,10.801V235.825z" | |
id="path92" /><path | |
fill="none" | |
stroke="#EDF5E5" | |
stroke-width="5" | |
stroke-miterlimit="10" | |
d="M186.706,235.825 c0,5.965,4.835,10.801,10.799,10.801h55.374c5.965,0,10.801-4.836,10.801-10.801v-19.373c0-5.965-4.836-10.801-10.801-10.801 h-55.374c-5.964,0-10.799,4.836-10.799,10.801V235.825z" | |
id="path94" /></g></g><path | |
opacity="0.74" | |
fill="#FFFFFF" | |
a:adobe-blending-mode="lighten" | |
d="M263.623,229.595c0.037-0.364,0.057-0.734,0.057-1.107 v-13.375c0-5.965-4.836-10.799-10.801-10.799h-55.374c-5.964,0-10.799,4.834-10.799,10.799v7.324 c7.545-1.012,15.699-1.566,24.213-1.566C231.959,220.87,250.812,224.252,263.623,229.595z" | |
id="path96" /><linearGradient | |
id="SVGID_6_" | |
gradientUnits="userSpaceOnUse" | |
x1="225.1929" | |
y1="204.3135" | |
x2="225.1929" | |
y2="246.626"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF;stop-opacity:0" | |
id="stop99" /><stop | |
offset="0.0141" | |
style="stop-color:#FDFDFC;stop-opacity:2.231669e-04" | |
id="stop101" /><stop | |
offset="0.1344" | |
style="stop-color:#BEBEAF;stop-opacity:0.0148" | |
id="stop103" /><stop | |
offset="0.2565" | |
style="stop-color:#94957C;stop-opacity:0.0297" | |
id="stop105" /><stop | |
offset="0.3796" | |
style="stop-color:#747759;stop-opacity:0.0446" | |
id="stop107" /><stop | |
offset="0.5029" | |
style="stop-color:#5D633F;stop-opacity:0.0596" | |
id="stop109" /><stop | |
offset="0.6263" | |
style="stop-color:#4D552E;stop-opacity:0.0746" | |
id="stop111" /><stop | |
offset="0.75" | |
style="stop-color:#414B23;stop-opacity:0.0896" | |
id="stop113" /><stop | |
offset="0.8742" | |
style="stop-color:#3B461E;stop-opacity:0.1047" | |
id="stop115" /><stop | |
offset="1" | |
style="stop-color:#38441C;stop-opacity:0.12" | |
id="stop117" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF;stop-opacity:0" /><a:midPointStop | |
offset="0.2901" | |
style="stop-color:#FFFFFF;stop-opacity:0" /><a:midPointStop | |
offset="1" | |
style="stop-color:#38441C;stop-opacity:0.12" /></linearGradient><path | |
fill="url(#SVGID_6_)" | |
a:adobe-blending-mode="darken" | |
d="M263.68,221.954v13.871c0,5.965-4.836,10.801-10.801,10.801 h-55.374c-5.964,0-10.799-4.836-10.799-10.801v-13.871l0.038-7.704c0,0,0.923-9.937,11.173-9.937h54.962 c0,0,10.063,0.328,10.801,10.799V221.954z" | |
id="path119" /></g><g | |
id="g121"><g | |
id="g123"><image | |
overflow="visible" | |
opacity="0.25" | |
a:adobe-blending-mode="multiply" | |
a:adobe-opacity-share="1" | |
width="30" | |
height="30" | |
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAuJJREFUeNrsl9trE0EUxjO7m5vW tKFN1RqLCmqlIvjgkz5I/cOFIqLggw9KsRHxUo1IdEtactG9+A1+A8dxNrsxK/rgwI9lt5ueb875 ZuZspfJ//Bhqjvc0AfCIHClIQEzSMkUoBqyCJbAKWrxXQoBmBL6AQzChmGQREWbmNQY/DS6Aa6AL mtZvdcDPoEcOQEgxUV5mVMYzH5wCZ8FFcJ0CLoN1UHeIGII34AV4BvbBW4qbzsqKctzruq+ALXAL 3ABXwAafNyjS9sQ3cAwG4BXYA0/AU/AejLOE+I4MtME22AH3wE2wyedNivSFQT3eB/y79kwHnGE2 v4IjinCaNrBEtJiBu2SLs686VkRWGRt8/wTL5jFwxIxMbSGB+Ac1qtcluEMBbWslFDV7QBFdlmBE bwxZtthVDn1dpgF3WIIOhakF9iCf2ajQK32W5hcRJgvnmYHb9ECzQAnyhif8o7PxkWImsiQeRSyJ fWCjJAGy5G2usKtgzc6wx5dWxT6wYhm2jKNBm/UcV90m/aLsdLVoonX+QJV8RvmcXNflNVOOKktQ Fz4p+6AMrBg/GUeeFWUHd51HyuXevz7+GRELNSRzjMwYnmhI5Laa/gEBYxEjskVE7Ih67AeOi3ZE BYc55j+xxzjgpBMpImZL1mNDMuDxm5aYBT2x1+wx+vZJ6lt94kl2Ux1uWl4JWZhy9g/AQ/DOPjt8 q0ULuLebhiRYYO8wPUTIdm+X1zDrKE/FKjH95TL3eP83MiIF7FHAY2ZkYpfadxhoRE80WJ66EKIK BE9YAiPgPkW8dPUSFUfDGnMpHVmKvQJCEoofcsamBLs0fOgSUMnomo2QQ66UAbMTi4+hmOk2mGZW B39OE+rgj5iBcNb3h5qxk9boDb1SLrEh2c75+NlnCfT1A4OP8nZiVeAT0IhZY0Ni+gHP8oEpQ59Z HHP2uRtfkeUnxTj7AWHqMU0ZiRVX2ld5kZ4jnSewHN8FGACSOOKkAlOGAAAAAABJRU5ErkJggg==" | |
transform="matrix(0.24 0 0 0.24 199.0298 216.5547)" | |
id="image125"></image><g | |
id="g127"><radialGradient | |
id="SVGID_7_" | |
cx="202.6289" | |
cy="219.7041" | |
r="2.9995" | |
gradientTransform="matrix(1 0 0 0.75 0 54.926)" | |
gradientUnits="userSpaceOnUse"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" | |
id="stop130" /><stop | |
offset="0.4235" | |
style="stop-color:#FAFCF6" | |
id="stop132" /><stop | |
offset="1" | |
style="stop-color:#F2F7E8" | |
id="stop134" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="0.6235" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="1" | |
style="stop-color:#F2F7E8" /></radialGradient><circle | |
fill="url(#SVGID_7_)" | |
cx="202.629" | |
cy="219.704" | |
r="2.999" | |
id="circle136" /></g></g><g | |
id="g138"><image | |
overflow="visible" | |
opacity="0.25" | |
a:adobe-blending-mode="multiply" | |
a:adobe-opacity-share="1" | |
width="30" | |
height="30" | |
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAhCAYAAAC1ONkWAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtFJREFUeNrsmP1LFEEYx292Ts3V 9ujFrCiwFyPShH4I+imoiPqbhYKIoKigN0W8SulNIrOU63S921u/A9+BYdm9mbndg4IGPiynuzOf eea52WeuVvvf/Joo8VwA6rxm+0lBD3R5TYctpu6XYBRE4DiYzMhpqRbYBDtgHyQ+gsIzQmMUOg3O gzkwzciZTUXqO1gCH8E3CsauERSOUiOgAc6AC2ABXAYXwZECsV/gPVgBb8AH8AVsg45NTjhKTYGr 4Aa4AmYZqYjLmpdj+4ySilwTLIOn4C34YZOTjlLXwH1wC8xzKSMureQym0g+O85ITxP1uU3hPS6r t5j63zFK3QM3uYwNQ0g45KUSPMSJNLjsLS71blHUZJ9Ox5lDSuo2k32SHYsBvslKcAIc5jJvUK7r I1ZntK6Du8yryBJhW9P73hi3jg2ym7ek0hKtO0z4E5xx2RYYOany7DPYyotaUPCwyoVL3KemKpLS TX+h5jhGI88jT0x9/U9yrzoHwoL7ykQtZN8LHGvURUxy05xhntWH8I7WOTzDsaSLmOAMQl6DIYgF mTGEi5iWEyWqD9dtpHCMoPaXtn9KrHSR59CsYxSJ6SKv1e9FW6L1MmM4iXWMIu8ri7u04mjF7HuJ Y3VcxLqciaqfVlnYJRWKJexzlWNs5r2SZMGMNOp1cRYc5atEVBCtPVazD8AzHzHdQUKZUyzywoIT kY9Uh9XrC4o1WTimPmI9ouv9iAXfIHKm1GtKvSyKlq2C1Una5sMTLBRHPN4MOvIxpV6BRfCEJU/s W8Ganf4xzoaCf5dGaS36JHnMKnWNUg/BY35uD1rza7ku5bY4658cMDHkEt6nUZP4TQG1dI/Ic/CJ /SVVHHglS2J94pnluXLecuB9x3Nlk5+3jUlV9hOBMAQjCpn1lMikgFrCdQrtGEKp62CDlCtaMLQc eNu+QmV/7XGp2cyN2rsdCDAAoyXZx8WJpTUAAAAASUVORK5CYII=" | |
transform="matrix(0.24 0 0 0.24 213.9448 216.5547)" | |
id="image140"></image><g | |
id="g142"><radialGradient | |
id="SVGID_8_" | |
cx="217.5439" | |
cy="219.7041" | |
r="2.9995" | |
gradientTransform="matrix(1 0 0 0.75 0 54.926)" | |
gradientUnits="userSpaceOnUse"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" | |
id="stop145" /><stop | |
offset="0.4235" | |
style="stop-color:#FAFCF6" | |
id="stop147" /><stop | |
offset="1" | |
style="stop-color:#F2F7E8" | |
id="stop149" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="0.6235" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="1" | |
style="stop-color:#F2F7E8" /></radialGradient><circle | |
fill="url(#SVGID_8_)" | |
cx="217.544" | |
cy="219.704" | |
r="2.999" | |
id="circle151" /></g></g><g | |
id="g153"><image | |
overflow="visible" | |
opacity="0.25" | |
a:adobe-blending-mode="multiply" | |
a:adobe-opacity-share="1" | |
width="30" | |
height="30" | |
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAhCAYAAAC1ONkWAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAttJREFUeNrsmO9r00Acxptc1m6d Fn9M125sU4RVpyjiSwXB/9wXulciiE4dhpUMpwzFUa02XdP4HDwHR7hcLk0mCh58WOnI9548973k uTYa/0e54c15nQ8E8TJ1UpKQ2Z8QJgUtgDa4CC6AliZOiYrBCfgGfoLTsgK9OQStgE2wDa6DDv+v hhQwBAdgH0TgS1mBLsIEBV0F18BNcJvC1sCyQdgIHFHYG/AODMAxBSZVhQXgHJ15AO5T2Aa4TMHC 0GMJBXwFhxT2Erygkz/AtGhim1NS1A3wCDwGO+AKBS3QKS+nrlp6eQProKe5G4LvNucCS0+1uXQP wRNwj6JaFkH6SgitNxeJ0BwNueSzMsIC3ulduiX/roJmpp9cWkVQ1CrrqB17ws+TPGdM3y3Rftnk fTpVVlS2ZpN1+qy7znl8V2HSrUvcdbKnutryVRk+63RZd5vzBC7ClFvyMXALbHEDiJreNGpDbbH+ Wp5rJmEd7sQ+n13NCq8uU881WbfPeTquwtq0u1ezW1nXepyn7SJM9dgSCc4oPBTO4Rus9jKJwatZ lGeZy+rYXzH+GWEpXxEq5Kl8VecwBcnURVjMgCcZn5GwsTZH7CJMD3khL5zWLGzKuiHnGZpe5CZh I6bO9wx7v+bN7YYxY70j1o/yEoZpKSdMmntMoMq1tIYlVG7ts/4x50tddmXCEDfgxRETZ1JRWMI6 EesObGFRWCyfaa+oDl8jQd4DscApJUr21S54Dj7wu1JBUW2Ct1rybDDRntditUtPnWor8Aw8Zd2h rXdFQdGYd6WfbPTYnOeeEiSv/cTDyC5FvbL1luspSSXPFUYUmaHu8KS0yfjdMpySYp6QIop6TZdC njEnRTvdpVc8Lt0yBW4wS+04HHj3+Fg4pKARnUxdJnVNBL7hSNal4OxPBFLAZ/CRzumn8NR1wrKR xdfy1KLlwDvmw3RaRlDVX3s8h8dGWiUE/BZgAMf82R9IYLF+AAAAAElFTkSuQmCC" | |
transform="matrix(0.24 0 0 0.24 228.8599 216.5547)" | |
id="image155"></image><g | |
id="g157"><radialGradient | |
id="SVGID_9_" | |
cx="232.459" | |
cy="219.7041" | |
r="2.9995" | |
gradientTransform="matrix(1 0 0 0.75 0 54.926)" | |
gradientUnits="userSpaceOnUse"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" | |
id="stop160" /><stop | |
offset="0.4235" | |
style="stop-color:#FAFCF6" | |
id="stop162" /><stop | |
offset="1" | |
style="stop-color:#F2F7E8" | |
id="stop164" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="0.6235" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="1" | |
style="stop-color:#F2F7E8" /></radialGradient><circle | |
fill="url(#SVGID_9_)" | |
cx="232.459" | |
cy="219.704" | |
r="2.999" | |
id="circle166" /></g></g><g | |
id="g168"><image | |
overflow="visible" | |
opacity="0.25" | |
a:adobe-blending-mode="multiply" | |
a:adobe-opacity-share="1" | |
width="30" | |
height="30" | |
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAt9JREFUeNrsl91rE0EUxTOzm69a 05YmVWsUFdRKRfDBJ32Q+ocLRUTBBx+UYiOitlqRaEos2UT3w3P1jIzrbHZNVuiDAz9CNru5Z+69 M3O2Uvk/fg414zOCDzSxRwJiEJGkTBGKAatgEayCFr8rS4AwAp/BIRhTTDyPCDPzGoOfAhfANdAF zdT/SMBPoEf2wYBiQldmVAEBHjgJzoCL4DoFXAZroO4QMQRvwAvwDOyCtxQ3SWdF5QiQui+DDXAL 3ABXwDqvNygy3RPfwBHog1dgBzwBT8E7ENhCvJwMrIBNsAXugZvgPK83KdKzGlTzu8/fpWc64DSz +RV8oYhfTetPEdFiBu6SDc6+6lgRWZNo8P4Flk0zcMiMSGkSP+MPalQvJbhDASuplVB0RfkU0WUJ RuyNIcsWucoh15bYgFssQYfC1Bz7kcdsVNgrByzNHyJMFs4xA7fZA80CJcgb2uofycYHihlrh4hF ax9YL0mAGT7LKivsKmjLpLXjplVrH1ie0ryzlkWa9SxXnWR5QTv6ocUmWuMDqlLu8Di5ruk1Vzmq LEGdD5QtQln7yI8YespZUXbwzBi6cgzGsRTx14ZkxvFbDJeI9Laa/AMBgRUjTIsI6Yh69ANH0xzR DMMc8x/pMcTwjNIiIlqyHg1Jn8dvUmIWZGKv6THk/Jh4GWqFE3RTHW5auoQsTDj7B+Ah2JOzI8vU RNxQ2pYh8efYO4yHGNDubfNzkHWUJ9YqMf5yiZ7AmyEjtoAdCnjMjIj5TbycBhqxJxosT90SogoE j1kCI+A+Rbw0XmKaxzQlCXjz2GpOXUBITPFDztiUYJsNPzAC8kQklpBDrpQ+sxNZL0MR020wZlaC P2cTSvBHzMAg/f6hCu6qNfaGrJRLNCSbOS8/uyyBfL5n8JFrJy7a7Solpk1DYrynTvWBKcMBsxhw 9nEZL8S2GNtzuJo6YFOG1oor7a28iOdI8gLb47sAAwCDFN6m03jgxgAAAABJRU5ErkJggg==" | |
transform="matrix(0.24 0 0 0.24 243.7749 216.5547)" | |
id="image170"></image><g | |
id="g172"><radialGradient | |
id="SVGID_10_" | |
cx="247.374" | |
cy="219.7041" | |
r="2.9995" | |
gradientTransform="matrix(1 0 0 0.75 0 54.926)" | |
gradientUnits="userSpaceOnUse"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" | |
id="stop175" /><stop | |
offset="0.4235" | |
style="stop-color:#FAFCF6" | |
id="stop177" /><stop | |
offset="1" | |
style="stop-color:#F2F7E8" | |
id="stop179" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="0.6235" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="1" | |
style="stop-color:#F2F7E8" /></radialGradient><circle | |
fill="url(#SVGID_10_)" | |
cx="247.374" | |
cy="219.704" | |
r="2.999" | |
id="circle181" /></g></g><g | |
id="g183"><image | |
overflow="visible" | |
opacity="0.25" | |
a:adobe-blending-mode="multiply" | |
a:adobe-opacity-share="1" | |
width="30" | |
height="30" | |
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAn9JREFUeNrsl+lrE0EYxvdKjSZW YxEPxBsVrNdHQTxA/KMFBRGPDwoVVIpoq3jUeJUG25qk2fVZ+A28WTabxG4lHzrwgxw78z7zzMw7 73reBDR/jOcCUREhn21LRCy6osfn0kT4BN0h9oiDoiGmTN8Efoum+CHWEBRvRoSbeZXgR8QZcVEc F7syfTcI/kq8Fgviu1jlv3hcET627xXHxFlxWZwXJ8RMxgmPIKkTn8UbMSdeinfiq1hnmUYS4QTs F5fENQSc4rfUgahgT7TFivgk5sVj8VQs4kqukGiAgCviDiKOijr/BUOWL7t/9uGaVyTEighYggsI uI79NQYfdY9FPF8x/WL2xiJLk9hOoelcJehtcYslqI8hYNDGrvP9G5t1PbtRQ+NIg/W/KWaxNNpk DnK5JZ35TzbuCq70ibAu3BBXxWHW1i8hGbpc0+akNLNuBDAtTopz4kBJAuxEC8cPzIlI88BpOoQl Xw1TuDtLsqvZkxbwUA2FjZxEVJYbdROj4mWOpVuzCMoWYGPlxggm4SrfFmFFJOTzDUi2KFY8KIYT sUoSWRadLRDSM0XPMgVPn4guOT0tSN6KVtHd/w8tYWJfqDHeM+m+jBkTeIEaoEmKTUp0oXD80Kjt kU4PkVSqJWTOhIDpFf5APBFLOOPliYhxZgYR00MKmVEEuKWeQ8Q8ruRe5Xb3po7s5CqvDSjnxhVw XzzjFu3k5XTbuuziNYLvZolCk+KHBU8n8QcBL8Rd8VB8yCto8kTEDNBCTIdBg4wQvyD4L6rsdOb3 xKNhhW44IKm4wZaghSAnoIdrHWhz/m3wlOfiI86OXPJPzMvPxLwG/tcX4u3m2l8BBgBQ/dU5d1Za tAAAAABJRU5ErkJggg==" | |
transform="matrix(0.24 0 0 0.24 199.0298 230.2217)" | |
id="image185"></image><g | |
id="g187"><radialGradient | |
id="SVGID_11_" | |
cx="202.6289" | |
cy="233.3711" | |
r="2.999" | |
gradientTransform="matrix(1 0 0 0.75 0 58.3428)" | |
gradientUnits="userSpaceOnUse"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" | |
id="stop190" /><stop | |
offset="0.4235" | |
style="stop-color:#FAFCF6" | |
id="stop192" /><stop | |
offset="1" | |
style="stop-color:#F2F7E8" | |
id="stop194" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="0.6235" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="1" | |
style="stop-color:#F2F7E8" /></radialGradient><circle | |
fill="url(#SVGID_11_)" | |
cx="202.629" | |
cy="233.37" | |
r="2.999" | |
id="circle196" /></g></g><g | |
id="g198"><image | |
overflow="visible" | |
opacity="0.25" | |
a:adobe-blending-mode="multiply" | |
a:adobe-opacity-share="1" | |
width="30" | |
height="30" | |
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAhCAYAAAC1ONkWAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmlJREFUeNrsmM9r1EAUx3cz2XW1 il2wLLagIh5aeilUBC967EX/XA/1It5aUaiC2JNY/EWp0lZkG3c3id+Bz0AIaXayibKHDnzIJfPm s29eZl/Sas3paNeYZ0SHaz5OKmIx5pr+azF7fyh6oi+WxXURZGJZiUScim/iWERiUkWwXTFDlxG6 I1bFBnKd3P1jpPbEvviE4JlvBtueUl1xQ9wVa2ITsdtkzOTmxGTsALE34oP4KH6I0TS5tofUJXFT PBCPxToZ67OlZTUWkSmbsffipXglvos/ZXLGI1N2qx6Kp+KRuFcgVYRh/oJYEgNxle08EUNqsbJY SDAnZa8r1FlYoQzc02sFF5n/W/wskzMlAReopydkaoVtDWocL1bqGtv8Bblx0YSgJFt9xNbJXLfG uZctjQEx11gj9M2YDXCFiVviflmAGeQCYtlt/MxTOvbJmEFkFZqSyu9GNr7xEXNP4gbnVK/mFhZl rUdsd0B3fcQCDs3lcw7PJobJrRH4iE37g24qa6VrBK05HRdiTYjVbvI8xtQ1isSyTd4pE5secW6N xEdslGnyDmhd0oazFRF7j7VGPmIxPdQ+HNMWNzUmBfFj3+7C1YDtMG7RT3UaONMS+jErtC1e05tV EksyPdkAyToHbsqW2e51R7ygs42qNooJaU/oPF2TF8wgl2SkdsVz8Y5sJVXFUvryX6TfNXld5HwE U37cWUbqGdfDsto1njVxQjscQ8jc8+SckO25jqipHTK1i+Ro1peR7FM6pKH7StAhC7uam7CQI+J+ J7RNTb0lU7Vf3+b6hXeuPxH8948qF6Pq+CvAAGGezDColMK7AAAAAElFTkSuQmCC" | |
transform="matrix(0.24 0 0 0.24 213.9448 230.2217)" | |
id="image200"></image><g | |
id="g202"><radialGradient | |
id="SVGID_12_" | |
cx="217.5439" | |
cy="233.3711" | |
r="2.999" | |
gradientTransform="matrix(1 0 0 0.75 0 58.3428)" | |
gradientUnits="userSpaceOnUse"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" | |
id="stop205" /><stop | |
offset="0.4235" | |
style="stop-color:#FAFCF6" | |
id="stop207" /><stop | |
offset="1" | |
style="stop-color:#F2F7E8" | |
id="stop209" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="0.6235" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="1" | |
style="stop-color:#F2F7E8" /></radialGradient><circle | |
fill="url(#SVGID_12_)" | |
cx="217.544" | |
cy="233.37" | |
r="2.999" | |
id="circle211" /></g></g><g | |
id="g213"><image | |
overflow="visible" | |
opacity="0.25" | |
a:adobe-blending-mode="multiply" | |
a:adobe-opacity-share="1" | |
width="30" | |
height="30" | |
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAhCAYAAAC1ONkWAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAlRJREFUeNrsmM9LG0EUx5PdjTTW otDYWmoOQm2M/YGXnrxI/3IvnnoRW7TagocotqjQtLYp5pffgc/CECc7u+uGpuDAB2Y32Tff9+bN 7Jstlaa0lXM+E4gIAsd/BqIHpj+cpLBY0Ix4JBbhwYg4I+SvOIdf4jqrwHIOQUvihXgtVsWCQ9gP 8UV8El/Ft6wCyyl+DxH0XLwUb8UbxD0V1RE7ZtCO+I6oj2JPHIlTBPZ94sqe3yIi0hCb4h1Reibm iOK4HDPRuRJnRO+D2BGHRLSXJC7yRGpeNMV7sYXAeQSFCU6FRHIGB56IGveMI/uIGxu5JGFzTN0W wpqIijIsmpDFYZ55hah4xRpxP7MIM4NWWHEbTGGDKY1ybi8VKyVM/l2wYjtM+S1xrvww9x6KulgX K0QqvOOeGafGCnbrjOPScOtmnPA1Hm7Sr+TcjF2Rq2F3nb4zNVzCZsWyWMOr2XFe5WgB9urYX+ba KywkF1bJh8d4WWSrYLdhbdBhmohVrddNtYApLOUZI0jxgp6EMO8YQWlK272wuwobFlHkeVqqMVzC OlaR15mQMO8Yo8L6VpFnypNL0S1YWBe7h4wTVxneiP0RJ+KzaHE9KEjUAHst7J9wnWoqe7z9TVly QL9bwJQOsXOB3X36vbTVhfHqN16Zh49F2xXujK2PnWPsthhnkLYeiz0ziblrVZ55CkV7Ftrk1Q52 z5NmIkowdsUBIrIqz7SltR2la0vUNhxhP3PNP7RCf4CouPIs4jDS9p2U/svj21QfeKf6E8E/+ahy 37K2GwEGAJb/2mQI89WQAAAAAElFTkSuQmCC" | |
transform="matrix(0.24 0 0 0.24 228.8599 230.2217)" | |
id="image215"></image><g | |
id="g217"><radialGradient | |
id="SVGID_13_" | |
cx="232.459" | |
cy="233.3711" | |
r="2.999" | |
gradientTransform="matrix(1 0 0 0.75 0 58.3428)" | |
gradientUnits="userSpaceOnUse"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" | |
id="stop220" /><stop | |
offset="0.4235" | |
style="stop-color:#FAFCF6" | |
id="stop222" /><stop | |
offset="1" | |
style="stop-color:#F2F7E8" | |
id="stop224" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="0.6235" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="1" | |
style="stop-color:#F2F7E8" /></radialGradient><circle | |
fill="url(#SVGID_13_)" | |
cx="232.459" | |
cy="233.37" | |
r="2.999" | |
id="circle226" /></g></g><g | |
id="g228"><image | |
overflow="visible" | |
opacity="0.25" | |
a:adobe-blending-mode="multiply" | |
a:adobe-opacity-share="1" | |
width="30" | |
height="30" | |
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnpJREFUeNrsl2lrE1EUhmdLjSZ2 sYgL4lqsYN0+CuIC4o8WFERcPii0YEsQtYpL3cVgW7PMjO+F55ZhmMlMzATyoRceSDKZc957zplz zzjOBCz3P+/xRE34fE6uWESiJ0I+VybCxekeMSMOizkxlbATwx/xRXwXWwiKRhFhd17H+TFxVlwU J8W+lJ0+zlfFmngjvolNrkXDinAJ+6w4IRbFZXFenBLzqUg4ODGR+CheimXxQrwWn8U2aSolwgo4 KC6Jawg4w28mAsGAmuiI3+KDaInH4qlYJyo7QoISAq6IO4g4Lppc8wrSl66fA0TNSQvJE+GRggsI uE74GxgvW8gB/68l7ouojXVSE/s5N9dxelvcIgXNIQTkFXaT718pViMiyjIa8OiZ/N8US4Q0GLEf 2d5iauYHhWtqpu8PiMINcVUcJbduBY3R9poOT4rpJdteRi1Mi9PinDhUkQC7/Cz7aRH2iTB9YIEb /IqPiSmiu0Sza3gZf2qgcC6jEVUVjWbCR83LOR8CqFpAMu07PrxJOMp3ReSJiOnnfYjH5DdK+sgS sUkT+SW6YxASJoYe46OXFtGjp5uB5JVop8/+EVfMxj4xY7w1m/YywtRmGmqhtlNhNMIs+36O2pB2 fYSmUq+gc8ZsyBzhD8QTsWEikyciomjnETFdMMiUEWBTvYyIFlGJ/ILqNRHZy1HeyBnnhhVwXzzj FO06BSHuUcVbON9Piuy7hlvCudnEXwSsiLvioXhnB5oiEREG2ojpYtRLCXEHOP/JlG12fk88yhp0 /RJNxRrbgDaCrICQqHWhw/OfdG54Lt4T2dIj/8S8/EzMa+DYX4h3l13/BBgABM7SO70ZkkMAAAAA SUVORK5CYII=" | |
transform="matrix(0.24 0 0 0.24 243.7749 230.2217)" | |
id="image230"></image><g | |
id="g232"><radialGradient | |
id="SVGID_14_" | |
cx="247.374" | |
cy="233.3711" | |
r="2.999" | |
gradientTransform="matrix(1 0 0 0.75 0 58.3428)" | |
gradientUnits="userSpaceOnUse"><stop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" | |
id="stop235" /><stop | |
offset="0.4235" | |
style="stop-color:#FAFCF6" | |
id="stop237" /><stop | |
offset="1" | |
style="stop-color:#F2F7E8" | |
id="stop239" /><a:midPointStop | |
offset="0.0123" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="0.6235" | |
style="stop-color:#FFFFFF" /><a:midPointStop | |
offset="1" | |
style="stop-color:#F2F7E8" /></radialGradient><circle | |
fill="url(#SVGID_14_)" | |
cx="247.374" | |
cy="233.37" | |
r="2.999" | |
id="circle241" /></g></g></g></g><path | |
d="m 529.664,248.155 h 18.498 l -2.809,18.064 h 5.59 37.586 l 2.6,-17.718 c 4.98,-1.091 9.133,-3.455 12.512,-6.693 3.084,4.075 8.566,7.37 18.252,7.37 6.338,0 12.775,-1.807 17.174,-3.687 4.254,2.399 9.463,3.687 15.459,3.687 3.088,0 6.236,-0.355 9.426,-1.023 h 67.135 l 3.354,-24.827 -5.445,-0.764 1.879,-13.356 c 0.371,-2.386 0.449,-4.66 0.449,-6.156 l -0.008,-0.375 c -0.457,-12.191 -8.139,-19.765 -20.045,-19.765 -2.404,0 -4.623,0.314 -6.676,0.852 h -34.189 l -0.035,0.244 c -2.527,-0.701 -5.41,-1.096 -8.686,-1.096 -3.801,0 -7.406,0.555 -10.76,1.598 l 0.105,-0.746 h -12.467 l 1.826,-12.951 H 613.08 l -1.846,7.658 c -1.373,5.704 -2.213,5.793 -4.453,6.03 l -4.508,0.477 c -3.049,-1.424 -6.357,-2.065 -9.602,-2.065 -2.135,0 -4.275,0.284 -6.416,0.852 h -19.291 c 0.502,-1.772 0.775,-3.674 0.775,-5.678 0,-9.601 -6.846,-16.305 -16.646,-16.305 -11.055,0 -18.775,7.721 -18.775,18.776 0,0.951 0.082,1.869 0.219,2.764 -2.135,-0.288 -4.277,-0.409 -5.553,-0.409 -2.053,0 -4.072,0.288 -6.045,0.852 h -31.342 c -2.74,-0.553 -5.641,-0.852 -8.537,-0.852 -7.138,0 -13.492,1.674 -18.808,4.723 l -3.451,-1.461 c -3.711,-1.571 -11.232,-3.262 -18.979,-3.262 -8.933,0 -16.383,2.56 -21.576,7.016 -3.265,-4.473 -8.523,-7.016 -15.228,-7.016 -4.822,0 -9.021,1.477 -12.572,3.44 -2.996,-2.204 -6.796,-3.44 -11.115,-3.44 -2.327,0 -4.48,0.315 -6.476,0.852 h -33.963 l -0.035,0.245 c -2.526,-0.702 -5.41,-1.097 -8.687,-1.097 -20.458,0 -35.307,16.031 -35.307,38.117 0,17.363 10.785,28.149 28.148,28.149 3.087,0 6.236,-0.356 9.426,-1.023 h 88.816 c 3.706,0.676 7.669,1.023 11.154,1.023 8.907,0 16.278,-2.375 21.51,-6.593 4.872,4.252 11.585,6.593 19.728,6.593 3.053,0 6.206,-0.368 9.286,-1.023 h 44.664 2.069 z" | |
id="path243" | |
inkscape:connector-curvature="0" | |
style="fill:#f5f5f5" /><g | |
id="g245" | |
transform="translate(0,16)"><g | |
id="g247"><path | |
d="m 340.308,218.463 c -5.538,2.556 -11.588,4.26 -17.638,4.26 -13.377,0 -18.148,-7.839 -18.148,-18.148 0,-17.893 11.418,-28.117 25.307,-28.117 9.372,0 13.973,4.26 13.973,11.247 0,12.184 -12.865,15.763 -26.157,17.126 0.255,4.346 2.045,8.35 8.435,8.35 3.068,0 7.243,-0.937 12.355,-3.067 l 1.873,8.349 z m -8.095,-29.567 c 0,-2.045 -1.448,-3.237 -4.09,-3.237 -4.771,0 -8.69,4.175 -9.969,10.906 3.664,-0.511 14.059,-2.3 14.059,-7.669 z" | |
id="path249" | |
inkscape:connector-curvature="0" | |
style="fill:#383838" /><path | |
d="m 394.07,221.7 -0.171,-0.255 1.789,-10.055 2.642,-18.063 c 0.512,-3.749 0.341,-5.623 -1.96,-5.623 -2.642,0 -5.794,2.727 -9.372,5.879 l -2.727,19.512 c -0.171,1.363 -0.171,1.534 1.022,1.704 l 4.26,0.597 -0.852,6.305 h -18.404 l -0.171,-0.341 1.875,-10.82 2.471,-17.212 c 0.512,-3.237 0.682,-5.453 -1.789,-5.453 -3.238,0 -7.413,3.664 -9.714,5.709 l -2.642,19.512 c -0.17,1.363 -0.17,1.534 1.108,1.704 l 4.26,0.597 -0.852,6.305 h -23.347 l 0.853,-6.39 3.749,-0.512 c 1.107,-0.17 1.363,-0.426 1.533,-1.704 l 3.579,-25.987 c 0.17,-0.938 0,-1.534 -0.767,-1.789 l -4.176,-1.534 0.938,-6.476 h 16.871 l -0.938,6.987 0.256,0.085 c 4.43,-3.749 9.116,-7.924 15.592,-7.924 4.687,0 7.839,2.641 8.18,7.753 l 0.256,0.086 c 4.175,-3.664 9.202,-7.839 15.252,-7.839 6.22,0 8.775,3.152 8.946,9.202 0,1.618 -0.171,3.493 -0.426,5.538 l -3.067,21.897 c -0.171,1.363 -0.171,1.534 1.107,1.704 l 4.175,0.597 -0.852,6.305 H 394.07 z" | |
id="path251" | |
inkscape:connector-curvature="0" | |
style="fill:#383838" /><path | |
d="m 443.995,190.771 -0.17,-4.431 c 0,-0.682 -0.085,-1.108 -1.022,-1.363 -1.022,-0.256 -2.642,-0.427 -4.771,-0.427 -3.579,0 -6.391,1.108 -6.391,4.09 0,2.727 2.982,3.749 6.731,5.027 6.05,2.045 13.888,4.431 13.888,13.463 0,11.076 -9.372,15.592 -20.193,15.592 -8.009,0 -14.91,-1.959 -16.273,-2.981 l 1.618,-12.355 8.691,0.512 0.255,4.941 c 0,0.597 0.171,1.108 0.938,1.363 1.278,0.427 3.238,0.768 6.05,0.768 4.687,0 7.327,-1.79 7.327,-4.687 0,-3.408 -3.152,-4.175 -8.009,-5.624 -6.135,-1.874 -12.78,-4.26 -12.78,-13.206 0,-10.48 9.116,-14.996 19.597,-14.996 6.646,0 12.866,1.533 15.081,2.471 l -1.704,12.354 -8.863,-0.511 z" | |
id="path253" | |
inkscape:connector-curvature="0" | |
style="fill:#383838" /><path | |
d="m 489.748,218.548 c -4.175,2.386 -10.395,4.175 -16.444,4.175 -13.036,0 -18.575,-7.583 -18.575,-18.574 0,-18.83 11.588,-27.691 25.988,-27.691 6.475,0 11.843,1.874 14.229,3.578 l -1.874,13.377 -8.691,-0.426 -0.255,-5.794 c 0,-0.597 -0.086,-0.938 -0.597,-1.192 -1.022,-0.427 -2.557,-0.597 -4.175,-0.597 -5.624,0 -11.418,4.601 -11.418,17.382 0,7.839 3.493,10.395 8.436,10.395 4.346,0 8.436,-1.448 11.247,-2.556 l 2.129,7.923 z" | |
id="path255" | |
inkscape:connector-curvature="0" | |
style="fill:#383838" /><path | |
d="m 491.364,221.7 0.853,-6.39 3.919,-0.512 c 1.193,-0.17 1.363,-0.426 1.534,-1.704 l 3.578,-25.987 c 0.086,-0.938 -0.085,-1.534 -0.852,-1.789 l -4.261,-1.534 0.938,-6.476 h 16.87 l -1.107,7.669 0.256,0.17 c 3.323,-4.771 8.095,-8.69 13.548,-8.69 1.874,0 5.112,0.341 6.561,0.767 l -2.13,15.507 -9.969,-0.341 -0.256,-4.431 c -0.086,-0.767 -0.256,-1.022 -0.938,-1.022 -1.619,0 -4.26,1.96 -6.646,4.431 l -2.981,21.643 c -0.171,1.363 -0.085,1.619 1.192,1.704 l 8.095,0.682 -0.938,6.305 h -27.266 z" | |
id="path257" | |
inkscape:connector-curvature="0" | |
style="fill:#383838" /><path | |
d="m 536.094,221.7 -0.17,-0.426 2.045,-11.503 3.152,-22.749 c 0.17,-0.938 -0.086,-1.534 -0.853,-1.79 l -4.175,-1.448 0.852,-6.476 h 18.149 l -5.027,35.786 c -0.171,1.363 -0.085,1.534 1.192,1.704 l 4.09,0.597 -0.852,6.305 h -18.403 z m 5.879,-57.598 c 0,-5.453 3.238,-8.775 8.776,-8.775 4.175,0 6.646,2.215 6.646,6.305 0,5.368 -3.322,8.861 -8.861,8.861 -4.176,-0.001 -6.561,-2.387 -6.561,-6.391 z" | |
id="path259" | |
inkscape:connector-curvature="0" | |
style="fill:#383838" /><path | |
d="m 556.796,239.764 -0.17,-0.341 2.471,-14.229 5.282,-38.087 c 0.171,-1.022 -0.085,-1.534 -0.767,-1.789 l -4.175,-1.534 0.938,-6.476 h 17.041 l -1.022,6.816 0.255,0.085 c 5.027,-4.686 10.311,-7.753 15.678,-7.753 7.328,0 12.44,4.686 12.44,17.041 0,11.758 -4.601,29.225 -20.449,29.225 -5.538,0 -8.605,-2.13 -11.759,-4.345 l -1.874,12.78 c -0.085,0.938 0.085,1.278 1.192,1.363 l 8.606,0.853 -0.938,6.39 h -22.749 z m 17.041,-30.247 c 2.13,1.789 4.942,3.322 8.095,3.322 6.901,0 9.458,-9.713 9.458,-17.211 0,-5.027 -1.193,-8.351 -4.431,-8.351 -3.408,0 -7.754,3.664 -10.821,6.391 l -2.301,15.849 z" | |
id="path261" | |
inkscape:connector-curvature="0" | |
style="fill:#383838" /><path | |
d="m 635.777,219.4 c -3.749,1.789 -9.458,3.322 -14.229,3.322 -8.521,0 -12.099,-2.981 -12.099,-9.969 0,-1.107 0.085,-2.386 0.256,-3.749 l 3.066,-22.323 c 0.086,-0.512 0.086,-0.853 -0.511,-0.853 h -5.879 l 1.107,-7.839 c 7.242,-0.767 10.906,-4.431 13.122,-13.633 h 7.924 l -1.704,12.1 c -0.085,0.596 -0.085,0.852 0.597,0.852 h 11.758 l -1.193,8.521 h -12.439 l -2.812,20.364 c -0.171,1.107 -0.256,1.96 -0.256,2.727 0,2.982 1.278,4.26 4.942,4.26 2.385,0 4.771,-0.596 6.816,-1.363 l 1.534,7.583 z" | |
id="path263" | |
inkscape:connector-curvature="0" | |
style="fill:#383838" /><path | |
d="m 671.817,218.463 c -5.538,2.556 -11.588,4.26 -17.638,4.26 -13.377,0 -18.148,-7.839 -18.148,-18.148 0,-17.893 11.418,-28.117 25.307,-28.117 9.372,0 13.973,4.26 13.973,11.247 0,12.184 -12.865,15.763 -26.157,17.126 0.255,4.346 2.045,8.35 8.435,8.35 3.068,0 7.243,-0.937 12.355,-3.067 l 1.873,8.349 z m -8.094,-29.567 c 0,-2.045 -1.448,-3.237 -4.09,-3.237 -4.771,0 -8.69,4.175 -9.969,10.906 3.664,-0.511 14.059,-2.3 14.059,-7.669 z" | |
id="path265" | |
inkscape:connector-curvature="0" | |
style="fill:#383838" /><path | |
d="m 703.596,221.7 -0.17,-0.255 1.874,-10.396 2.471,-17.723 c 0.512,-3.578 0.341,-5.879 -2.215,-5.879 -3.664,0 -8.18,3.578 -11.077,6.135 l -2.641,19.512 c -0.171,1.363 -0.171,1.534 1.107,1.704 l 4.26,0.597 -0.852,6.305 h -23.347 l 0.853,-6.39 3.749,-0.512 c 1.107,-0.17 1.363,-0.426 1.533,-1.704 l 3.579,-25.987 c 0.17,-0.938 0,-1.534 -0.768,-1.789 l -4.175,-1.534 0.938,-6.476 h 16.87 l -0.937,6.987 0.255,0.085 c 4.771,-4.09 9.373,-7.924 16.02,-7.924 6.475,0 9.798,3.322 10.054,10.139 0,1.363 -0.085,3.067 -0.341,4.687 l -3.067,21.812 c -0.171,1.363 -0.171,1.534 1.022,1.704 l 4.26,0.597 L 722,221.7 h -18.404 z" | |
id="path267" | |
inkscape:connector-curvature="0" | |
style="fill:#383838" /></g><g | |
id="g269"><linearGradient | |
id="SVGID_15_" | |
gradientUnits="userSpaceOnUse" | |
x1="324.1611" | |
y1="239.7637" | |
x2="324.1611" | |
y2="155.3275"><stop | |
offset="0" | |
style="stop-color:#000000" | |
id="stop272" /><stop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" | |
id="stop274" /><a:midPointStop | |
offset="0" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="0.6933" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" /></linearGradient><path | |
d="m 340.308,218.463 c -5.538,2.556 -11.588,4.26 -17.638,4.26 -13.377,0 -18.148,-7.839 -18.148,-18.148 0,-17.893 11.418,-28.117 25.307,-28.117 9.372,0 13.973,4.26 13.973,11.247 0,12.184 -12.865,15.763 -26.157,17.126 0.255,4.346 2.045,8.35 8.435,8.35 3.068,0 7.243,-0.937 12.355,-3.067 l 1.873,8.349 z m -8.095,-29.567 c 0,-2.045 -1.448,-3.237 -4.09,-3.237 -4.771,0 -8.69,4.175 -9.969,10.906 3.664,-0.511 14.059,-2.3 14.059,-7.669 z" | |
id="path276" | |
style="fill:url(#SVGID_15_)" | |
inkscape:connector-curvature="0" /><linearGradient | |
id="SVGID_16_" | |
gradientUnits="userSpaceOnUse" | |
x1="377.45459" | |
y1="239.7637" | |
x2="377.45459" | |
y2="155.3277"><stop | |
offset="0" | |
style="stop-color:#000000" | |
id="stop279" /><stop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" | |
id="stop281" /><a:midPointStop | |
offset="0" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="0.6933" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" /></linearGradient><path | |
d="m 394.07,221.7 -0.171,-0.255 1.789,-10.055 2.642,-18.063 c 0.512,-3.749 0.341,-5.623 -1.96,-5.623 -2.642,0 -5.794,2.727 -9.372,5.879 l -2.727,19.512 c -0.171,1.363 -0.171,1.534 1.022,1.704 l 4.26,0.597 -0.852,6.305 h -18.404 l -0.171,-0.341 1.875,-10.82 2.471,-17.212 c 0.512,-3.237 0.682,-5.453 -1.789,-5.453 -3.238,0 -7.413,3.664 -9.714,5.709 l -2.642,19.512 c -0.17,1.363 -0.17,1.534 1.108,1.704 l 4.26,0.597 -0.852,6.305 h -23.347 l 0.853,-6.39 3.749,-0.512 c 1.107,-0.17 1.363,-0.426 1.533,-1.704 l 3.579,-25.987 c 0.17,-0.938 0,-1.534 -0.767,-1.789 l -4.176,-1.534 0.938,-6.476 h 16.871 l -0.938,6.987 0.256,0.085 c 4.43,-3.749 9.116,-7.924 15.592,-7.924 4.687,0 7.839,2.641 8.18,7.753 l 0.256,0.086 c 4.175,-3.664 9.202,-7.839 15.252,-7.839 6.22,0 8.775,3.152 8.946,9.202 0,1.618 -0.171,3.493 -0.426,5.538 l -3.067,21.897 c -0.171,1.363 -0.171,1.534 1.107,1.704 l 4.175,0.597 -0.852,6.305 H 394.07 z" | |
id="path283" | |
style="fill:url(#SVGID_16_)" | |
inkscape:connector-curvature="0" /><linearGradient | |
id="SVGID_17_" | |
gradientUnits="userSpaceOnUse" | |
x1="435.17719" | |
y1="239.7637" | |
x2="435.17719" | |
y2="155.3275"><stop | |
offset="0" | |
style="stop-color:#000000" | |
id="stop286" /><stop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" | |
id="stop288" /><a:midPointStop | |
offset="0" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="0.6933" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" /></linearGradient><path | |
d="m 443.995,190.771 -0.17,-4.431 c 0,-0.682 -0.085,-1.108 -1.022,-1.363 -1.022,-0.256 -2.642,-0.427 -4.771,-0.427 -3.579,0 -6.391,1.108 -6.391,4.09 0,2.727 2.982,3.749 6.731,5.027 6.05,2.045 13.888,4.431 13.888,13.463 0,11.076 -9.372,15.592 -20.193,15.592 -8.009,0 -14.91,-1.959 -16.273,-2.981 l 1.618,-12.355 8.691,0.512 0.255,4.941 c 0,0.597 0.171,1.108 0.938,1.363 1.278,0.427 3.238,0.768 6.05,0.768 4.687,0 7.327,-1.79 7.327,-4.687 0,-3.408 -3.152,-4.175 -8.009,-5.624 -6.135,-1.874 -12.78,-4.26 -12.78,-13.206 0,-10.48 9.116,-14.996 19.597,-14.996 6.646,0 12.866,1.533 15.081,2.471 l -1.704,12.354 -8.863,-0.511 z" | |
id="path290" | |
style="fill:url(#SVGID_17_)" | |
inkscape:connector-curvature="0" /><linearGradient | |
id="SVGID_18_" | |
gradientUnits="userSpaceOnUse" | |
x1="474.83691" | |
y1="239.7637" | |
x2="474.83691" | |
y2="155.3275"><stop | |
offset="0" | |
style="stop-color:#000000" | |
id="stop293" /><stop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" | |
id="stop295" /><a:midPointStop | |
offset="0" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="0.6933" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" /></linearGradient><path | |
d="m 489.748,218.548 c -4.175,2.386 -10.395,4.175 -16.444,4.175 -13.036,0 -18.575,-7.583 -18.575,-18.574 0,-18.83 11.588,-27.691 25.988,-27.691 6.475,0 11.843,1.874 14.229,3.578 l -1.874,13.377 -8.691,-0.426 -0.255,-5.794 c 0,-0.597 -0.086,-0.938 -0.597,-1.192 -1.022,-0.427 -2.557,-0.597 -4.175,-0.597 -5.624,0 -11.418,4.601 -11.418,17.382 0,7.839 3.493,10.395 8.436,10.395 4.346,0 8.436,-1.448 11.247,-2.556 l 2.129,7.923 z" | |
id="path297" | |
style="fill:url(#SVGID_18_)" | |
inkscape:connector-curvature="0" /><linearGradient | |
id="SVGID_19_" | |
gradientUnits="userSpaceOnUse" | |
x1="512.28223" | |
y1="239.7637" | |
x2="512.28223" | |
y2="155.3277"><stop | |
offset="0" | |
style="stop-color:#000000" | |
id="stop300" /><stop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" | |
id="stop302" /><a:midPointStop | |
offset="0" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="0.6933" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" /></linearGradient><path | |
d="m 491.364,221.7 0.853,-6.39 3.919,-0.512 c 1.193,-0.17 1.363,-0.426 1.534,-1.704 l 3.578,-25.987 c 0.086,-0.938 -0.085,-1.534 -0.852,-1.789 l -4.261,-1.534 0.938,-6.476 h 16.87 l -1.107,7.669 0.256,0.17 c 3.323,-4.771 8.095,-8.69 13.548,-8.69 1.874,0 5.112,0.341 6.561,0.767 l -2.13,15.507 -9.969,-0.341 -0.256,-4.431 c -0.086,-0.767 -0.256,-1.022 -0.938,-1.022 -1.619,0 -4.26,1.96 -6.646,4.431 l -2.981,21.643 c -0.171,1.363 -0.085,1.619 1.192,1.704 l 8.095,0.682 -0.938,6.305 h -27.266 z" | |
id="path304" | |
style="fill:url(#SVGID_19_)" | |
inkscape:connector-curvature="0" /><linearGradient | |
id="SVGID_20_" | |
gradientUnits="userSpaceOnUse" | |
x1="546.65918" | |
y1="239.7637" | |
x2="546.65918" | |
y2="155.32719"><stop | |
offset="0" | |
style="stop-color:#000000" | |
id="stop307" /><stop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" | |
id="stop309" /><a:midPointStop | |
offset="0" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="0.6933" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" /></linearGradient><path | |
d="m 536.094,221.7 -0.17,-0.426 2.045,-11.503 3.152,-22.749 c 0.17,-0.938 -0.086,-1.534 -0.853,-1.79 l -4.175,-1.448 0.852,-6.476 h 18.149 l -5.027,35.786 c -0.171,1.363 -0.085,1.534 1.192,1.704 l 4.09,0.597 -0.852,6.305 h -18.403 z m 5.879,-57.598 c 0,-5.453 3.238,-8.775 8.776,-8.775 4.175,0 6.646,2.215 6.646,6.305 0,5.368 -3.322,8.861 -8.861,8.861 -4.176,-0.001 -6.561,-2.387 -6.561,-6.391 z" | |
id="path311" | |
style="fill:url(#SVGID_20_)" | |
inkscape:connector-curvature="0" /><linearGradient | |
id="SVGID_21_" | |
gradientUnits="userSpaceOnUse" | |
x1="580.69629" | |
y1="239.7637" | |
x2="580.69629" | |
y2="155.32719"><stop | |
offset="0" | |
style="stop-color:#000000" | |
id="stop314" /><stop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" | |
id="stop316" /><a:midPointStop | |
offset="0" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="0.6933" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" /></linearGradient><path | |
d="m 556.796,239.764 -0.17,-0.341 2.471,-14.229 5.282,-38.087 c 0.171,-1.022 -0.085,-1.534 -0.767,-1.789 l -4.175,-1.534 0.938,-6.476 h 17.041 l -1.022,6.816 0.255,0.085 c 5.027,-4.686 10.311,-7.753 15.678,-7.753 7.328,0 12.44,4.686 12.44,17.041 0,11.758 -4.601,29.225 -20.449,29.225 -5.538,0 -8.605,-2.13 -11.759,-4.345 l -1.874,12.78 c -0.085,0.938 0.085,1.278 1.192,1.363 l 8.606,0.853 -0.938,6.39 h -22.749 z m 17.041,-30.247 c 2.13,1.789 4.942,3.322 8.095,3.322 6.901,0 9.458,-9.713 9.458,-17.211 0,-5.027 -1.193,-8.351 -4.431,-8.351 -3.408,0 -7.754,3.664 -10.821,6.391 l -2.301,15.849 z" | |
id="path318" | |
style="fill:url(#SVGID_21_)" | |
inkscape:connector-curvature="0" /><linearGradient | |
id="SVGID_22_" | |
gradientUnits="userSpaceOnUse" | |
x1="622.7832" | |
y1="239.7637" | |
x2="622.7832" | |
y2="155.3268"><stop | |
offset="0" | |
style="stop-color:#000000" | |
id="stop321" /><stop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" | |
id="stop323" /><a:midPointStop | |
offset="0" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="0.6933" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" /></linearGradient><path | |
d="m 635.777,219.4 c -3.749,1.789 -9.458,3.322 -14.229,3.322 -8.521,0 -12.099,-2.981 -12.099,-9.969 0,-1.107 0.085,-2.386 0.256,-3.749 l 3.066,-22.323 c 0.086,-0.512 0.086,-0.853 -0.511,-0.853 h -5.879 l 1.107,-7.839 c 7.242,-0.767 10.906,-4.431 13.122,-13.633 h 7.924 l -1.704,12.1 c -0.085,0.596 -0.085,0.852 0.597,0.852 h 11.758 l -1.193,8.521 h -12.439 l -2.812,20.364 c -0.171,1.107 -0.256,1.96 -0.256,2.727 0,2.982 1.278,4.26 4.942,4.26 2.385,0 4.771,-0.596 6.816,-1.363 l 1.534,7.583 z" | |
id="path325" | |
style="fill:url(#SVGID_22_)" | |
inkscape:connector-curvature="0" /><linearGradient | |
id="SVGID_23_" | |
gradientUnits="userSpaceOnUse" | |
x1="655.6709" | |
y1="239.7637" | |
x2="655.6709" | |
y2="155.3275"><stop | |
offset="0" | |
style="stop-color:#000000" | |
id="stop328" /><stop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" | |
id="stop330" /><a:midPointStop | |
offset="0" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="0.6933" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" /></linearGradient><path | |
d="m 671.817,218.463 c -5.538,2.556 -11.588,4.26 -17.638,4.26 -13.377,0 -18.148,-7.839 -18.148,-18.148 0,-17.893 11.418,-28.117 25.307,-28.117 9.372,0 13.973,4.26 13.973,11.247 0,12.184 -12.865,15.763 -26.157,17.126 0.255,4.346 2.045,8.35 8.435,8.35 3.068,0 7.243,-0.937 12.355,-3.067 l 1.873,8.349 z m -8.094,-29.567 c 0,-2.045 -1.448,-3.237 -4.09,-3.237 -4.771,0 -8.69,4.175 -9.969,10.906 3.664,-0.511 14.059,-2.3 14.059,-7.669 z" | |
id="path332" | |
style="fill:url(#SVGID_23_)" | |
inkscape:connector-curvature="0" /><linearGradient | |
id="SVGID_24_" | |
gradientUnits="userSpaceOnUse" | |
x1="697.92969" | |
y1="239.7637" | |
x2="697.92969" | |
y2="155.3277"><stop | |
offset="0" | |
style="stop-color:#000000" | |
id="stop335" /><stop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" | |
id="stop337" /><a:midPointStop | |
offset="0" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="0.6933" | |
style="stop-color:#000000" /><a:midPointStop | |
offset="1" | |
style="stop-color:#000000;stop-opacity:0" /></linearGradient><path | |
d="m 703.596,221.7 -0.17,-0.255 1.874,-10.396 2.471,-17.723 c 0.512,-3.578 0.341,-5.879 -2.215,-5.879 -3.664,0 -8.18,3.578 -11.077,6.135 l -2.641,19.512 c -0.171,1.363 -0.171,1.534 1.107,1.704 l 4.26,0.597 -0.852,6.305 h -23.347 l 0.853,-6.39 3.749,-0.512 c 1.107,-0.17 1.363,-0.426 1.533,-1.704 l 3.579,-25.987 c 0.17,-0.938 0,-1.534 -0.768,-1.789 l -4.175,-1.534 0.938,-6.476 h 16.87 l -0.937,6.987 0.255,0.085 c 4.771,-4.09 9.373,-7.924 16.02,-7.924 6.475,0 9.798,3.322 10.054,10.139 0,1.363 -0.085,3.067 -0.341,4.687 l -3.067,21.812 c -0.171,1.363 -0.171,1.534 1.022,1.704 l 4.26,0.597 L 722,221.7 h -18.404 z" | |
id="path339" | |
style="fill:url(#SVGID_24_)" | |
inkscape:connector-curvature="0" /></g></g><g | |
id="g4141" | |
transform="matrix(0.81856441,0,0,0.81856441,79.234731,-94.128741)"><g | |
id="g4143"></g><g | |
id="g4165"><linearGradient | |
y2="155.3275" | |
x2="324.1611" | |
y1="239.7637" | |
x1="324.1611" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient4167"><stop | |
id="stop4169" | |
style="stop-color:#000000" | |
offset="0" /><stop | |
id="stop4171" | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0.6933" /><a:midPointStop | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /></linearGradient><linearGradient | |
y2="155.3277" | |
x2="377.45459" | |
y1="239.7637" | |
x1="377.45459" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient4175"><stop | |
id="stop4177" | |
style="stop-color:#000000" | |
offset="0" /><stop | |
id="stop4179" | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0.6933" /><a:midPointStop | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /></linearGradient><linearGradient | |
y2="155.3275" | |
x2="435.17719" | |
y1="239.7637" | |
x1="435.17719" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient4183"><stop | |
id="stop4185" | |
style="stop-color:#000000" | |
offset="0" /><stop | |
id="stop4187" | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0.6933" /><a:midPointStop | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /></linearGradient><linearGradient | |
y2="155.3275" | |
x2="474.83691" | |
y1="239.7637" | |
x1="474.83691" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient4191"><stop | |
id="stop4193" | |
style="stop-color:#000000" | |
offset="0" /><stop | |
id="stop4195" | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0.6933" /><a:midPointStop | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /></linearGradient><linearGradient | |
y2="155.3277" | |
x2="512.28223" | |
y1="239.7637" | |
x1="512.28223" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient4199"><stop | |
id="stop4201" | |
style="stop-color:#000000" | |
offset="0" /><stop | |
id="stop4203" | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0.6933" /><a:midPointStop | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /></linearGradient><linearGradient | |
y2="155.32719" | |
x2="546.65918" | |
y1="239.7637" | |
x1="546.65918" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient4207"><stop | |
id="stop4209" | |
style="stop-color:#000000" | |
offset="0" /><stop | |
id="stop4211" | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0.6933" /><a:midPointStop | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /></linearGradient><linearGradient | |
y2="155.32719" | |
x2="580.69629" | |
y1="239.7637" | |
x1="580.69629" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient4215"><stop | |
id="stop4217" | |
style="stop-color:#000000" | |
offset="0" /><stop | |
id="stop4219" | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0.6933" /><a:midPointStop | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /></linearGradient><linearGradient | |
y2="155.3268" | |
x2="622.7832" | |
y1="239.7637" | |
x1="622.7832" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient4223"><stop | |
id="stop4225" | |
style="stop-color:#000000" | |
offset="0" /><stop | |
id="stop4227" | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0.6933" /><a:midPointStop | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /></linearGradient><linearGradient | |
y2="155.3275" | |
x2="655.6709" | |
y1="239.7637" | |
x1="655.6709" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient4231"><stop | |
id="stop4233" | |
style="stop-color:#000000" | |
offset="0" /><stop | |
id="stop4235" | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0.6933" /><a:midPointStop | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /></linearGradient><linearGradient | |
y2="155.3277" | |
x2="697.92969" | |
y1="239.7637" | |
x1="697.92969" | |
gradientUnits="userSpaceOnUse" | |
id="linearGradient4239"><stop | |
id="stop4241" | |
style="stop-color:#000000" | |
offset="0" /><stop | |
id="stop4243" | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0" /><a:midPointStop | |
style="stop-color:#000000" | |
offset="0.6933" /><a:midPointStop | |
style="stop-color:#000000;stop-opacity:0" | |
offset="1" /></linearGradient></g></g></svg> | |
</a> | |
<div class="spinner" id='spinner'></div> | |
<div class="emscripten" id="status">Downloading...</div> | |
<span id='controls'> | |
<span><input type="checkbox" id="resize">Resize canvas</span> | |
<span><input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer </span> | |
<span><input type="button" value="Fullscreen" onclick="Module.requestFullScreen(document.getElementById('pointerLock').checked, | |
document.getElementById('resize').checked)"> | |
</span> | |
</span> | |
<div class="emscripten"> | |
<progress value="0" max="100" id="progress" hidden=1></progress> | |
</div> | |
<div class="emscripten_border"> | |
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas> | |
</div> | |
<textarea id="output" rows="8"></textarea> | |
<script type='text/javascript'> | |
var statusElement = document.getElementById('status'); | |
var progressElement = document.getElementById('progress'); | |
var spinnerElement = document.getElementById('spinner'); | |
var Module = { | |
preRun: [], | |
postRun: [], | |
print: (function() { | |
var element = document.getElementById('output'); | |
if (element) element.value = ''; // clear browser cache | |
return function(text) { | |
text = Array.prototype.slice.call(arguments).join(' '); | |
// These replacements are necessary if you render to raw HTML | |
//text = text.replace(/&/g, "&"); | |
//text = text.replace(/</g, "<"); | |
//text = text.replace(/>/g, ">"); | |
//text = text.replace('\n', '<br>', 'g'); | |
console.log(text); | |
if (element) { | |
element.value += text + "\n"; | |
element.scrollTop = element.scrollHeight; // focus on bottom | |
} | |
}; | |
})(), | |
printErr: function(text) { | |
text = Array.prototype.slice.call(arguments).join(' '); | |
if (0) { // XXX disabled for safety typeof dump == 'function') { | |
dump(text + '\n'); // fast, straight to the real console | |
} else { | |
console.error(text); | |
} | |
}, | |
canvas: (function() { | |
var canvas = document.getElementById('canvas'); | |
canvas = WebGL2DScreen(canvas); // !!! the important line !!! | |
// As a default initial behavior, pop up an alert when webgl context is lost. To make your | |
// application robust, you may want to override this behavior before shipping! | |
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2 | |
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false); | |
return canvas; | |
})(), | |
setStatus: function(text) { | |
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' }; | |
if (text === Module.setStatus.text) return; | |
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); | |
var now = Date.now(); | |
if (m && now - Date.now() < 30) return; // if this is a progress update, skip it if too soon | |
if (m) { | |
text = m[1]; | |
progressElement.value = parseInt(m[2])*100; | |
progressElement.max = parseInt(m[4])*100; | |
progressElement.hidden = false; | |
spinnerElement.hidden = false; | |
} else { | |
progressElement.value = null; | |
progressElement.max = null; | |
progressElement.hidden = true; | |
if (!text) spinnerElement.style.display = 'none'; | |
} | |
statusElement.innerHTML = text; | |
}, | |
totalDependencies: 0, | |
monitorRunDependencies: function(left) { | |
this.totalDependencies = Math.max(this.totalDependencies, left); | |
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); | |
} | |
}; | |
Module.setStatus('Downloading...'); | |
window.onerror = function(event) { | |
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus | |
Module.setStatus('Exception thrown, see JavaScript console'); | |
spinnerElement.style.display = 'none'; | |
Module.setStatus = function(text) { | |
if (text) Module.printErr('[post-exception status] ' + text); | |
}; | |
}; | |
</script> | |
<script async type="text/javascript" src="a.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The Module object: Our interface to the outside world. We import | |
// and export values on it, and do the work to get that through | |
// closure compiler if necessary. There are various ways Module can be used: | |
// 1. Not defined. We create it here | |
// 2. A function parameter, function(Module) { ..generated code.. } | |
// 3. pre-run appended it, var Module = {}; ..generated code.. | |
// 4. External script tag defines var Module. | |
// We need to do an eval in order to handle the closure compiler | |
// case, where this code here is minified but Module was defined | |
// elsewhere (e.g. case 4 above). We also need to check if Module | |
// already exists (e.g. case 3 above). | |
// Note that if you want to run closure, and also to use Module | |
// after the generated code, you will need to define var Module = {}; | |
// before the code. Then that object will be used in the code, and you | |
// can continue to use Module afterwards as well. | |
var Module; | |
if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {}; | |
// Sometimes an existing Module object exists with properties | |
// meant to overwrite the default module functionality. Here | |
// we collect those properties and reapply _after_ we configure | |
// the current environment's defaults to avoid having to be so | |
// defensive during initialization. | |
var moduleOverrides = {}; | |
for (var key in Module) { | |
if (Module.hasOwnProperty(key)) { | |
moduleOverrides[key] = Module[key]; | |
} | |
} | |
// The environment setup code below is customized to use Module. | |
// *** Environment setup code *** | |
var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function'; | |
var ENVIRONMENT_IS_WEB = typeof window === 'object'; | |
var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; | |
var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; | |
if (ENVIRONMENT_IS_NODE) { | |
// Expose functionality in the same simple way that the shells work | |
// Note that we pollute the global namespace here, otherwise we break in node | |
if (!Module['print']) Module['print'] = function print(x) { | |
process['stdout'].write(x + '\n'); | |
}; | |
if (!Module['printErr']) Module['printErr'] = function printErr(x) { | |
process['stderr'].write(x + '\n'); | |
}; | |
var nodeFS = require('fs'); | |
var nodePath = require('path'); | |
Module['read'] = function read(filename, binary) { | |
filename = nodePath['normalize'](filename); | |
var ret = nodeFS['readFileSync'](filename); | |
// The path is absolute if the normalized version is the same as the resolved. | |
if (!ret && filename != nodePath['resolve'](filename)) { | |
filename = path.join(__dirname, '..', 'src', filename); | |
ret = nodeFS['readFileSync'](filename); | |
} | |
if (ret && !binary) ret = ret.toString(); | |
return ret; | |
}; | |
Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) }; | |
Module['load'] = function load(f) { | |
globalEval(read(f)); | |
}; | |
if (process['argv'].length > 1) | |
Module['thisProgram'] = process['argv'][1].replace(/\\/g, '/'); | |
Module['arguments'] = process['argv'].slice(2); | |
if (typeof module !== 'undefined') { | |
module['exports'] = Module; | |
} | |
process['on']('uncaughtException', function(ex) { | |
// suppress ExitStatus exceptions from showing an error | |
if (!(ex instanceof ExitStatus)) { | |
throw ex; | |
} | |
}); | |
} | |
else if (ENVIRONMENT_IS_SHELL) { | |
if (!Module['print']) Module['print'] = print; | |
if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm | |
if (typeof read != 'undefined') { | |
Module['read'] = read; | |
} else { | |
Module['read'] = function read() { throw 'no read() available (jsc?)' }; | |
} | |
Module['readBinary'] = function readBinary(f) { | |
if (typeof readbuffer === 'function') { | |
return new Uint8Array(readbuffer(f)); | |
} | |
var data = read(f, 'binary'); | |
assert(typeof data === 'object'); | |
return data; | |
}; | |
if (typeof scriptArgs != 'undefined') { | |
Module['arguments'] = scriptArgs; | |
} else if (typeof arguments != 'undefined') { | |
Module['arguments'] = arguments; | |
} | |
this['Module'] = Module; | |
} | |
else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { | |
Module['read'] = function read(url) { | |
var xhr = new XMLHttpRequest(); | |
xhr.open('GET', url, false); | |
xhr.send(null); | |
return xhr.responseText; | |
}; | |
if (typeof arguments != 'undefined') { | |
Module['arguments'] = arguments; | |
} | |
if (typeof console !== 'undefined') { | |
if (!Module['print']) Module['print'] = function print(x) { | |
console.log(x); | |
}; | |
if (!Module['printErr']) Module['printErr'] = function printErr(x) { | |
console.log(x); | |
}; | |
} else { | |
// Probably a worker, and without console.log. We can do very little here... | |
var TRY_USE_DUMP = false; | |
if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) { | |
dump(x); | |
}) : (function(x) { | |
// self.postMessage(x); // enable this if you want stdout to be sent as messages | |
})); | |
} | |
if (ENVIRONMENT_IS_WEB) { | |
window['Module'] = Module; | |
} else { | |
Module['load'] = importScripts; | |
} | |
} | |
else { | |
// Unreachable because SHELL is dependant on the others | |
throw 'Unknown runtime environment. Where are we?'; | |
} | |
function globalEval(x) { | |
eval.call(null, x); | |
} | |
if (!Module['load'] && Module['read']) { | |
Module['load'] = function load(f) { | |
globalEval(Module['read'](f)); | |
}; | |
} | |
if (!Module['print']) { | |
Module['print'] = function(){}; | |
} | |
if (!Module['printErr']) { | |
Module['printErr'] = Module['print']; | |
} | |
if (!Module['arguments']) { | |
Module['arguments'] = []; | |
} | |
if (!Module['thisProgram']) { | |
Module['thisProgram'] = './this.program'; | |
} | |
// *** Environment setup code *** | |
// Closure helpers | |
Module.print = Module['print']; | |
Module.printErr = Module['printErr']; | |
// Callbacks | |
Module['preRun'] = []; | |
Module['postRun'] = []; | |
// Merge back in the overrides | |
for (var key in moduleOverrides) { | |
if (moduleOverrides.hasOwnProperty(key)) { | |
Module[key] = moduleOverrides[key]; | |
} | |
} | |
// === Preamble library stuff === | |
// Documentation for the public APIs defined in this file must be updated in: | |
// site/source/docs/api_reference/preamble.js.rst | |
// A prebuilt local version of the documentation is available at: | |
// site/build/text/docs/api_reference/preamble.js.txt | |
// You can also build docs locally as HTML or other formats in site/ | |
// An online HTML version (which may be of a different version of Emscripten) | |
// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html | |
//======================================== | |
// Runtime code shared with compiler | |
//======================================== | |
var Runtime = { | |
setTempRet0: function (value) { | |
tempRet0 = value; | |
}, | |
getTempRet0: function () { | |
return tempRet0; | |
}, | |
stackSave: function () { | |
return STACKTOP; | |
}, | |
stackRestore: function (stackTop) { | |
STACKTOP = stackTop; | |
}, | |
getNativeTypeSize: function (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 Runtime.QUANTUM_SIZE; // A pointer | |
} else if (type[0] === 'i') { | |
var bits = parseInt(type.substr(1)); | |
assert(bits % 8 === 0); | |
return bits/8; | |
} else { | |
return 0; | |
} | |
} | |
} | |
}, | |
getNativeFieldSize: function (type) { | |
return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE); | |
}, | |
STACK_ALIGN: 16, | |
getAlignSize: function (type, size, vararg) { | |
// we align i64s and doubles on 64-bit boundaries, unlike x86 | |
if (!vararg && (type == 'i64' || type == 'double')) return 8; | |
if (!type) return Math.min(size, 8); // align structures internally to 64 bits | |
return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE); | |
}, | |
dynCall: function (sig, ptr, args) { | |
if (args && args.length) { | |
assert(args.length == sig.length-1); | |
if (!args.splice) args = Array.prototype.slice.call(args); | |
args.splice(0, 0, ptr); | |
assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\''); | |
return Module['dynCall_' + sig].apply(null, args); | |
} else { | |
assert(sig.length == 1); | |
assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\''); | |
return Module['dynCall_' + sig].call(null, ptr); | |
} | |
}, | |
functionPointers: [], | |
addFunction: function (func) { | |
for (var i = 0; i < Runtime.functionPointers.length; i++) { | |
if (!Runtime.functionPointers[i]) { | |
Runtime.functionPointers[i] = func; | |
return 2*(1 + i); | |
} | |
} | |
throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.'; | |
}, | |
removeFunction: function (index) { | |
Runtime.functionPointers[(index-2)/2] = null; | |
}, | |
getAsmConst: function (code, numArgs) { | |
// code is a constant string on the heap, so we can cache these | |
if (!Runtime.asmConstCache) Runtime.asmConstCache = {}; | |
var func = Runtime.asmConstCache[code]; | |
if (func) return func; | |
var args = []; | |
for (var i = 0; i < numArgs; i++) { | |
args.push(String.fromCharCode(36) + i); // $0, $1 etc | |
} | |
var source = Pointer_stringify(code); | |
if (source[0] === '"') { | |
// tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct | |
if (source.indexOf('"', 1) === source.length-1) { | |
source = source.substr(1, source.length-2); | |
} else { | |
// something invalid happened, e.g. EM_ASM("..code($0)..", input) | |
abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)'); | |
} | |
} | |
try { | |
// Module is the only 'upvar', which we provide directly. We also provide FS for legacy support. | |
var evalled = eval('(function(Module, FS) { return function(' + args.join(',') + '){ ' + source + ' } })')(Module, typeof FS !== 'undefined' ? FS : null); | |
} catch(e) { | |
Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)'); | |
throw e; | |
} | |
return Runtime.asmConstCache[code] = evalled; | |
}, | |
warnOnce: function (text) { | |
if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {}; | |
if (!Runtime.warnOnce.shown[text]) { | |
Runtime.warnOnce.shown[text] = 1; | |
Module.printErr(text); | |
} | |
}, | |
funcWrappers: {}, | |
getFuncWrapper: function (func, sig) { | |
assert(sig); | |
if (!Runtime.funcWrappers[sig]) { | |
Runtime.funcWrappers[sig] = {}; | |
} | |
var sigCache = Runtime.funcWrappers[sig]; | |
if (!sigCache[func]) { | |
sigCache[func] = function dynCall_wrapper() { | |
return Runtime.dynCall(sig, func, arguments); | |
}; | |
} | |
return sigCache[func]; | |
}, | |
UTF8Processor: function () { | |
var buffer = []; | |
var needed = 0; | |
this.processCChar = function (code) { | |
code = code & 0xFF; | |
if (buffer.length == 0) { | |
if ((code & 0x80) == 0x00) { // 0xxxxxxx | |
return String.fromCharCode(code); | |
} | |
buffer.push(code); | |
if ((code & 0xE0) == 0xC0) { // 110xxxxx | |
needed = 1; | |
} else if ((code & 0xF0) == 0xE0) { // 1110xxxx | |
needed = 2; | |
} else { // 11110xxx | |
needed = 3; | |
} | |
return ''; | |
} | |
if (needed) { | |
buffer.push(code); | |
needed--; | |
if (needed > 0) return ''; | |
} | |
var c1 = buffer[0]; | |
var c2 = buffer[1]; | |
var c3 = buffer[2]; | |
var c4 = buffer[3]; | |
var ret; | |
if (buffer.length == 2) { | |
ret = String.fromCharCode(((c1 & 0x1F) << 6) | (c2 & 0x3F)); | |
} else if (buffer.length == 3) { | |
ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)); | |
} else { | |
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae | |
var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) | | |
((c3 & 0x3F) << 6) | (c4 & 0x3F); | |
ret = String.fromCharCode( | |
(((codePoint - 0x10000) / 0x400)|0) + 0xD800, | |
(codePoint - 0x10000) % 0x400 + 0xDC00); | |
} | |
buffer.length = 0; | |
return ret; | |
} | |
this.processJSString = function processJSString(string) { | |
/* TODO: use TextEncoder when present, | |
var encoder = new TextEncoder(); | |
encoder['encoding'] = "utf-8"; | |
var utf8Array = encoder['encode'](aMsg.data); | |
*/ | |
string = unescape(encodeURIComponent(string)); | |
var ret = []; | |
for (var i = 0; i < string.length; i++) { | |
ret.push(string.charCodeAt(i)); | |
} | |
return ret; | |
} | |
}, | |
getCompilerSetting: function (name) { | |
throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work'; | |
}, | |
stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+15)&-16);(assert((((STACKTOP|0) < (STACK_MAX|0))|0))|0); return ret; }, | |
staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + (assert(!staticSealed),size))|0;STATICTOP = (((STATICTOP)+15)&-16); return ret; }, | |
dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + (assert(DYNAMICTOP > 0),size))|0;DYNAMICTOP = (((DYNAMICTOP)+15)&-16); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; }, | |
alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 16))*(quantum ? quantum : 16); return ret; }, | |
makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0))); return ret; }, | |
GLOBAL_BASE: 8, | |
QUANTUM_SIZE: 4, | |
__dummy__: 0 | |
} | |
Module['Runtime'] = Runtime; | |
//======================================== | |
// Runtime essentials | |
//======================================== | |
var __THREW__ = 0; // Used in checking for thrown exceptions. | |
var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort() | |
var EXITSTATUS = 0; | |
var undef = 0; | |
// tempInt is used for 32-bit signed values or smaller. tempBigInt is used | |
// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt | |
var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat; | |
var tempI64, tempI64b; | |
var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9; | |
function assert(condition, text) { | |
if (!condition) { | |
abort('Assertion failed: ' + text); | |
} | |
} | |
var globalScope = this; | |
// Returns the C function with a specified identifier (for C++, you need to do manual name mangling) | |
function getCFunc(ident) { | |
var func = Module['_' + ident]; // closure exported function | |
if (!func) { | |
try { | |
func = eval('_' + ident); // explicit lookup | |
} catch(e) {} | |
} | |
assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)'); | |
return func; | |
} | |
var cwrap, ccall; | |
(function(){ | |
var stack = 0; | |
var JSfuncs = { | |
'stackSave' : function() { | |
stack = Runtime.stackSave(); | |
}, | |
'stackRestore' : function() { | |
Runtime.stackRestore(stack); | |
}, | |
// type conversion from js to c | |
'arrayToC' : function(arr) { | |
var ret = Runtime.stackAlloc(arr.length); | |
writeArrayToMemory(arr, ret); | |
return ret; | |
}, | |
'stringToC' : function(str) { | |
var ret = 0; | |
if (str !== null && str !== undefined && str !== 0) { // null string | |
// at most 4 bytes per UTF-8 code point, +1 for the trailing '\0' | |
ret = Runtime.stackAlloc((str.length << 2) + 1); | |
writeStringToMemory(str, ret); | |
} | |
return ret; | |
} | |
}; | |
// For fast lookup of conversion functions | |
var toC = {'string' : JSfuncs['stringToC'], 'array' : JSfuncs['arrayToC']}; | |
// C calling interface. | |
ccall = function ccallFunc(ident, returnType, argTypes, args) { | |
var func = getCFunc(ident); | |
var cArgs = []; | |
assert(returnType !== 'array', 'Return type should not be "array".'); | |
if (args) { | |
for (var i = 0; i < args.length; i++) { | |
var converter = toC[argTypes[i]]; | |
if (converter) { | |
if (stack === 0) stack = Runtime.stackSave(); | |
cArgs[i] = converter(args[i]); | |
} else { | |
cArgs[i] = args[i]; | |
} | |
} | |
} | |
var ret = func.apply(null, cArgs); | |
if (returnType === 'string') ret = Pointer_stringify(ret); | |
if (stack !== 0) JSfuncs['stackRestore'](); | |
return ret; | |
} | |
var sourceRegex = /^function\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/; | |
function parseJSFunc(jsfunc) { | |
// Match the body and the return value of a javascript function source | |
var parsed = jsfunc.toString().match(sourceRegex).slice(1); | |
return {arguments : parsed[0], body : parsed[1], returnValue: parsed[2]} | |
} | |
var JSsource = {}; | |
for (var fun in JSfuncs) { | |
if (JSfuncs.hasOwnProperty(fun)) { | |
// Elements of toCsource are arrays of three items: | |
// the code, and the return value | |
JSsource[fun] = parseJSFunc(JSfuncs[fun]); | |
} | |
} | |
cwrap = function cwrap(ident, returnType, argTypes) { | |
argTypes = argTypes || []; | |
var cfunc = getCFunc(ident); | |
// When the function takes numbers and returns a number, we can just return | |
// the original function | |
var numericArgs = argTypes.every(function(type){ return type === 'number'}); | |
var numericRet = (returnType !== 'string'); | |
if ( numericRet && numericArgs) { | |
return cfunc; | |
} | |
// Creation of the arguments list (["$1","$2",...,"$nargs"]) | |
var argNames = argTypes.map(function(x,i){return '$'+i}); | |
var funcstr = "(function(" + argNames.join(',') + ") {"; | |
var nargs = argTypes.length; | |
if (!numericArgs) { | |
// Generate the code needed to convert the arguments from javascript | |
// values to pointers | |
funcstr += JSsource['stackSave'].body + ';'; | |
for (var i = 0; i < nargs; i++) { | |
var arg = argNames[i], type = argTypes[i]; | |
if (type === 'number') continue; | |
var convertCode = JSsource[type + 'ToC']; // [code, return] | |
funcstr += 'var ' + convertCode.arguments + ' = ' + arg + ';'; | |
funcstr += convertCode.body + ';'; | |
funcstr += arg + '=' + convertCode.returnValue + ';'; | |
} | |
} | |
// When the code is compressed, the name of cfunc is not literally 'cfunc' anymore | |
var cfuncname = parseJSFunc(function(){return cfunc}).returnValue; | |
// Call the function | |
funcstr += 'var ret = ' + cfuncname + '(' + argNames.join(',') + ');'; | |
if (!numericRet) { // Return type can only by 'string' or 'number' | |
// Convert the result to a string | |
var strgfy = parseJSFunc(function(){return Pointer_stringify}).returnValue; | |
funcstr += 'ret = ' + strgfy + '(ret);'; | |
} | |
if (!numericArgs) { | |
// If we had a stack, restore it | |
funcstr += JSsource['stackRestore'].body + ';'; | |
} | |
funcstr += 'return ret})'; | |
return eval(funcstr); | |
}; | |
})(); | |
Module["cwrap"] = cwrap; | |
Module["ccall"] = ccall; | |
function setValue(ptr, value, type, noSafe) { | |
type = type || 'i8'; | |
if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit | |
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.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>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); | |
} | |
} | |
Module['setValue'] = setValue; | |
function getValue(ptr, type, noSafe) { | |
type = type || 'i8'; | |
if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit | |
switch(type) { | |
case 'i1': return HEAP8[((ptr)>>0)]; | |
case 'i8': return HEAP8[((ptr)>>0)]; | |
case 'i16': return HEAP16[((ptr)>>1)]; | |
case 'i32': return HEAP32[((ptr)>>2)]; | |
case 'i64': return HEAP32[((ptr)>>2)]; | |
case 'float': return HEAPF32[((ptr)>>2)]; | |
case 'double': return HEAPF64[((ptr)>>3)]; | |
default: abort('invalid type for setValue: ' + type); | |
} | |
return null; | |
} | |
Module['getValue'] = getValue; | |
var ALLOC_NORMAL = 0; // Tries to use _malloc() | |
var ALLOC_STACK = 1; // Lives for the duration of the current function call | |
var ALLOC_STATIC = 2; // Cannot be freed | |
var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk | |
var ALLOC_NONE = 4; // Do not allocate | |
Module['ALLOC_NORMAL'] = ALLOC_NORMAL; | |
Module['ALLOC_STACK'] = ALLOC_STACK; | |
Module['ALLOC_STATIC'] = ALLOC_STATIC; | |
Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC; | |
Module['ALLOC_NONE'] = ALLOC_NONE; | |
// allocate(): This is for internal use. You can use it yourself as well, but the interface | |
// is a little tricky (see docs right below). The reason is that it is optimized | |
// for multiple syntaxes to save space in generated code. So you should | |
// normally not use allocate(), and instead allocate memory using _malloc(), | |
// initialize it with setValue(), and so forth. | |
// @slab: An array of data, or a number. If a number, then the size of the block to allocate, | |
// in *bytes* (note that this is sometimes confusing: the next parameter does not | |
// affect this!) | |
// @types: Either an array of types, one for each byte (or 0 if no type at that position), | |
// or a single type which is used for the entire block. This only matters if there | |
// is initial data - if @slab is a number, then this does not matter at all and is | |
// ignored. | |
// @allocator: How to allocate memory, see ALLOC_* | |
function allocate(slab, types, allocator, ptr) { | |
var zeroinit, size; | |
if (typeof slab === 'number') { | |
zeroinit = true; | |
size = slab; | |
} else { | |
zeroinit = false; | |
size = slab.length; | |
} | |
var singleType = typeof types === 'string' ? types : null; | |
var ret; | |
if (allocator == ALLOC_NONE) { | |
ret = ptr; | |
} else { | |
ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length)); | |
} | |
if (zeroinit) { | |
var ptr = ret, stop; | |
assert((ret & 3) == 0); | |
stop = ret + (size & ~3); | |
for (; ptr < stop; ptr += 4) { | |
HEAP32[((ptr)>>2)]=0; | |
} | |
stop = ret + size; | |
while (ptr < stop) { | |
HEAP8[((ptr++)>>0)]=0; | |
} | |
return ret; | |
} | |
if (singleType === 'i8') { | |
if (slab.subarray || slab.slice) { | |
HEAPU8.set(slab, ret); | |
} else { | |
HEAPU8.set(new Uint8Array(slab), ret); | |
} | |
return ret; | |
} | |
var i = 0, type, typeSize, previousType; | |
while (i < size) { | |
var curr = slab[i]; | |
if (typeof curr === 'function') { | |
curr = Runtime.getFunctionIndex(curr); | |
} | |
type = singleType || types[i]; | |
if (type === 0) { | |
i++; | |
continue; | |
} | |
assert(type, 'Must know what type to store in allocate!'); | |
if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later | |
setValue(ret+i, curr, type); | |
// no need to look up size unless type changes, so cache it | |
if (previousType !== type) { | |
typeSize = Runtime.getNativeTypeSize(type); | |
previousType = type; | |
} | |
i += typeSize; | |
} | |
return ret; | |
} | |
Module['allocate'] = allocate; | |
function Pointer_stringify(ptr, /* optional */ length) { | |
if (length === 0 || !ptr) return ''; | |
// TODO: use TextDecoder | |
// Find the length, and check for UTF while doing so | |
var hasUtf = false; | |
var t; | |
var i = 0; | |
while (1) { | |
assert(ptr + i < TOTAL_MEMORY); | |
t = HEAPU8[(((ptr)+(i))>>0)]; | |
if (t >= 128) hasUtf = true; | |
else if (t == 0 && !length) break; | |
i++; | |
if (length && i == length) break; | |
} | |
if (!length) length = i; | |
var ret = ''; | |
if (!hasUtf) { | |
var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack | |
var curr; | |
while (length > 0) { | |
curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK))); | |
ret = ret ? ret + curr : curr; | |
ptr += MAX_CHUNK; | |
length -= MAX_CHUNK; | |
} | |
return ret; | |
} | |
var utf8 = new Runtime.UTF8Processor(); | |
for (i = 0; i < length; i++) { | |
assert(ptr + i < TOTAL_MEMORY); | |
t = HEAPU8[(((ptr)+(i))>>0)]; | |
ret += utf8.processCChar(t); | |
} | |
return ret; | |
} | |
Module['Pointer_stringify'] = Pointer_stringify; | |
function UTF16ToString(ptr) { | |
var i = 0; | |
var str = ''; | |
while (1) { | |
var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; | |
if (codeUnit == 0) | |
return str; | |
++i; | |
// fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through. | |
str += String.fromCharCode(codeUnit); | |
} | |
} | |
Module['UTF16ToString'] = UTF16ToString; | |
function stringToUTF16(str, outPtr) { | |
for(var i = 0; i < str.length; ++i) { | |
// charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. | |
var codeUnit = str.charCodeAt(i); // possibly a lead surrogate | |
HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit; | |
} | |
// Null-terminate the pointer to the HEAP. | |
HEAP16[(((outPtr)+(str.length*2))>>1)]=0; | |
} | |
Module['stringToUTF16'] = stringToUTF16; | |
function UTF32ToString(ptr) { | |
var i = 0; | |
var str = ''; | |
while (1) { | |
var utf32 = HEAP32[(((ptr)+(i*4))>>2)]; | |
if (utf32 == 0) | |
return str; | |
++i; | |
// Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing. | |
if (utf32 >= 0x10000) { | |
var ch = utf32 - 0x10000; | |
str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); | |
} else { | |
str += String.fromCharCode(utf32); | |
} | |
} | |
} | |
Module['UTF32ToString'] = UTF32ToString; | |
function stringToUTF32(str, outPtr) { | |
var iChar = 0; | |
for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) { | |
// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap. | |
var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate | |
if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) { | |
var trailSurrogate = str.charCodeAt(++iCodeUnit); | |
codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF); | |
} | |
HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit; | |
++iChar; | |
} | |
// Null-terminate the pointer to the HEAP. | |
HEAP32[(((outPtr)+(iChar*4))>>2)]=0; | |
} | |
Module['stringToUTF32'] = stringToUTF32; | |
function demangle(func) { | |
var hasLibcxxabi = !!Module['___cxa_demangle']; | |
if (hasLibcxxabi) { | |
try { | |
var buf = _malloc(func.length); | |
writeStringToMemory(func.substr(1), buf); | |
var status = _malloc(4); | |
var ret = Module['___cxa_demangle'](buf, 0, 0, status); | |
if (getValue(status, 'i32') === 0 && ret) { | |
return Pointer_stringify(ret); | |
} | |
// otherwise, libcxxabi failed, we can try ours which may return a partial result | |
} catch(e) { | |
// failure when using libcxxabi, we can try ours which may return a partial result | |
} finally { | |
if (buf) _free(buf); | |
if (status) _free(status); | |
if (ret) _free(ret); | |
} | |
} | |
var i = 3; | |
// params, etc. | |
var basicTypes = { | |
'v': 'void', | |
'b': 'bool', | |
'c': 'char', | |
's': 'short', | |
'i': 'int', | |
'l': 'long', | |
'f': 'float', | |
'd': 'double', | |
'w': 'wchar_t', | |
'a': 'signed char', | |
'h': 'unsigned char', | |
't': 'unsigned short', | |
'j': 'unsigned int', | |
'm': 'unsigned long', | |
'x': 'long long', | |
'y': 'unsigned long long', | |
'z': '...' | |
}; | |
var subs = []; | |
var first = true; | |
function dump(x) { | |
//return; | |
if (x) Module.print(x); | |
Module.print(func); | |
var pre = ''; | |
for (var a = 0; a < i; a++) pre += ' '; | |
Module.print (pre + '^'); | |
} | |
function parseNested() { | |
i++; | |
if (func[i] === 'K') i++; // ignore const | |
var parts = []; | |
while (func[i] !== 'E') { | |
if (func[i] === 'S') { // substitution | |
i++; | |
var next = func.indexOf('_', i); | |
var num = func.substring(i, next) || 0; | |
parts.push(subs[num] || '?'); | |
i = next+1; | |
continue; | |
} | |
if (func[i] === 'C') { // constructor | |
parts.push(parts[parts.length-1]); | |
i += 2; | |
continue; | |
} | |
var size = parseInt(func.substr(i)); | |
var pre = size.toString().length; | |
if (!size || !pre) { i--; break; } // counter i++ below us | |
var curr = func.substr(i + pre, size); | |
parts.push(curr); | |
subs.push(curr); | |
i += pre + size; | |
} | |
i++; // skip E | |
return parts; | |
} | |
function parse(rawList, limit, allowVoid) { // main parser | |
limit = limit || Infinity; | |
var ret = '', list = []; | |
function flushList() { | |
return '(' + list.join(', ') + ')'; | |
} | |
var name; | |
if (func[i] === 'N') { | |
// namespaced N-E | |
name = parseNested().join('::'); | |
limit--; | |
if (limit === 0) return rawList ? [name] : name; | |
} else { | |
// not namespaced | |
if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L' | |
var size = parseInt(func.substr(i)); | |
if (size) { | |
var pre = size.toString().length; | |
name = func.substr(i + pre, size); | |
i += pre + size; | |
} | |
} | |
first = false; | |
if (func[i] === 'I') { | |
i++; | |
var iList = parse(true); | |
var iRet = parse(true, 1, true); | |
ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>'; | |
} else { | |
ret = name; | |
} | |
paramLoop: while (i < func.length && limit-- > 0) { | |
//dump('paramLoop'); | |
var c = func[i++]; | |
if (c in basicTypes) { | |
list.push(basicTypes[c]); | |
} else { | |
switch (c) { | |
case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer | |
case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference | |
case 'L': { // literal | |
i++; // skip basic type | |
var end = func.indexOf('E', i); | |
var size = end - i; | |
list.push(func.substr(i, size)); | |
i += size + 2; // size + 'EE' | |
break; | |
} | |
case 'A': { // array | |
var size = parseInt(func.substr(i)); | |
i += size.toString().length; | |
if (func[i] !== '_') throw '?'; | |
i++; // skip _ | |
list.push(parse(true, 1, true)[0] + ' [' + size + ']'); | |
break; | |
} | |
case 'E': break paramLoop; | |
default: ret += '?' + c; break paramLoop; | |
} | |
} | |
} | |
if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void) | |
if (rawList) { | |
if (ret) { | |
list.push(ret + '?'); | |
} | |
return list; | |
} else { | |
return ret + flushList(); | |
} | |
} | |
var final = func; | |
try { | |
// Special-case the entry point, since its name differs from other name mangling. | |
if (func == 'Object._main' || func == '_main') { | |
return 'main()'; | |
} | |
if (typeof func === 'number') func = Pointer_stringify(func); | |
if (func[0] !== '_') return func; | |
if (func[1] !== '_') return func; // C function | |
if (func[2] !== 'Z') return func; | |
switch (func[3]) { | |
case 'n': return 'operator new()'; | |
case 'd': return 'operator delete()'; | |
} | |
final = parse(); | |
} catch(e) { | |
final += '?'; | |
} | |
if (final.indexOf('?') >= 0 && !hasLibcxxabi) { | |
Runtime.warnOnce('warning: a problem occurred in builtin C++ name demangling; build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling'); | |
} | |
return final; | |
} | |
function demangleAll(text) { | |
return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') }); | |
} | |
function jsStackTrace() { | |
var err = new Error(); | |
if (!err.stack) { | |
// IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown, | |
// so try that as a special-case. | |
try { | |
throw new Error(0); | |
} catch(e) { | |
err = e; | |
} | |
if (!err.stack) { | |
return '(no stack trace available)'; | |
} | |
} | |
return err.stack.toString(); | |
} | |
function stackTrace() { | |
return demangleAll(jsStackTrace()); | |
} | |
Module['stackTrace'] = stackTrace; | |
// Memory management | |
var PAGE_SIZE = 4096; | |
function alignMemoryPage(x) { | |
return (x+4095)&-4096; | |
} | |
var HEAP; | |
var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; | |
var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area | |
var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area | |
var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk | |
function enlargeMemory() { | |
abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.'); | |
} | |
var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880; | |
var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 16777216; | |
var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152; | |
var totalMemory = 64*1024; | |
while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) { | |
if (totalMemory < 16*1024*1024) { | |
totalMemory *= 2; | |
} else { | |
totalMemory += 16*1024*1024 | |
} | |
} | |
if (totalMemory !== TOTAL_MEMORY) { | |
Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be compliant with the asm.js spec'); | |
TOTAL_MEMORY = totalMemory; | |
} | |
// Initialize the runtime's memory | |
// check for full engine support (use string 'subarray' to avoid closure compiler confusion) | |
assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']), | |
'JS engine does not provide full typed array support'); | |
var buffer = new ArrayBuffer(TOTAL_MEMORY); | |
HEAP8 = new Int8Array(buffer); | |
HEAP16 = new Int16Array(buffer); | |
HEAP32 = new Int32Array(buffer); | |
HEAPU8 = new Uint8Array(buffer); | |
HEAPU16 = new Uint16Array(buffer); | |
HEAPU32 = new Uint32Array(buffer); | |
HEAPF32 = new Float32Array(buffer); | |
HEAPF64 = new Float64Array(buffer); | |
// Endianness check (note: assumes compiler arch was little-endian) | |
HEAP32[0] = 255; | |
assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system'); | |
Module['HEAP'] = HEAP; | |
Module['buffer'] = buffer; | |
Module['HEAP8'] = HEAP8; | |
Module['HEAP16'] = HEAP16; | |
Module['HEAP32'] = HEAP32; | |
Module['HEAPU8'] = HEAPU8; | |
Module['HEAPU16'] = HEAPU16; | |
Module['HEAPU32'] = HEAPU32; | |
Module['HEAPF32'] = HEAPF32; | |
Module['HEAPF64'] = HEAPF64; | |
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) { | |
Runtime.dynCall('v', func); | |
} else { | |
Runtime.dynCall('vi', func, [callback.arg]); | |
} | |
} else { | |
func(callback.arg === undefined ? null : callback.arg); | |
} | |
} | |
} | |
var __ATPRERUN__ = []; // functions called before the runtime is initialized | |
var __ATINIT__ = []; // functions called during startup | |
var __ATMAIN__ = []; // functions called when main() is to be run | |
var __ATEXIT__ = []; // functions called during shutdown | |
var __ATPOSTRUN__ = []; // functions called after the runtime has exited | |
var runtimeInitialized = false; | |
var runtimeExited = false; | |
function preRun() { | |
// compatibility - merge in anything from Module['preRun'] at this time | |
if (Module['preRun']) { | |
if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']]; | |
while (Module['preRun'].length) { | |
addOnPreRun(Module['preRun'].shift()); | |
} | |
} | |
callRuntimeCallbacks(__ATPRERUN__); | |
} | |
function ensureInitRuntime() { | |
if (runtimeInitialized) return; | |
runtimeInitialized = true; | |
callRuntimeCallbacks(__ATINIT__); | |
} | |
function preMain() { | |
callRuntimeCallbacks(__ATMAIN__); | |
} | |
function exitRuntime() { | |
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { | |
Module.printErr('Exiting runtime. Any attempt to access the compiled C code may fail from now. If you want to keep the runtime alive, set Module["noExitRuntime"] = true or build with -s NO_EXIT_RUNTIME=1'); | |
} | |
callRuntimeCallbacks(__ATEXIT__); | |
runtimeExited = true; | |
} | |
function postRun() { | |
// compatibility - merge in anything from Module['postRun'] at this time | |
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); | |
} | |
Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun; | |
function addOnInit(cb) { | |
__ATINIT__.unshift(cb); | |
} | |
Module['addOnInit'] = Module.addOnInit = addOnInit; | |
function addOnPreMain(cb) { | |
__ATMAIN__.unshift(cb); | |
} | |
Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain; | |
function addOnExit(cb) { | |
__ATEXIT__.unshift(cb); | |
} | |
Module['addOnExit'] = Module.addOnExit = addOnExit; | |
function addOnPostRun(cb) { | |
__ATPOSTRUN__.unshift(cb); | |
} | |
Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun; | |
// Tools | |
function intArrayFromString(stringy, dontAddNull, length /* optional */) { | |
var ret = (new Runtime.UTF8Processor()).processJSString(stringy); | |
if (length) { | |
ret.length = length; | |
} | |
if (!dontAddNull) { | |
ret.push(0); | |
} | |
return ret; | |
} | |
Module['intArrayFromString'] = intArrayFromString; | |
function intArrayToString(array) { | |
var ret = []; | |
for (var i = 0; i < array.length; i++) { | |
var chr = array[i]; | |
if (chr > 0xFF) { | |
assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.'); | |
chr &= 0xFF; | |
} | |
ret.push(String.fromCharCode(chr)); | |
} | |
return ret.join(''); | |
} | |
Module['intArrayToString'] = intArrayToString; | |
function writeStringToMemory(string, buffer, dontAddNull) { | |
var array = intArrayFromString(string, dontAddNull); | |
var i = 0; | |
while (i < array.length) { | |
var chr = array[i]; | |
HEAP8[(((buffer)+(i))>>0)]=chr; | |
i = i + 1; | |
} | |
} | |
Module['writeStringToMemory'] = writeStringToMemory; | |
function writeArrayToMemory(array, buffer) { | |
for (var i = 0; i < array.length; i++) { | |
HEAP8[(((buffer)+(i))>>0)]=array[i]; | |
} | |
} | |
Module['writeArrayToMemory'] = writeArrayToMemory; | |
function writeAsciiToMemory(str, buffer, dontAddNull) { | |
for (var i = 0; i < str.length; i++) { | |
assert(str.charCodeAt(i) === str.charCodeAt(i)&0xff); | |
HEAP8[(((buffer)+(i))>>0)]=str.charCodeAt(i); | |
} | |
if (!dontAddNull) HEAP8[(((buffer)+(str.length))>>0)]=0; | |
} | |
Module['writeAsciiToMemory'] = writeAsciiToMemory; | |
function unSign(value, bits, ignore) { | |
if (value >= 0) { | |
return value; | |
} | |
return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts | |
: Math.pow(2, bits) + value; | |
} | |
function reSign(value, bits, ignore) { | |
if (value <= 0) { | |
return value; | |
} | |
var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32 | |
: Math.pow(2, bits-1); | |
if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that | |
// but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors | |
// TODO: In i64 mode 1, resign the two parts separately and safely | |
value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts | |
} | |
return value; | |
} | |
// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 ) | |
if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) { | |
var ah = a >>> 16; | |
var al = a & 0xffff; | |
var bh = b >>> 16; | |
var bl = b & 0xffff; | |
return (al*bl + ((ah*bl + al*bh) << 16))|0; | |
}; | |
Math.imul = Math['imul']; | |
var Math_abs = Math.abs; | |
var Math_cos = Math.cos; | |
var Math_sin = Math.sin; | |
var Math_tan = Math.tan; | |
var Math_acos = Math.acos; | |
var Math_asin = Math.asin; | |
var Math_atan = Math.atan; | |
var Math_atan2 = Math.atan2; | |
var Math_exp = Math.exp; | |
var Math_log = Math.log; | |
var Math_sqrt = Math.sqrt; | |
var Math_ceil = Math.ceil; | |
var Math_floor = Math.floor; | |
var Math_pow = Math.pow; | |
var Math_imul = Math.imul; | |
var Math_fround = Math.fround; | |
var Math_min = Math.min; | |
// A counter of dependencies for calling run(). If we need to | |
// do asynchronous work before running, increment this and | |
// decrement it. Incrementing must happen in a place like | |
// PRE_RUN_ADDITIONS (used by emcc to add file preloading). | |
// Note that you can add dependencies in preRun, even though | |
// it happens right before run - run will be postponed until | |
// the dependencies are met. | |
var runDependencies = 0; | |
var runDependencyWatcher = null; | |
var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled | |
var runDependencyTracking = {}; | |
function addRunDependency(id) { | |
runDependencies++; | |
if (Module['monitorRunDependencies']) { | |
Module['monitorRunDependencies'](runDependencies); | |
} | |
if (id) { | |
assert(!runDependencyTracking[id]); | |
runDependencyTracking[id] = 1; | |
if (runDependencyWatcher === null && typeof setInterval !== 'undefined') { | |
// Check for missing dependencies every few seconds | |
runDependencyWatcher = setInterval(function() { | |
if (ABORT) { | |
clearInterval(runDependencyWatcher); | |
runDependencyWatcher = null; | |
return; | |
} | |
var shown = false; | |
for (var dep in runDependencyTracking) { | |
if (!shown) { | |
shown = true; | |
Module.printErr('still waiting on run dependencies:'); | |
} | |
Module.printErr('dependency: ' + dep); | |
} | |
if (shown) { | |
Module.printErr('(end of list)'); | |
} | |
}, 10000); | |
} | |
} else { | |
Module.printErr('warning: run dependency added without ID'); | |
} | |
} | |
Module['addRunDependency'] = addRunDependency; | |
function removeRunDependency(id) { | |
runDependencies--; | |
if (Module['monitorRunDependencies']) { | |
Module['monitorRunDependencies'](runDependencies); | |
} | |
if (id) { | |
assert(runDependencyTracking[id]); | |
delete runDependencyTracking[id]; | |
} else { | |
Module.printErr('warning: run dependency removed without ID'); | |
} | |
if (runDependencies == 0) { | |
if (runDependencyWatcher !== null) { | |
clearInterval(runDependencyWatcher); | |
runDependencyWatcher = null; | |
} | |
if (dependenciesFulfilled) { | |
var callback = dependenciesFulfilled; | |
dependenciesFulfilled = null; | |
callback(); // can add another dependenciesFulfilled | |
} | |
} | |
} | |
Module['removeRunDependency'] = removeRunDependency; | |
Module["preloadedImages"] = {}; // maps url to image data | |
Module["preloadedAudios"] = {}; // maps url to audio data | |
var memoryInitializer = null; | |
// === Body === | |
STATIC_BASE = 8; | |
STATICTOP = STATIC_BASE + 528; | |
/* global initializers */ __ATINIT__.push(); | |
/* memory initializer */ allocate([119,105,110,100,111,119,46,99,108,111,115,101,40,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE); | |
var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8); | |
assert(tempDoublePtr % 8 == 0); | |
function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much | |
HEAP8[tempDoublePtr] = HEAP8[ptr]; | |
HEAP8[tempDoublePtr+1] = HEAP8[ptr+1]; | |
HEAP8[tempDoublePtr+2] = HEAP8[ptr+2]; | |
HEAP8[tempDoublePtr+3] = HEAP8[ptr+3]; | |
} | |
function copyTempDouble(ptr) { | |
HEAP8[tempDoublePtr] = HEAP8[ptr]; | |
HEAP8[tempDoublePtr+1] = HEAP8[ptr+1]; | |
HEAP8[tempDoublePtr+2] = HEAP8[ptr+2]; | |
HEAP8[tempDoublePtr+3] = HEAP8[ptr+3]; | |
HEAP8[tempDoublePtr+4] = HEAP8[ptr+4]; | |
HEAP8[tempDoublePtr+5] = HEAP8[ptr+5]; | |
HEAP8[tempDoublePtr+6] = HEAP8[ptr+6]; | |
HEAP8[tempDoublePtr+7] = HEAP8[ptr+7]; | |
} | |
var ___errno_state=0;function ___setErrNo(value) { | |
// For convenient setting and returning of errno. | |
HEAP32[((___errno_state)>>2)]=value; | |
return value; | |
} | |
var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};function _sysconf(name) { | |
// long sysconf(int name); | |
// http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html | |
switch(name) { | |
case 30: return PAGE_SIZE; | |
case 132: | |
case 133: | |
case 12: | |
case 137: | |
case 138: | |
case 15: | |
case 235: | |
case 16: | |
case 17: | |
case 18: | |
case 19: | |
case 20: | |
case 149: | |
case 13: | |
case 10: | |
case 236: | |
case 153: | |
case 9: | |
case 21: | |
case 22: | |
case 159: | |
case 154: | |
case 14: | |
case 77: | |
case 78: | |
case 139: | |
case 80: | |
case 81: | |
case 79: | |
case 82: | |
case 68: | |
case 67: | |
case 164: | |
case 11: | |
case 29: | |
case 47: | |
case 48: | |
case 95: | |
case 52: | |
case 51: | |
case 46: | |
return 200809; | |
case 27: | |
case 246: | |
case 127: | |
case 128: | |
case 23: | |
case 24: | |
case 160: | |
case 161: | |
case 181: | |
case 182: | |
case 242: | |
case 183: | |
case 184: | |
case 243: | |
case 244: | |
case 245: | |
case 165: | |
case 178: | |
case 179: | |
case 49: | |
case 50: | |
case 168: | |
case 169: | |
case 175: | |
case 170: | |
case 171: | |
case 172: | |
case 97: | |
case 76: | |
case 32: | |
case 173: | |
case 35: | |
return -1; | |
case 176: | |
case 177: | |
case 7: | |
case 155: | |
case 8: | |
case 157: | |
case 125: | |
case 126: | |
case 92: | |
case 93: | |
case 129: | |
case 130: | |
case 131: | |
case 94: | |
case 91: | |
return 1; | |
case 74: | |
case 60: | |
case 69: | |
case 70: | |
case 4: | |
return 1024; | |
case 31: | |
case 42: | |
case 72: | |
return 32; | |
case 87: | |
case 26: | |
case 33: | |
return 2147483647; | |
case 34: | |
case 1: | |
return 47839; | |
case 38: | |
case 36: | |
return 99; | |
case 43: | |
case 37: | |
return 2048; | |
case 0: return 2097152; | |
case 3: return 65536; | |
case 28: return 32768; | |
case 44: return 32767; | |
case 75: return 16384; | |
case 39: return 1000; | |
case 89: return 700; | |
case 71: return 256; | |
case 40: return 255; | |
case 2: return 100; | |
case 180: return 64; | |
case 25: return 20; | |
case 5: return 16; | |
case 6: return 6; | |
case 73: return 4; | |
case 84: { | |
if (typeof navigator === 'object') return navigator['hardwareConcurrency'] || 1; | |
return 1; | |
} | |
} | |
___setErrNo(ERRNO_CODES.EINVAL); | |
return -1; | |
} | |
Module["_memset"] = _memset; | |
function _abort() { | |
Module['abort'](); | |
} | |
var GL={counter:1,lastError:0,buffers:[],mappedBuffers:{},programs:[],framebuffers:[],renderbuffers:[],textures:[],uniforms:[],shaders:[],vaos:[],contexts:[],byteSizeByTypeRoot:5120,byteSizeByType:[1,1,2,2,4,4,4,2,3,4,8],programInfos:{},stringCache:{},packAlignment:4,unpackAlignment:4,init:function () { | |
GL.miniTempBuffer = new Float32Array(GL.MINI_TEMP_BUFFER_SIZE); | |
for (var i = 0; i < GL.MINI_TEMP_BUFFER_SIZE; i++) { | |
GL.miniTempBufferViews[i] = GL.miniTempBuffer.subarray(0, i+1); | |
} | |
},recordError:function recordError(errorCode) { | |
if (!GL.lastError) { | |
GL.lastError = errorCode; | |
} | |
},getNewId:function (table) { | |
var ret = GL.counter++; | |
for (var i = table.length; i < ret; i++) { | |
table[i] = null; | |
} | |
return ret; | |
},MINI_TEMP_BUFFER_SIZE:16,miniTempBuffer:null,miniTempBufferViews:[0],getSource:function (shader, count, string, length) { | |
var source = ''; | |
for (var i = 0; i < count; ++i) { | |
var frag; | |
if (length) { | |
var len = HEAP32[(((length)+(i*4))>>2)]; | |
if (len < 0) { | |
frag = Pointer_stringify(HEAP32[(((string)+(i*4))>>2)]); | |
} else { | |
frag = Pointer_stringify(HEAP32[(((string)+(i*4))>>2)], len); | |
} | |
} else { | |
frag = Pointer_stringify(HEAP32[(((string)+(i*4))>>2)]); | |
} | |
source += frag; | |
} | |
return source; | |
},computeImageSize:function (width, height, sizePerPixel, alignment) { | |
function roundedToNextMultipleOf(x, y) { | |
return Math.floor((x + y - 1) / y) * y | |
} | |
var plainRowSize = width * sizePerPixel; | |
var alignedRowSize = roundedToNextMultipleOf(plainRowSize, alignment); | |
return (height <= 0) ? 0 : | |
((height - 1) * alignedRowSize + plainRowSize); | |
},get:function (name_, p, type) { | |
// Guard against user passing a null pointer. | |
// Note that GLES2 spec does not say anything about how passing a null pointer should be treated. | |
// Testing on desktop core GL 3, the application crashes on glGetIntegerv to a null pointer, but | |
// better to report an error instead of doing anything random. | |
if (!p) { | |
GL.recordError(0x0501 /* GL_INVALID_VALUE */); | |
return; | |
} | |
var ret = undefined; | |
switch(name_) { // Handle a few trivial GLES values | |
case 0x8DFA: // GL_SHADER_COMPILER | |
ret = 1; | |
break; | |
case 0x8DF8: // GL_SHADER_BINARY_FORMATS | |
if (type !== 'Integer') { | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
} | |
return; // Do not write anything to the out pointer, since no binary formats are supported. | |
case 0x8DF9: // GL_NUM_SHADER_BINARY_FORMATS | |
ret = 0; | |
break; | |
case 0x86A2: // GL_NUM_COMPRESSED_TEXTURE_FORMATS | |
// WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be queried for length), | |
// so implement it ourselves to allow C++ GLES2 code get the length. | |
var formats = GLctx.getParameter(0x86A3 /*GL_COMPRESSED_TEXTURE_FORMATS*/); | |
ret = formats.length; | |
break; | |
case 0x8B9A: // GL_IMPLEMENTATION_COLOR_READ_TYPE | |
ret = 0x1401; // GL_UNSIGNED_BYTE | |
break; | |
case 0x8B9B: // GL_IMPLEMENTATION_COLOR_READ_FORMAT | |
ret = 0x1908; // GL_RGBA | |
break; | |
} | |
if (ret === undefined) { | |
var result = GLctx.getParameter(name_); | |
switch (typeof(result)) { | |
case "number": | |
ret = result; | |
break; | |
case "boolean": | |
ret = result ? 1 : 0; | |
break; | |
case "string": | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
return; | |
case "object": | |
if (result === null) { | |
// null is a valid result for some (e.g., which buffer is bound - perhaps nothing is bound), but otherwise | |
// can mean an invalid name_, which we need to report as an error | |
switch(name_) { | |
case 0x8894: // ARRAY_BUFFER_BINDING | |
case 0x8B8D: // CURRENT_PROGRAM | |
case 0x8895: // ELEMENT_ARRAY_BUFFER_BINDING | |
case 0x8CA6: // FRAMEBUFFER_BINDING | |
case 0x8CA7: // RENDERBUFFER_BINDING | |
case 0x8069: // TEXTURE_BINDING_2D | |
case 0x8514: { // TEXTURE_BINDING_CUBE_MAP | |
ret = 0; | |
break; | |
} | |
default: { | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
return; | |
} | |
} | |
} else if (result instanceof Float32Array || | |
result instanceof Uint32Array || | |
result instanceof Int32Array || | |
result instanceof Array) { | |
for (var i = 0; i < result.length; ++i) { | |
switch (type) { | |
case 'Integer': HEAP32[(((p)+(i*4))>>2)]=result[i]; break; | |
case 'Float': HEAPF32[(((p)+(i*4))>>2)]=result[i]; break; | |
case 'Boolean': HEAP8[(((p)+(i))>>0)]=result[i] ? 1 : 0; break; | |
default: throw 'internal glGet error, bad type: ' + type; | |
} | |
} | |
return; | |
} else if (result instanceof WebGLBuffer || | |
result instanceof WebGLProgram || | |
result instanceof WebGLFramebuffer || | |
result instanceof WebGLRenderbuffer || | |
result instanceof WebGLTexture) { | |
ret = result.name | 0; | |
} else { | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
return; | |
} | |
break; | |
default: | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
return; | |
} | |
} | |
switch (type) { | |
case 'Integer': HEAP32[((p)>>2)]=ret; break; | |
case 'Float': HEAPF32[((p)>>2)]=ret; break; | |
case 'Boolean': HEAP8[((p)>>0)]=ret ? 1 : 0; break; | |
default: throw 'internal glGet error, bad type: ' + type; | |
} | |
},getTexPixelData:function (type, format, width, height, pixels, internalFormat) { | |
var sizePerPixel; | |
switch (type) { | |
case 0x1401 /* GL_UNSIGNED_BYTE */: | |
switch (format) { | |
case 0x1906 /* GL_ALPHA */: | |
case 0x1909 /* GL_LUMINANCE */: | |
sizePerPixel = 1; | |
break; | |
case 0x1907 /* GL_RGB */: | |
sizePerPixel = 3; | |
break; | |
case 0x1908 /* GL_RGBA */: | |
sizePerPixel = 4; | |
break; | |
case 0x190A /* GL_LUMINANCE_ALPHA */: | |
sizePerPixel = 2; | |
break; | |
default: | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
return { | |
pixels: null, | |
internalFormat: 0x0 | |
}; | |
} | |
break; | |
case 0x1403 /* GL_UNSIGNED_SHORT */: | |
if (format == 0x1902 /* GL_DEPTH_COMPONENT */) { | |
sizePerPixel = 2; | |
} else { | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
return { | |
pixels: null, | |
internalFormat: 0x0 | |
}; | |
} | |
break; | |
case 0x1405 /* GL_UNSIGNED_INT */: | |
if (format == 0x1902 /* GL_DEPTH_COMPONENT */) { | |
sizePerPixel = 4; | |
} else { | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
return { | |
pixels: null, | |
internalFormat: 0x0 | |
}; | |
} | |
break; | |
case 0x84FA /* UNSIGNED_INT_24_8_WEBGL */: | |
sizePerPixel = 4; | |
break; | |
case 0x8363 /* GL_UNSIGNED_SHORT_5_6_5 */: | |
case 0x8033 /* GL_UNSIGNED_SHORT_4_4_4_4 */: | |
case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */: | |
sizePerPixel = 2; | |
break; | |
case 0x1406 /* GL_FLOAT */: | |
switch (format) { | |
case 0x1907 /* GL_RGB */: | |
sizePerPixel = 3*4; | |
break; | |
case 0x1908 /* GL_RGBA */: | |
sizePerPixel = 4*4; | |
break; | |
default: | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
return { | |
pixels: null, | |
internalFormat: 0x0 | |
}; | |
} | |
internalFormat = GLctx.RGBA; | |
break; | |
case 0x8D61 /* GL_HALF_FLOAT_OES */: | |
switch (format) { | |
case 0x1903 /* GL_RED */: | |
sizePerPixel = 2; | |
break; | |
case 0x8277 /* GL_RG */: | |
sizePerPixel = 2*2; | |
break; | |
case 0x1907 /* GL_RGB */: | |
sizePerPixel = 3*2; | |
break; | |
case 0x1908 /* GL_RGBA */: | |
sizePerPixel = 4*2; | |
break; | |
default: | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
return { | |
pixels: null, | |
internalFormat: 0x0 | |
}; | |
} | |
break; | |
default: | |
GL.recordError(0x0500); // GL_INVALID_ENUM | |
return { | |
pixels: null, | |
internalFormat: 0x0 | |
}; | |
} | |
var bytes = GL.computeImageSize(width, height, sizePerPixel, GL.unpackAlignment); | |
if (type == 0x1401 /* GL_UNSIGNED_BYTE */) { | |
pixels = HEAPU8.subarray((pixels),(pixels+bytes)); | |
} else if (type == 0x1406 /* GL_FLOAT */) { | |
pixels = HEAPF32.subarray((pixels)>>2,(pixels+bytes)>>2); | |
} else if (type == 0x1405 /* GL_UNSIGNED_INT */ || type == 0x84FA /* UNSIGNED_INT_24_8_WEBGL */) { | |
pixels = HEAPU32.subarray((pixels)>>2,(pixels+bytes)>>2); | |
} else { | |
pixels = HEAPU16.subarray((pixels)>>1,(pixels+bytes)>>1); | |
} | |
return { | |
pixels: pixels, | |
internalFormat: internalFormat | |
}; | |
},validateBufferTarget:function (target) { | |
switch (target) { | |
case 0x8892: // GL_ARRAY_BUFFER | |
case 0x8893: // GL_ELEMENT_ARRAY_BUFFER | |
case 0x8F36: // GL_COPY_READ_BUFFER | |
case 0x8F37: // GL_COPY_WRITE_BUFFER | |
case 0x88EB: // GL_PIXEL_PACK_BUFFER | |
case 0x88EC: // GL_PIXEL_UNPACK_BUFFER | |
case 0x8C2A: // GL_TEXTURE_BUFFER | |
case 0x8C8E: // GL_TRANSFORM_FEEDBACK_BUFFER | |
case 0x8A11: // GL_UNIFORM_BUFFER | |
return true; | |
default: | |
return false; | |
} | |
},createContext:function (canvas, webGLContextAttributes) { | |
if (typeof webGLContextAttributes.majorVersion === 'undefined' && typeof webGLContextAttributes.minorVersion === 'undefined') { | |
webGLContextAttributes.majorVersion = 1; | |
webGLContextAttributes.minorVersion = 0; | |
} | |
var ctx; | |
var errorInfo = '?'; | |
function onContextCreationError(event) { | |
errorInfo = event.statusMessage || errorInfo; | |
} | |
try { | |
canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false); | |
try { | |
if (webGLContextAttributes.majorVersion == 1 && webGLContextAttributes.minorVersion == 0) { | |
ctx = canvas.getContext("webgl", webGLContextAttributes) || canvas.getContext("experimental-webgl", webGLContextAttributes); | |
} else if (webGLContextAttributes.majorVersion == 2 && webGLContextAttributes.minorVersion == 0) { | |
ctx = canvas.getContext("webgl2", webGLContextAttributes) || canvas.getContext("experimental-webgl2", webGLContextAttributes); | |
} else { | |
throw 'Unsupported WebGL context version ' + majorVersion + '.' + minorVersion + '!' | |
} | |
} finally { | |
canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false); | |
} | |
if (!ctx) throw ':('; | |
} catch (e) { | |
Module.print('Could not create canvas: ' + [errorInfo, e, JSON.stringify(webGLContextAttributes)]); | |
return 0; | |
} | |
// possible GL_DEBUG entry point: ctx = wrapDebugGL(ctx); | |
if (!ctx) return 0; | |
var handle = GL.getNewId(GL.contexts); | |
var context = { | |
handle: handle, | |
version: webGLContextAttributes.majorVersion, | |
GLctx: ctx | |
}; | |
// Store the created context object so that we can access the context given a canvas without having to pass the parameters again. | |
ctx.canvas.GLctxObject = context; | |
GL.contexts[handle] = context; | |
if (typeof webGLContextAttributes['webGLContextAttributes'] === 'undefined' || webGLContextAttributes.enableExtensionsByDefault) { | |
GL.initExtensions(context); | |
} | |
return handle; | |
},makeContextCurrent:function (contextHandle) { | |
var context = GL.contexts[contextHandle]; | |
if (!context) return false; | |
GLctx = Module.ctx = context.GLctx; // Active WebGL context object. | |
GL.currentContext = context; // Active Emscripten GL layer context object. | |
return true; | |
},getContext:function (contextHandle) { | |
return GL.contexts[contextHandle]; | |
},deleteContext:function (contextHandle) { | |
if (GL.currentContext === GL.contexts[contextHandle]) GL.currentContext = 0; | |
if (GL.contexts[contextHandle]) GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined; // Make sure the canvas object no longer refers to the context object so there are no GC surprises. | |
GL.contexts[contextHandle] = null; | |
},initExtensions:function (context) { | |
// If this function is called without a specific context object, init the extensions of the currently active context. | |
if (!context) context = GL.currentContext; | |
if (context.initExtensionsDone) return; | |
context.initExtensionsDone = true; | |
var GLctx = context.GLctx; | |
context.maxVertexAttribs = GLctx.getParameter(GLctx.MAX_VERTEX_ATTRIBS); | |
// Detect the presence of a few extensions manually, this GL interop layer itself will need to know if they exist. | |
context.compressionExt = GLctx.getExtension('WEBGL_compressed_texture_s3tc') || | |
GLctx.getExtension('MOZ_WEBGL_compressed_texture_s3tc') || | |
GLctx.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc'); | |
context.anisotropicExt = GLctx.getExtension('EXT_texture_filter_anisotropic') || | |
GLctx.getExtension('MOZ_EXT_texture_filter_anisotropic') || | |
GLctx.getExtension('WEBKIT_EXT_texture_filter_anisotropic'); | |
context.floatExt = GLctx.getExtension('OES_texture_float'); | |
// Extension available from Firefox 26 and Google Chrome 30 | |
context.instancedArraysExt = GLctx.getExtension('ANGLE_instanced_arrays'); | |
// Extension available from Firefox 25 and WebKit | |
context.vaoExt = GLctx.getExtension('OES_vertex_array_object'); | |
if (context.version === 2) { | |
// drawBuffers is available in WebGL2 by default. | |
context.drawBuffersExt = function(n, bufs) { | |
GLctx.drawBuffers(n, bufs); | |
}; | |
} else { | |
var ext = GLctx.getExtension('WEBGL_draw_buffers'); | |
if (ext) { | |
context.drawBuffersExt = function(n, bufs) { | |
ext.drawBuffersWEBGL(n, bufs); | |
}; | |
} | |
} | |
// These are the 'safe' feature-enabling extensions that don't add any performance impact related to e.g. debugging, and | |
// should be enabled by default so that client GLES2/GL code will not need to go through extra hoops to get its stuff working. | |
// As new extensions are ratified at http://www.khronos.org/registry/webgl/extensions/ , feel free to add your new extensions | |
// here, as long as they don't produce a performance impact for users that might not be using those extensions. | |
// E.g. debugging-related extensions should probably be off by default. | |
var automaticallyEnabledExtensions = [ "OES_texture_float", "OES_texture_half_float", "OES_standard_derivatives", | |
"OES_vertex_array_object", "WEBGL_compressed_texture_s3tc", "WEBGL_depth_texture", | |
"OES_element_index_uint", "EXT_texture_filter_anisotropic", "ANGLE_instanced_arrays", | |
"OES_texture_float_linear", "OES_texture_half_float_linear", "WEBGL_compressed_texture_atc", | |
"WEBGL_compressed_texture_pvrtc", "EXT_color_buffer_half_float", "WEBGL_color_buffer_float", | |
"EXT_frag_depth", "EXT_sRGB", "WEBGL_draw_buffers", "WEBGL_shared_resources", | |
"EXT_shader_texture_lod" ]; | |
function shouldEnableAutomatically(extension) { | |
var ret = false; | |
automaticallyEnabledExtensions.forEach(function(include) { | |
if (ext.indexOf(include) != -1) { | |
ret = true; | |
} | |
}); | |
return ret; | |
} | |
GLctx.getSupportedExtensions().forEach(function(ext) { | |
ext = ext.replace('MOZ_', '').replace('WEBKIT_', ''); | |
if (automaticallyEnabledExtensions.indexOf(ext) != -1) { | |
GLctx.getExtension(ext); // Calling .getExtension enables that extension permanently, no need to store the return value to be enabled. | |
} | |
}); | |
},populateUniformTable:function (program) { | |
var p = GL.programs[program]; | |
GL.programInfos[program] = { | |
uniforms: {}, | |
maxUniformLength: 0, // This is eagerly computed below, since we already enumerate all uniforms anyway. | |
maxAttributeLength: -1 // This is lazily computed and cached, computed when/if first asked, "-1" meaning not computed yet. | |
}; | |
var ptable = GL.programInfos[program]; | |
var utable = ptable.uniforms; | |
// A program's uniform table maps the string name of an uniform to an integer location of that uniform. | |
// The global GL.uniforms map maps integer locations to WebGLUniformLocations. | |
var numUniforms = GLctx.getProgramParameter(p, GLctx.ACTIVE_UNIFORMS); | |
for (var i = 0; i < numUniforms; ++i) { | |
var u = GLctx.getActiveUniform(p, i); | |
var name = u.name; | |
ptable.maxUniformLength = Math.max(ptable.maxUniformLength, name.length+1); | |
// Strip off any trailing array specifier we might have got, e.g. "[0]". | |
if (name.indexOf(']', name.length-1) !== -1) { | |
var ls = name.lastIndexOf('['); | |
name = name.slice(0, ls); | |
} | |
// Optimize memory usage slightly: If we have an array of uniforms, e.g. 'vec3 colors[3];', then | |
// only store the string 'colors' in utable, and 'colors[0]', 'colors[1]' and 'colors[2]' will be parsed as 'colors'+i. | |
// Note that for the GL.uniforms table, we still need to fetch the all WebGLUniformLocations for all the indices. | |
var loc = GLctx.getUniformLocation(p, name); | |
var id = GL.getNewId(GL.uniforms); | |
utable[name] = [u.size, id]; | |
GL.uniforms[id] = loc; | |
for (var j = 1; j < u.size; ++j) { | |
var n = name + '['+j+']'; | |
loc = GLctx.getUniformLocation(p, n); | |
id = GL.getNewId(GL.uniforms); | |
GL.uniforms[id] = loc; | |
} | |
} | |
}};function _SDL_SetVideoMode(width, height, depth, flags) { | |
['touchstart', 'touchend', 'touchmove', 'mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'wheel', 'mouseout'].forEach(function(event) { | |
Module['canvas'].addEventListener(event, SDL.receiveEvent, true); | |
}); | |
var canvas = Module['canvas']; | |
// (0,0) means 'use fullscreen' in native; in Emscripten, use the current canvas size. | |
if (width == 0 && height == 0) { | |
width = canvas.width; | |
height = canvas.height; | |
} | |
if (!SDL.addedResizeListener) { | |
SDL.addedResizeListener = true; | |
Browser.resizeListeners.push(function(w, h) { | |
if (!SDL.settingVideoMode) { | |
SDL.receiveEvent({ | |
type: 'resize', | |
w: w, | |
h: h | |
}); | |
} | |
}); | |
} | |
if (width !== canvas.width || height !== canvas.height) { | |
SDL.settingVideoMode = true; // SetVideoMode itself should not trigger resize events | |
Browser.setCanvasSize(width, height); | |
SDL.settingVideoMode = false; | |
} | |
// Free the old surface first if there is one | |
if (SDL.screen) { | |
SDL.freeSurface(SDL.screen); | |
assert(!SDL.screen); | |
} | |
if (SDL.GL) flags = flags | 0x04000000; // SDL_OPENGL - if we are using GL, then later calls to SetVideoMode may not mention GL, but we do need it. Once in GL mode, we never leave it. | |
SDL.screen = SDL.makeSurface(width, height, flags, true, 'screen'); | |
return SDL.screen; | |
} | |
var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"}; | |
var PATH={splitPath:function (filename) { | |
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; | |
return splitPathRe.exec(filename).slice(1); | |
},normalizeArray:function (parts, allowAboveRoot) { | |
// if the path tries to go above the root, `up` ends up > 0 | |
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 the path is allowed to go above the root, restore leading ..s | |
if (allowAboveRoot) { | |
for (; up--; up) { | |
parts.unshift('..'); | |
} | |
} | |
return parts; | |
},normalize:function (path) { | |
var isAbsolute = path.charAt(0) === '/', | |
trailingSlash = path.substr(-1) === '/'; | |
// Normalize the path | |
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) { | |
// No dirname whatsoever | |
return '.'; | |
} | |
if (dir) { | |
// It has a dirname, strip trailing slash | |
dir = dir.substr(0, dir.length - 1); | |
} | |
return root + dir; | |
},basename:function (path) { | |
// EMSCRIPTEN return '/'' for '/', not an empty string | |
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); | |
},resolve:function () { | |
var resolvedPath = '', | |
resolvedAbsolute = false; | |
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { | |
var path = (i >= 0) ? arguments[i] : FS.cwd(); | |
// Skip empty and invalid entries | |
if (typeof path !== 'string') { | |
throw new TypeError('Arguments to path.resolve must be strings'); | |
} else if (!path) { | |
return ''; // an invalid portion invalidates the whole thing | |
} | |
resolvedPath = path + '/' + resolvedPath; | |
resolvedAbsolute = path.charAt(0) === '/'; | |
} | |
// At this point the path should be resolved to a full absolute path, but | |
// handle relative paths to be safe (might happen when process.cwd() fails) | |
resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) { | |
return !!p; | |
}), !resolvedAbsolute).join('/'); | |
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; | |
},relative:function (from, to) { | |
from = PATH.resolve(from).substr(1); | |
to = PATH.resolve(to).substr(1); | |
function trim(arr) { | |
var start = 0; | |
for (; start < arr.length; start++) { | |
if (arr[start] !== '') break; | |
} | |
var end = arr.length - 1; | |
for (; end >= 0; end--) { | |
if (arr[end] !== '') break; | |
} | |
if (start > end) return []; | |
return arr.slice(start, end - start + 1); | |
} | |
var fromParts = trim(from.split('/')); | |
var toParts = trim(to.split('/')); | |
var length = Math.min(fromParts.length, toParts.length); | |
var samePartsLength = length; | |
for (var i = 0; i < length; i++) { | |
if (fromParts[i] !== toParts[i]) { | |
samePartsLength = i; | |
break; | |
} | |
} | |
var outputParts = []; | |
for (var i = samePartsLength; i < fromParts.length; i++) { | |
outputParts.push('..'); | |
} | |
outputParts = outputParts.concat(toParts.slice(samePartsLength)); | |
return outputParts.join('/'); | |
}}; | |
var TTY={ttys:[],init:function () { | |
// https://github.com/kripken/emscripten/pull/1555 | |
// if (ENVIRONMENT_IS_NODE) { | |
// // currently, FS.init does not distinguish if process.stdin is a file or TTY | |
// // device, it always assumes it's a TTY device. because of this, we're forcing | |
// // process.stdin to UTF8 encoding to at least make stdin reading compatible | |
// // with text files until FS.init can be refactored. | |
// process['stdin']['setEncoding']('utf8'); | |
// } | |
},shutdown:function () { | |
// https://github.com/kripken/emscripten/pull/1555 | |
// if (ENVIRONMENT_IS_NODE) { | |
// // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)? | |
// // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation | |
// // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists? | |
// // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle | |
// // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call | |
// process['stdin']['pause'](); | |
// } | |
},register:function (dev, ops) { | |
TTY.ttys[dev] = { input: [], output: [], ops: ops }; | |
FS.registerDevice(dev, TTY.stream_ops); | |
},stream_ops:{open:function (stream) { | |
var tty = TTY.ttys[stream.node.rdev]; | |
if (!tty) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENODEV); | |
} | |
stream.tty = tty; | |
stream.seekable = false; | |
},close:function (stream) { | |
// flush any pending line data | |
if (stream.tty.output.length) { | |
stream.tty.ops.put_char(stream.tty, 10); | |
} | |
},read:function (stream, buffer, offset, length, pos /* ignored */) { | |
if (!stream.tty || !stream.tty.ops.get_char) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENXIO); | |
} | |
var bytesRead = 0; | |
for (var i = 0; i < length; i++) { | |
var result; | |
try { | |
result = stream.tty.ops.get_char(stream.tty); | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
if (result === undefined && bytesRead === 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EAGAIN); | |
} | |
if (result === null || result === undefined) break; | |
bytesRead++; | |
buffer[offset+i] = result; | |
} | |
if (bytesRead) { | |
stream.node.timestamp = Date.now(); | |
} | |
return bytesRead; | |
},write:function (stream, buffer, offset, length, pos) { | |
if (!stream.tty || !stream.tty.ops.put_char) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENXIO); | |
} | |
for (var i = 0; i < length; i++) { | |
try { | |
stream.tty.ops.put_char(stream.tty, buffer[offset+i]); | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
} | |
if (length) { | |
stream.node.timestamp = Date.now(); | |
} | |
return i; | |
}},default_tty_ops:{get_char:function (tty) { | |
if (!tty.input.length) { | |
var result = null; | |
if (ENVIRONMENT_IS_NODE) { | |
result = process['stdin']['read'](); | |
if (!result) { | |
if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) { | |
return null; // EOF | |
} | |
return undefined; // no data available | |
} | |
} else if (typeof window != 'undefined' && | |
typeof window.prompt == 'function') { | |
// Browser. | |
result = window.prompt('Input: '); // returns null on cancel | |
if (result !== null) { | |
result += '\n'; | |
} | |
} else if (typeof readline == 'function') { | |
// Command line. | |
result = readline(); | |
if (result !== null) { | |
result += '\n'; | |
} | |
} | |
if (!result) { | |
return null; | |
} | |
tty.input = intArrayFromString(result, true); | |
} | |
return tty.input.shift(); | |
},put_char:function (tty, val) { | |
if (val === null || val === 10) { | |
Module['print'](tty.output.join('')); | |
tty.output = []; | |
} else { | |
tty.output.push(TTY.utf8.processCChar(val)); | |
} | |
}},default_tty1_ops:{put_char:function (tty, val) { | |
if (val === null || val === 10) { | |
Module['printErr'](tty.output.join('')); | |
tty.output = []; | |
} else { | |
tty.output.push(TTY.utf8.processCChar(val)); | |
} | |
}}}; | |
var MEMFS={ops_table:null,mount:function (mount) { | |
return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0); | |
},createNode:function (parent, name, mode, dev) { | |
if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { | |
// no supported | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
if (!MEMFS.ops_table) { | |
MEMFS.ops_table = { | |
dir: { | |
node: { | |
getattr: MEMFS.node_ops.getattr, | |
setattr: MEMFS.node_ops.setattr, | |
lookup: MEMFS.node_ops.lookup, | |
mknod: MEMFS.node_ops.mknod, | |
rename: MEMFS.node_ops.rename, | |
unlink: MEMFS.node_ops.unlink, | |
rmdir: MEMFS.node_ops.rmdir, | |
readdir: MEMFS.node_ops.readdir, | |
symlink: MEMFS.node_ops.symlink | |
}, | |
stream: { | |
llseek: MEMFS.stream_ops.llseek | |
} | |
}, | |
file: { | |
node: { | |
getattr: MEMFS.node_ops.getattr, | |
setattr: MEMFS.node_ops.setattr | |
}, | |
stream: { | |
llseek: MEMFS.stream_ops.llseek, | |
read: MEMFS.stream_ops.read, | |
write: MEMFS.stream_ops.write, | |
allocate: MEMFS.stream_ops.allocate, | |
mmap: MEMFS.stream_ops.mmap | |
} | |
}, | |
link: { | |
node: { | |
getattr: MEMFS.node_ops.getattr, | |
setattr: MEMFS.node_ops.setattr, | |
readlink: MEMFS.node_ops.readlink | |
}, | |
stream: {} | |
}, | |
chrdev: { | |
node: { | |
getattr: MEMFS.node_ops.getattr, | |
setattr: MEMFS.node_ops.setattr | |
}, | |
stream: FS.chrdev_stream_ops | |
}, | |
}; | |
} | |
var node = FS.createNode(parent, name, mode, dev); | |
if (FS.isDir(node.mode)) { | |
node.node_ops = MEMFS.ops_table.dir.node; | |
node.stream_ops = MEMFS.ops_table.dir.stream; | |
node.contents = {}; | |
} else if (FS.isFile(node.mode)) { | |
node.node_ops = MEMFS.ops_table.file.node; | |
node.stream_ops = MEMFS.ops_table.file.stream; | |
node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.buffer.byteLength which gives the whole capacity. | |
// When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred | |
// for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size | |
// penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme. | |
node.contents = null; | |
} else if (FS.isLink(node.mode)) { | |
node.node_ops = MEMFS.ops_table.link.node; | |
node.stream_ops = MEMFS.ops_table.link.stream; | |
} else if (FS.isChrdev(node.mode)) { | |
node.node_ops = MEMFS.ops_table.chrdev.node; | |
node.stream_ops = MEMFS.ops_table.chrdev.stream; | |
} | |
node.timestamp = Date.now(); | |
// add the new node to the parent | |
if (parent) { | |
parent.contents[name] = node; | |
} | |
return node; | |
},getFileDataAsRegularArray:function (node) { | |
if (node.contents && node.contents.subarray) { | |
var arr = []; | |
for (var i = 0; i < node.usedBytes; ++i) arr.push(node.contents[i]); | |
return arr; // Returns a copy of the original data. | |
} | |
return node.contents; // No-op, the file contents are already in a JS array. Return as-is. | |
},getFileDataAsTypedArray:function (node) { | |
if (!node.contents) return new Uint8Array; | |
if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes. | |
return new Uint8Array(node.contents); | |
},expandFileStorage:function (node, newCapacity) { | |
// If we are asked to expand the size of a file that already exists, revert to using a standard JS array to store the file | |
// instead of a typed array. This makes resizing the array more flexible because we can just .push() elements at the back to | |
// increase the size. | |
if (node.contents && node.contents.subarray && newCapacity > node.contents.length) { | |
node.contents = MEMFS.getFileDataAsRegularArray(node); | |
node.usedBytes = node.contents.length; // We might be writing to a lazy-loaded file which had overridden this property, so force-reset it. | |
} | |
if (!node.contents || node.contents.subarray) { // Keep using a typed array if creating a new storage, or if old one was a typed array as well. | |
var prevCapacity = node.contents ? node.contents.buffer.byteLength : 0; | |
if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough. | |
// Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity. | |
// For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to | |
// avoid overshooting the allocation cap by a very large margin. | |
var CAPACITY_DOUBLING_MAX = 1024 * 1024; | |
newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) | 0); | |
if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding. | |
var oldContents = node.contents; | |
node.contents = new Uint8Array(newCapacity); // Allocate new storage. | |
if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage. | |
return; | |
} | |
// Not using a typed array to back the file storage. Use a standard JS array instead. | |
if (!node.contents && newCapacity > 0) node.contents = []; | |
while (node.contents.length < newCapacity) node.contents.push(0); | |
},resizeFileStorage:function (node, newSize) { | |
if (node.usedBytes == newSize) return; | |
if (newSize == 0) { | |
node.contents = null; // Fully decommit when requesting a resize to zero. | |
node.usedBytes = 0; | |
return; | |
} | |
if (!node.contents || node.contents.subarray) { // Resize a typed array if that is being used as the backing store. | |
var oldContents = node.contents; | |
node.contents = new Uint8Array(new ArrayBuffer(newSize)); // Allocate new storage. | |
if (oldContents) { | |
node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage. | |
} | |
node.usedBytes = newSize; | |
return; | |
} | |
// Backing with a JS array. | |
if (!node.contents) node.contents = []; | |
if (node.contents.length > newSize) node.contents.length = newSize; | |
else while (node.contents.length < newSize) node.contents.push(0); | |
node.usedBytes = newSize; | |
},node_ops:{getattr:function (node) { | |
var attr = {}; | |
// device numbers reuse inode numbers. | |
attr.dev = FS.isChrdev(node.mode) ? node.id : 1; | |
attr.ino = node.id; | |
attr.mode = node.mode; | |
attr.nlink = 1; | |
attr.uid = 0; | |
attr.gid = 0; | |
attr.rdev = node.rdev; | |
if (FS.isDir(node.mode)) { | |
attr.size = 4096; | |
} else if (FS.isFile(node.mode)) { | |
attr.size = node.usedBytes; | |
} else if (FS.isLink(node.mode)) { | |
attr.size = node.link.length; | |
} else { | |
attr.size = 0; | |
} | |
attr.atime = new Date(node.timestamp); | |
attr.mtime = new Date(node.timestamp); | |
attr.ctime = new Date(node.timestamp); | |
// NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize), | |
// but this is not required by the standard. | |
attr.blksize = 4096; | |
attr.blocks = Math.ceil(attr.size / attr.blksize); | |
return attr; | |
},setattr:function (node, attr) { | |
if (attr.mode !== undefined) { | |
node.mode = attr.mode; | |
} | |
if (attr.timestamp !== undefined) { | |
node.timestamp = attr.timestamp; | |
} | |
if (attr.size !== undefined) { | |
MEMFS.resizeFileStorage(node, attr.size); | |
} | |
},lookup:function (parent, name) { | |
throw FS.genericErrors[ERRNO_CODES.ENOENT]; | |
},mknod:function (parent, name, mode, dev) { | |
return MEMFS.createNode(parent, name, mode, dev); | |
},rename:function (old_node, new_dir, new_name) { | |
// if we're overwriting a directory at new_name, make sure it's empty. | |
if (FS.isDir(old_node.mode)) { | |
var new_node; | |
try { | |
new_node = FS.lookupNode(new_dir, new_name); | |
} catch (e) { | |
} | |
if (new_node) { | |
for (var i in new_node.contents) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY); | |
} | |
} | |
} | |
// do the internal rewiring | |
delete old_node.parent.contents[old_node.name]; | |
old_node.name = new_name; | |
new_dir.contents[new_name] = old_node; | |
old_node.parent = new_dir; | |
},unlink:function (parent, name) { | |
delete parent.contents[name]; | |
},rmdir:function (parent, name) { | |
var node = FS.lookupNode(parent, name); | |
for (var i in node.contents) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY); | |
} | |
delete parent.contents[name]; | |
},readdir:function (node) { | |
var entries = ['.', '..'] | |
for (var key in node.contents) { | |
if (!node.contents.hasOwnProperty(key)) { | |
continue; | |
} | |
entries.push(key); | |
} | |
return entries; | |
},symlink:function (parent, newname, oldpath) { | |
var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0); | |
node.link = oldpath; | |
return node; | |
},readlink:function (node) { | |
if (!FS.isLink(node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
return node.link; | |
}},stream_ops:{read:function (stream, buffer, offset, length, position) { | |
var contents = stream.node.contents; | |
if (position >= stream.node.usedBytes) return 0; | |
var size = Math.min(stream.node.usedBytes - position, length); | |
assert(size >= 0); | |
if (size > 8 && contents.subarray) { // non-trivial, and typed array | |
buffer.set(contents.subarray(position, position + size), offset); | |
} else | |
{ | |
for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i]; | |
} | |
return size; | |
},write:function (stream, buffer, offset, length, position, canOwn) { | |
if (!length) return 0; | |
var node = stream.node; | |
node.timestamp = Date.now(); | |
if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array? | |
if (canOwn) { // Can we just reuse the buffer we are given? | |
assert(position === 0, 'canOwn must imply no weird position inside the file'); | |
node.contents = buffer.subarray(offset, offset + length); | |
node.usedBytes = length; | |
return length; | |
} else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data. | |
node.contents = new Uint8Array(buffer.subarray(offset, offset + length)); | |
node.usedBytes = length; | |
return length; | |
} else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file? | |
node.contents.set(buffer.subarray(offset, offset + length), position); | |
return length; | |
} | |
} | |
// Appending to an existing file and we need to reallocate, or source data did not come as a typed array. | |
MEMFS.expandFileStorage(node, position+length); | |
if (node.contents.subarray && buffer.subarray) node.contents.set(buffer.subarray(offset, offset + length), position); // Use typed array write if available. | |
else | |
for (var i = 0; i < length; i++) { | |
node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not. | |
} | |
node.usedBytes = Math.max(node.usedBytes, position+length); | |
return length; | |
},llseek:function (stream, offset, whence) { | |
var position = offset; | |
if (whence === 1) { // SEEK_CUR. | |
position += stream.position; | |
} else if (whence === 2) { // SEEK_END. | |
if (FS.isFile(stream.node.mode)) { | |
position += stream.node.usedBytes; | |
} | |
} | |
if (position < 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
return position; | |
},allocate:function (stream, offset, length) { | |
MEMFS.expandFileStorage(stream.node, offset + length); | |
stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length); | |
},mmap:function (stream, buffer, offset, length, position, prot, flags) { | |
if (!FS.isFile(stream.node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENODEV); | |
} | |
var ptr; | |
var allocated; | |
var contents = stream.node.contents; | |
// Only make a new copy when MAP_PRIVATE is specified. | |
if ( !(flags & 2) && | |
(contents.buffer === buffer || contents.buffer === buffer.buffer) ) { | |
// We can't emulate MAP_SHARED when the file is not backed by the buffer | |
// we're mapping to (e.g. the HEAP buffer). | |
allocated = false; | |
ptr = contents.byteOffset; | |
} else { | |
// Try to avoid unnecessary slices. | |
if (position > 0 || position + length < stream.node.usedBytes) { | |
if (contents.subarray) { | |
contents = contents.subarray(position, position + length); | |
} else { | |
contents = Array.prototype.slice.call(contents, position, position + length); | |
} | |
} | |
allocated = true; | |
ptr = _malloc(length); | |
if (!ptr) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOMEM); | |
} | |
buffer.set(contents, ptr); | |
} | |
return { ptr: ptr, allocated: allocated }; | |
}}}; | |
var IDBFS={dbs:{},indexedDB:function () { | |
if (typeof indexedDB !== 'undefined') return indexedDB; | |
var ret = null; | |
if (typeof window === 'object') ret = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; | |
assert(ret, 'IDBFS used, but indexedDB not supported'); | |
return ret; | |
},DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) { | |
// reuse all of the core MEMFS functionality | |
return MEMFS.mount.apply(null, arguments); | |
},syncfs:function (mount, populate, callback) { | |
IDBFS.getLocalSet(mount, function(err, local) { | |
if (err) return callback(err); | |
IDBFS.getRemoteSet(mount, function(err, remote) { | |
if (err) return callback(err); | |
var src = populate ? remote : local; | |
var dst = populate ? local : remote; | |
IDBFS.reconcile(src, dst, callback); | |
}); | |
}); | |
},getDB:function (name, callback) { | |
// check the cache first | |
var db = IDBFS.dbs[name]; | |
if (db) { | |
return callback(null, db); | |
} | |
var req; | |
try { | |
req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION); | |
} catch (e) { | |
return callback(e); | |
} | |
req.onupgradeneeded = function(e) { | |
var db = e.target.result; | |
var transaction = e.target.transaction; | |
var fileStore; | |
if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) { | |
fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME); | |
} else { | |
fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME); | |
} | |
fileStore.createIndex('timestamp', 'timestamp', { unique: false }); | |
}; | |
req.onsuccess = function() { | |
db = req.result; | |
// add to the cache | |
IDBFS.dbs[name] = db; | |
callback(null, db); | |
}; | |
req.onerror = function() { | |
callback(this.error); | |
}; | |
},getLocalSet:function (mount, callback) { | |
var entries = {}; | |
function isRealDir(p) { | |
return p !== '.' && p !== '..'; | |
}; | |
function toAbsolute(root) { | |
return function(p) { | |
return PATH.join2(root, p); | |
} | |
}; | |
var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint)); | |
while (check.length) { | |
var path = check.pop(); | |
var stat; | |
try { | |
stat = FS.stat(path); | |
} catch (e) { | |
return callback(e); | |
} | |
if (FS.isDir(stat.mode)) { | |
check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path))); | |
} | |
entries[path] = { timestamp: stat.mtime }; | |
} | |
return callback(null, { type: 'local', entries: entries }); | |
},getRemoteSet:function (mount, callback) { | |
var entries = {}; | |
IDBFS.getDB(mount.mountpoint, function(err, db) { | |
if (err) return callback(err); | |
var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly'); | |
transaction.onerror = function() { callback(this.error); }; | |
var store = transaction.objectStore(IDBFS.DB_STORE_NAME); | |
var index = store.index('timestamp'); | |
index.openKeyCursor().onsuccess = function(event) { | |
var cursor = event.target.result; | |
if (!cursor) { | |
return callback(null, { type: 'remote', db: db, entries: entries }); | |
} | |
entries[cursor.primaryKey] = { timestamp: cursor.key }; | |
cursor.continue(); | |
}; | |
}); | |
},loadLocalEntry:function (path, callback) { | |
var stat, node; | |
try { | |
var lookup = FS.lookupPath(path); | |
node = lookup.node; | |
stat = FS.stat(path); | |
} catch (e) { | |
return callback(e); | |
} | |
if (FS.isDir(stat.mode)) { | |
return callback(null, { timestamp: stat.mtime, mode: stat.mode }); | |
} else if (FS.isFile(stat.mode)) { | |
// Performance consideration: storing a normal JavaScript array to a IndexedDB is much slower than storing a typed array. | |
// Therefore always convert the file contents to a typed array first before writing the data to IndexedDB. | |
node.contents = MEMFS.getFileDataAsTypedArray(node); | |
return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents }); | |
} else { | |
return callback(new Error('node type not supported')); | |
} | |
},storeLocalEntry:function (path, entry, callback) { | |
try { | |
if (FS.isDir(entry.mode)) { | |
FS.mkdir(path, entry.mode); | |
} else if (FS.isFile(entry.mode)) { | |
FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true }); | |
} else { | |
return callback(new Error('node type not supported')); | |
} | |
FS.chmod(path, entry.mode); | |
FS.utime(path, entry.timestamp, entry.timestamp); | |
} catch (e) { | |
return callback(e); | |
} | |
callback(null); | |
},removeLocalEntry:function (path, callback) { | |
try { | |
var lookup = FS.lookupPath(path); | |
var stat = FS.stat(path); | |
if (FS.isDir(stat.mode)) { | |
FS.rmdir(path); | |
} else if (FS.isFile(stat.mode)) { | |
FS.unlink(path); | |
} | |
} catch (e) { | |
return callback(e); | |
} | |
callback(null); | |
},loadRemoteEntry:function (store, path, callback) { | |
var req = store.get(path); | |
req.onsuccess = function(event) { callback(null, event.target.result); }; | |
req.onerror = function() { callback(this.error); }; | |
},storeRemoteEntry:function (store, path, entry, callback) { | |
var req = store.put(entry, path); | |
req.onsuccess = function() { callback(null); }; | |
req.onerror = function() { callback(this.error); }; | |
},removeRemoteEntry:function (store, path, callback) { | |
var req = store.delete(path); | |
req.onsuccess = function() { callback(null); }; | |
req.onerror = function() { callback(this.error); }; | |
},reconcile:function (src, dst, callback) { | |
var total = 0; | |
var create = []; | |
Object.keys(src.entries).forEach(function (key) { | |
var e = src.entries[key]; | |
var e2 = dst.entries[key]; | |
if (!e2 || e.timestamp > e2.timestamp) { | |
create.push(key); | |
total++; | |
} | |
}); | |
var remove = []; | |
Object.keys(dst.entries).forEach(function (key) { | |
var e = dst.entries[key]; | |
var e2 = src.entries[key]; | |
if (!e2) { | |
remove.push(key); | |
total++; | |
} | |
}); | |
if (!total) { | |
return callback(null); | |
} | |
var errored = false; | |
var completed = 0; | |
var db = src.type === 'remote' ? src.db : dst.db; | |
var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite'); | |
var store = transaction.objectStore(IDBFS.DB_STORE_NAME); | |
function done(err) { | |
if (err) { | |
if (!done.errored) { | |
done.errored = true; | |
return callback(err); | |
} | |
return; | |
} | |
if (++completed >= total) { | |
return callback(null); | |
} | |
}; | |
transaction.onerror = function() { done(this.error); }; | |
// sort paths in ascending order so directory entries are created | |
// before the files inside them | |
create.sort().forEach(function (path) { | |
if (dst.type === 'local') { | |
IDBFS.loadRemoteEntry(store, path, function (err, entry) { | |
if (err) return done(err); | |
IDBFS.storeLocalEntry(path, entry, done); | |
}); | |
} else { | |
IDBFS.loadLocalEntry(path, function (err, entry) { | |
if (err) return done(err); | |
IDBFS.storeRemoteEntry(store, path, entry, done); | |
}); | |
} | |
}); | |
// sort paths in descending order so files are deleted before their | |
// parent directories | |
remove.sort().reverse().forEach(function(path) { | |
if (dst.type === 'local') { | |
IDBFS.removeLocalEntry(path, done); | |
} else { | |
IDBFS.removeRemoteEntry(store, path, done); | |
} | |
}); | |
}}; | |
var NODEFS={isWindows:false,staticInit:function () { | |
NODEFS.isWindows = !!process.platform.match(/^win/); | |
},mount:function (mount) { | |
assert(ENVIRONMENT_IS_NODE); | |
return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0); | |
},createNode:function (parent, name, mode, dev) { | |
if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
var node = FS.createNode(parent, name, mode); | |
node.node_ops = NODEFS.node_ops; | |
node.stream_ops = NODEFS.stream_ops; | |
return node; | |
},getMode:function (path) { | |
var stat; | |
try { | |
stat = fs.lstatSync(path); | |
if (NODEFS.isWindows) { | |
// On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so | |
// propagate write bits to execute bits. | |
stat.mode = stat.mode | ((stat.mode & 146) >> 1); | |
} | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
return stat.mode; | |
},realPath:function (node) { | |
var parts = []; | |
while (node.parent !== node) { | |
parts.push(node.name); | |
node = node.parent; | |
} | |
parts.push(node.mount.opts.root); | |
parts.reverse(); | |
return PATH.join.apply(null, parts); | |
},flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) { | |
if (flags in NODEFS.flagsToPermissionStringMap) { | |
return NODEFS.flagsToPermissionStringMap[flags]; | |
} else { | |
return flags; | |
} | |
},node_ops:{getattr:function (node) { | |
var path = NODEFS.realPath(node); | |
var stat; | |
try { | |
stat = fs.lstatSync(path); | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
// node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096. | |
// See http://support.microsoft.com/kb/140365 | |
if (NODEFS.isWindows && !stat.blksize) { | |
stat.blksize = 4096; | |
} | |
if (NODEFS.isWindows && !stat.blocks) { | |
stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0; | |
} | |
return { | |
dev: stat.dev, | |
ino: stat.ino, | |
mode: stat.mode, | |
nlink: stat.nlink, | |
uid: stat.uid, | |
gid: stat.gid, | |
rdev: stat.rdev, | |
size: stat.size, | |
atime: stat.atime, | |
mtime: stat.mtime, | |
ctime: stat.ctime, | |
blksize: stat.blksize, | |
blocks: stat.blocks | |
}; | |
},setattr:function (node, attr) { | |
var path = NODEFS.realPath(node); | |
try { | |
if (attr.mode !== undefined) { | |
fs.chmodSync(path, attr.mode); | |
// update the common node structure mode as well | |
node.mode = attr.mode; | |
} | |
if (attr.timestamp !== undefined) { | |
var date = new Date(attr.timestamp); | |
fs.utimesSync(path, date, date); | |
} | |
if (attr.size !== undefined) { | |
fs.truncateSync(path, attr.size); | |
} | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
},lookup:function (parent, name) { | |
var path = PATH.join2(NODEFS.realPath(parent), name); | |
var mode = NODEFS.getMode(path); | |
return NODEFS.createNode(parent, name, mode); | |
},mknod:function (parent, name, mode, dev) { | |
var node = NODEFS.createNode(parent, name, mode, dev); | |
// create the backing node for this in the fs root as well | |
var path = NODEFS.realPath(node); | |
try { | |
if (FS.isDir(node.mode)) { | |
fs.mkdirSync(path, node.mode); | |
} else { | |
fs.writeFileSync(path, '', { mode: node.mode }); | |
} | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
return node; | |
},rename:function (oldNode, newDir, newName) { | |
var oldPath = NODEFS.realPath(oldNode); | |
var newPath = PATH.join2(NODEFS.realPath(newDir), newName); | |
try { | |
fs.renameSync(oldPath, newPath); | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
},unlink:function (parent, name) { | |
var path = PATH.join2(NODEFS.realPath(parent), name); | |
try { | |
fs.unlinkSync(path); | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
},rmdir:function (parent, name) { | |
var path = PATH.join2(NODEFS.realPath(parent), name); | |
try { | |
fs.rmdirSync(path); | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
},readdir:function (node) { | |
var path = NODEFS.realPath(node); | |
try { | |
return fs.readdirSync(path); | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
},symlink:function (parent, newName, oldPath) { | |
var newPath = PATH.join2(NODEFS.realPath(parent), newName); | |
try { | |
fs.symlinkSync(oldPath, newPath); | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
},readlink:function (node) { | |
var path = NODEFS.realPath(node); | |
try { | |
return fs.readlinkSync(path); | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
}},stream_ops:{open:function (stream) { | |
var path = NODEFS.realPath(stream.node); | |
try { | |
if (FS.isFile(stream.node.mode)) { | |
stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags)); | |
} | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
},close:function (stream) { | |
try { | |
if (FS.isFile(stream.node.mode) && stream.nfd) { | |
fs.closeSync(stream.nfd); | |
} | |
} catch (e) { | |
if (!e.code) throw e; | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
},read:function (stream, buffer, offset, length, position) { | |
if (length === 0) return 0; // node errors on 0 length reads | |
// FIXME this is terrible. | |
var nbuffer = new Buffer(length); | |
var res; | |
try { | |
res = fs.readSync(stream.nfd, nbuffer, 0, length, position); | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
if (res > 0) { | |
for (var i = 0; i < res; i++) { | |
buffer[offset + i] = nbuffer[i]; | |
} | |
} | |
return res; | |
},write:function (stream, buffer, offset, length, position) { | |
// FIXME this is terrible. | |
var nbuffer = new Buffer(buffer.subarray(offset, offset + length)); | |
var res; | |
try { | |
res = fs.writeSync(stream.nfd, nbuffer, 0, length, position); | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
return res; | |
},llseek:function (stream, offset, whence) { | |
var position = offset; | |
if (whence === 1) { // SEEK_CUR. | |
position += stream.position; | |
} else if (whence === 2) { // SEEK_END. | |
if (FS.isFile(stream.node.mode)) { | |
try { | |
var stat = fs.fstatSync(stream.nfd); | |
position += stat.size; | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES[e.code]); | |
} | |
} | |
} | |
if (position < 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
return position; | |
}}}; | |
var _stdin=allocate(1, "i32*", ALLOC_STATIC); | |
var _stdout=allocate(1, "i32*", ALLOC_STATIC); | |
var _stderr=allocate(1, "i32*", ALLOC_STATIC); | |
function _fflush(stream) { | |
// int fflush(FILE *stream); | |
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html | |
// we don't currently perform any user-space buffering of data | |
}var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},handleFSError:function (e) { | |
if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace(); | |
return ___setErrNo(e.errno); | |
},lookupPath:function (path, opts) { | |
path = PATH.resolve(FS.cwd(), path); | |
opts = opts || {}; | |
if (!path) return { path: '', node: null }; | |
var defaults = { | |
follow_mount: true, | |
recurse_count: 0 | |
}; | |
for (var key in defaults) { | |
if (opts[key] === undefined) { | |
opts[key] = defaults[key]; | |
} | |
} | |
if (opts.recurse_count > 8) { // max recursive lookup of 8 | |
throw new FS.ErrnoError(ERRNO_CODES.ELOOP); | |
} | |
// split the path | |
var parts = PATH.normalizeArray(path.split('/').filter(function(p) { | |
return !!p; | |
}), false); | |
// start at the root | |
var current = FS.root; | |
var current_path = '/'; | |
for (var i = 0; i < parts.length; i++) { | |
var islast = (i === parts.length-1); | |
if (islast && opts.parent) { | |
// stop resolving | |
break; | |
} | |
current = FS.lookupNode(current, parts[i]); | |
current_path = PATH.join2(current_path, parts[i]); | |
// jump to the mount's root node if this is a mountpoint | |
if (FS.isMountpoint(current)) { | |
if (!islast || (islast && opts.follow_mount)) { | |
current = current.mounted.root; | |
} | |
} | |
// by default, lookupPath will not follow a symlink if it is the final path component. | |
// setting opts.follow = true will override this behavior. | |
if (!islast || opts.follow) { | |
var count = 0; | |
while (FS.isLink(current.mode)) { | |
var link = FS.readlink(current_path); | |
current_path = PATH.resolve(PATH.dirname(current_path), link); | |
var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count }); | |
current = lookup.node; | |
if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX). | |
throw new FS.ErrnoError(ERRNO_CODES.ELOOP); | |
} | |
} | |
} | |
} | |
return { path: current_path, node: current }; | |
},getPath:function (node) { | |
var path; | |
while (true) { | |
if (FS.isRoot(node)) { | |
var mount = node.mount.mountpoint; | |
if (!path) return mount; | |
return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path; | |
} | |
path = path ? node.name + '/' + path : node.name; | |
node = node.parent; | |
} | |
},hashName:function (parentid, name) { | |
var hash = 0; | |
for (var i = 0; i < name.length; i++) { | |
hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0; | |
} | |
return ((parentid + hash) >>> 0) % FS.nameTable.length; | |
},hashAddNode:function (node) { | |
var hash = FS.hashName(node.parent.id, node.name); | |
node.name_next = FS.nameTable[hash]; | |
FS.nameTable[hash] = node; | |
},hashRemoveNode:function (node) { | |
var hash = FS.hashName(node.parent.id, node.name); | |
if (FS.nameTable[hash] === node) { | |
FS.nameTable[hash] = node.name_next; | |
} else { | |
var current = FS.nameTable[hash]; | |
while (current) { | |
if (current.name_next === node) { | |
current.name_next = node.name_next; | |
break; | |
} | |
current = current.name_next; | |
} | |
} | |
},lookupNode:function (parent, name) { | |
var err = FS.mayLookup(parent); | |
if (err) { | |
throw new FS.ErrnoError(err, parent); | |
} | |
var hash = FS.hashName(parent.id, name); | |
for (var node = FS.nameTable[hash]; node; node = node.name_next) { | |
var nodeName = node.name; | |
if (node.parent.id === parent.id && nodeName === name) { | |
return node; | |
} | |
} | |
// if we failed to find it in the cache, call into the VFS | |
return FS.lookup(parent, name); | |
},createNode:function (parent, name, mode, rdev) { | |
if (!FS.FSNode) { | |
FS.FSNode = function(parent, name, mode, rdev) { | |
if (!parent) { | |
parent = this; // root node sets parent to itself | |
} | |
this.parent = parent; | |
this.mount = parent.mount; | |
this.mounted = null; | |
this.id = FS.nextInode++; | |
this.name = name; | |
this.mode = mode; | |
this.node_ops = {}; | |
this.stream_ops = {}; | |
this.rdev = rdev; | |
}; | |
FS.FSNode.prototype = {}; | |
// compatibility | |
var readMode = 292 | 73; | |
var writeMode = 146; | |
// NOTE we must use Object.defineProperties instead of individual calls to | |
// Object.defineProperty in order to make closure compiler happy | |
Object.defineProperties(FS.FSNode.prototype, { | |
read: { | |
get: function() { return (this.mode & readMode) === readMode; }, | |
set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; } | |
}, | |
write: { | |
get: function() { return (this.mode & writeMode) === writeMode; }, | |
set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; } | |
}, | |
isFolder: { | |
get: function() { return FS.isDir(this.mode); }, | |
}, | |
isDevice: { | |
get: function() { return FS.isChrdev(this.mode); }, | |
}, | |
}); | |
} | |
var node = new FS.FSNode(parent, name, mode, rdev); | |
FS.hashAddNode(node); | |
return node; | |
},destroyNode:function (node) { | |
FS.hashRemoveNode(node); | |
},isRoot:function (node) { | |
return node === node.parent; | |
},isMountpoint:function (node) { | |
return !!node.mounted; | |
},isFile:function (mode) { | |
return (mode & 61440) === 32768; | |
},isDir:function (mode) { | |
return (mode & 61440) === 16384; | |
},isLink:function (mode) { | |
return (mode & 61440) === 40960; | |
},isChrdev:function (mode) { | |
return (mode & 61440) === 8192; | |
},isBlkdev:function (mode) { | |
return (mode & 61440) === 24576; | |
},isFIFO:function (mode) { | |
return (mode & 61440) === 4096; | |
},isSocket:function (mode) { | |
return (mode & 49152) === 49152; | |
},flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) { | |
var flags = FS.flagModes[str]; | |
if (typeof flags === 'undefined') { | |
throw new Error('Unknown file open mode: ' + str); | |
} | |
return flags; | |
},flagsToPermissionString:function (flag) { | |
var accmode = flag & 2097155; | |
var perms = ['r', 'w', 'rw'][accmode]; | |
if ((flag & 512)) { | |
perms += 'w'; | |
} | |
return perms; | |
},nodePermissions:function (node, perms) { | |
if (FS.ignorePermissions) { | |
return 0; | |
} | |
// return 0 if any user, group or owner bits are set. | |
if (perms.indexOf('r') !== -1 && !(node.mode & 292)) { | |
return ERRNO_CODES.EACCES; | |
} else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) { | |
return ERRNO_CODES.EACCES; | |
} else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) { | |
return ERRNO_CODES.EACCES; | |
} | |
return 0; | |
},mayLookup:function (dir) { | |
var err = FS.nodePermissions(dir, 'x'); | |
if (err) return err; | |
if (!dir.node_ops.lookup) return ERRNO_CODES.EACCES; | |
return 0; | |
},mayCreate:function (dir, name) { | |
try { | |
var node = FS.lookupNode(dir, name); | |
return ERRNO_CODES.EEXIST; | |
} catch (e) { | |
} | |
return FS.nodePermissions(dir, 'wx'); | |
},mayDelete:function (dir, name, isdir) { | |
var node; | |
try { | |
node = FS.lookupNode(dir, name); | |
} catch (e) { | |
return e.errno; | |
} | |
var err = FS.nodePermissions(dir, 'wx'); | |
if (err) { | |
return err; | |
} | |
if (isdir) { | |
if (!FS.isDir(node.mode)) { | |
return ERRNO_CODES.ENOTDIR; | |
} | |
if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { | |
return ERRNO_CODES.EBUSY; | |
} | |
} else { | |
if (FS.isDir(node.mode)) { | |
return ERRNO_CODES.EISDIR; | |
} | |
} | |
return 0; | |
},mayOpen:function (node, flags) { | |
if (!node) { | |
return ERRNO_CODES.ENOENT; | |
} | |
if (FS.isLink(node.mode)) { | |
return ERRNO_CODES.ELOOP; | |
} else if (FS.isDir(node.mode)) { | |
if ((flags & 2097155) !== 0 || // opening for write | |
(flags & 512)) { | |
return ERRNO_CODES.EISDIR; | |
} | |
} | |
return FS.nodePermissions(node, FS.flagsToPermissionString(flags)); | |
},MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) { | |
fd_start = fd_start || 0; | |
fd_end = fd_end || FS.MAX_OPEN_FDS; | |
for (var fd = fd_start; fd <= fd_end; fd++) { | |
if (!FS.streams[fd]) { | |
return fd; | |
} | |
} | |
throw new FS.ErrnoError(ERRNO_CODES.EMFILE); | |
},getStream:function (fd) { | |
return FS.streams[fd]; | |
},createStream:function (stream, fd_start, fd_end) { | |
if (!FS.FSStream) { | |
FS.FSStream = function(){}; | |
FS.FSStream.prototype = {}; | |
// compatibility | |
Object.defineProperties(FS.FSStream.prototype, { | |
object: { | |
get: function() { return this.node; }, | |
set: function(val) { this.node = val; } | |
}, | |
isRead: { | |
get: function() { return (this.flags & 2097155) !== 1; } | |
}, | |
isWrite: { | |
get: function() { return (this.flags & 2097155) !== 0; } | |
}, | |
isAppend: { | |
get: function() { return (this.flags & 1024); } | |
} | |
}); | |
} | |
// clone it, so we can return an instance of FSStream | |
var newStream = new FS.FSStream(); | |
for (var p in stream) { | |
newStream[p] = stream[p]; | |
} | |
stream = newStream; | |
var fd = FS.nextfd(fd_start, fd_end); | |
stream.fd = fd; | |
FS.streams[fd] = stream; | |
return stream; | |
},closeStream:function (fd) { | |
FS.streams[fd] = null; | |
},getStreamFromPtr:function (ptr) { | |
return FS.streams[ptr - 1]; | |
},getPtrForStream:function (stream) { | |
return stream ? stream.fd + 1 : 0; | |
},chrdev_stream_ops:{open:function (stream) { | |
var device = FS.getDevice(stream.node.rdev); | |
// override node's stream ops with the device's | |
stream.stream_ops = device.stream_ops; | |
// forward the open call | |
if (stream.stream_ops.open) { | |
stream.stream_ops.open(stream); | |
} | |
},llseek:function () { | |
throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); | |
}},major:function (dev) { | |
return ((dev) >> 8); | |
},minor:function (dev) { | |
return ((dev) & 0xff); | |
},makedev:function (ma, mi) { | |
return ((ma) << 8 | (mi)); | |
},registerDevice:function (dev, ops) { | |
FS.devices[dev] = { stream_ops: ops }; | |
},getDevice:function (dev) { | |
return FS.devices[dev]; | |
},getMounts:function (mount) { | |
var mounts = []; | |
var check = [mount]; | |
while (check.length) { | |
var m = check.pop(); | |
mounts.push(m); | |
check.push.apply(check, m.mounts); | |
} | |
return mounts; | |
},syncfs:function (populate, callback) { | |
if (typeof(populate) === 'function') { | |
callback = populate; | |
populate = false; | |
} | |
var mounts = FS.getMounts(FS.root.mount); | |
var completed = 0; | |
function done(err) { | |
if (err) { | |
if (!done.errored) { | |
done.errored = true; | |
return callback(err); | |
} | |
return; | |
} | |
if (++completed >= mounts.length) { | |
callback(null); | |
} | |
}; | |
// sync all mounts | |
mounts.forEach(function (mount) { | |
if (!mount.type.syncfs) { | |
return done(null); | |
} | |
mount.type.syncfs(mount, populate, done); | |
}); | |
},mount:function (type, opts, mountpoint) { | |
var root = mountpoint === '/'; | |
var pseudo = !mountpoint; | |
var node; | |
if (root && FS.root) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBUSY); | |
} else if (!root && !pseudo) { | |
var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); | |
mountpoint = lookup.path; // use the absolute path | |
node = lookup.node; | |
if (FS.isMountpoint(node)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBUSY); | |
} | |
if (!FS.isDir(node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR); | |
} | |
} | |
var mount = { | |
type: type, | |
opts: opts, | |
mountpoint: mountpoint, | |
mounts: [] | |
}; | |
// create a root node for the fs | |
var mountRoot = type.mount(mount); | |
mountRoot.mount = mount; | |
mount.root = mountRoot; | |
if (root) { | |
FS.root = mountRoot; | |
} else if (node) { | |
// set as a mountpoint | |
node.mounted = mount; | |
// add the new mount to the current mount's children | |
if (node.mount) { | |
node.mount.mounts.push(mount); | |
} | |
} | |
return mountRoot; | |
},unmount:function (mountpoint) { | |
var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); | |
if (!FS.isMountpoint(lookup.node)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
// destroy the nodes for this mount, and all its child mounts | |
var node = lookup.node; | |
var mount = node.mounted; | |
var mounts = FS.getMounts(mount); | |
Object.keys(FS.nameTable).forEach(function (hash) { | |
var current = FS.nameTable[hash]; | |
while (current) { | |
var next = current.name_next; | |
if (mounts.indexOf(current.mount) !== -1) { | |
FS.destroyNode(current); | |
} | |
current = next; | |
} | |
}); | |
// no longer a mountpoint | |
node.mounted = null; | |
// remove this mount from the child mounts | |
var idx = node.mount.mounts.indexOf(mount); | |
assert(idx !== -1); | |
node.mount.mounts.splice(idx, 1); | |
},lookup:function (parent, name) { | |
return parent.node_ops.lookup(parent, name); | |
},mknod:function (path, mode, dev) { | |
var lookup = FS.lookupPath(path, { parent: true }); | |
var parent = lookup.node; | |
var name = PATH.basename(path); | |
if (!name || name === '.' || name === '..') { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
var err = FS.mayCreate(parent, name); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
if (!parent.node_ops.mknod) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
return parent.node_ops.mknod(parent, name, mode, dev); | |
},create:function (path, mode) { | |
mode = mode !== undefined ? mode : 438 /* 0666 */; | |
mode &= 4095; | |
mode |= 32768; | |
return FS.mknod(path, mode, 0); | |
},mkdir:function (path, mode) { | |
mode = mode !== undefined ? mode : 511 /* 0777 */; | |
mode &= 511 | 512; | |
mode |= 16384; | |
return FS.mknod(path, mode, 0); | |
},mkdev:function (path, mode, dev) { | |
if (typeof(dev) === 'undefined') { | |
dev = mode; | |
mode = 438 /* 0666 */; | |
} | |
mode |= 8192; | |
return FS.mknod(path, mode, dev); | |
},symlink:function (oldpath, newpath) { | |
if (!PATH.resolve(oldpath)) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOENT); | |
} | |
var lookup = FS.lookupPath(newpath, { parent: true }); | |
var parent = lookup.node; | |
if (!parent) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOENT); | |
} | |
var newname = PATH.basename(newpath); | |
var err = FS.mayCreate(parent, newname); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
if (!parent.node_ops.symlink) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
return parent.node_ops.symlink(parent, newname, oldpath); | |
},rename:function (old_path, new_path) { | |
var old_dirname = PATH.dirname(old_path); | |
var new_dirname = PATH.dirname(new_path); | |
var old_name = PATH.basename(old_path); | |
var new_name = PATH.basename(new_path); | |
// parents must exist | |
var lookup, old_dir, new_dir; | |
try { | |
lookup = FS.lookupPath(old_path, { parent: true }); | |
old_dir = lookup.node; | |
lookup = FS.lookupPath(new_path, { parent: true }); | |
new_dir = lookup.node; | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBUSY); | |
} | |
if (!old_dir || !new_dir) throw new FS.ErrnoError(ERRNO_CODES.ENOENT); | |
// need to be part of the same mount | |
if (old_dir.mount !== new_dir.mount) { | |
throw new FS.ErrnoError(ERRNO_CODES.EXDEV); | |
} | |
// source must exist | |
var old_node = FS.lookupNode(old_dir, old_name); | |
// old path should not be an ancestor of the new path | |
var relative = PATH.relative(old_path, new_dirname); | |
if (relative.charAt(0) !== '.') { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
// new path should not be an ancestor of the old path | |
relative = PATH.relative(new_path, old_dirname); | |
if (relative.charAt(0) !== '.') { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY); | |
} | |
// see if the new path already exists | |
var new_node; | |
try { | |
new_node = FS.lookupNode(new_dir, new_name); | |
} catch (e) { | |
// not fatal | |
} | |
// early out if nothing needs to change | |
if (old_node === new_node) { | |
return; | |
} | |
// we'll need to delete the old entry | |
var isdir = FS.isDir(old_node.mode); | |
var err = FS.mayDelete(old_dir, old_name, isdir); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
// need delete permissions if we'll be overwriting. | |
// need create permissions if new doesn't already exist. | |
err = new_node ? | |
FS.mayDelete(new_dir, new_name, isdir) : | |
FS.mayCreate(new_dir, new_name); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
if (!old_dir.node_ops.rename) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBUSY); | |
} | |
// if we are going to change the parent, check write permissions | |
if (new_dir !== old_dir) { | |
err = FS.nodePermissions(old_dir, 'w'); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
} | |
try { | |
if (FS.trackingDelegate['willMovePath']) { | |
FS.trackingDelegate['willMovePath'](old_path, new_path); | |
} | |
} catch(e) { | |
console.log("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message); | |
} | |
// remove the node from the lookup hash | |
FS.hashRemoveNode(old_node); | |
// do the underlying fs rename | |
try { | |
old_dir.node_ops.rename(old_node, new_dir, new_name); | |
} catch (e) { | |
throw e; | |
} finally { | |
// add the node back to the hash (in case node_ops.rename | |
// changed its name) | |
FS.hashAddNode(old_node); | |
} | |
try { | |
if (FS.trackingDelegate['onMovePath']) FS.trackingDelegate['onMovePath'](old_path, new_path); | |
} catch(e) { | |
console.log("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message); | |
} | |
},rmdir:function (path) { | |
var lookup = FS.lookupPath(path, { parent: true }); | |
var parent = lookup.node; | |
var name = PATH.basename(path); | |
var node = FS.lookupNode(parent, name); | |
var err = FS.mayDelete(parent, name, true); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
if (!parent.node_ops.rmdir) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
if (FS.isMountpoint(node)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBUSY); | |
} | |
try { | |
if (FS.trackingDelegate['willDeletePath']) { | |
FS.trackingDelegate['willDeletePath'](path); | |
} | |
} catch(e) { | |
console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message); | |
} | |
parent.node_ops.rmdir(parent, name); | |
FS.destroyNode(node); | |
try { | |
if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path); | |
} catch(e) { | |
console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message); | |
} | |
},readdir:function (path) { | |
var lookup = FS.lookupPath(path, { follow: true }); | |
var node = lookup.node; | |
if (!node.node_ops.readdir) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR); | |
} | |
return node.node_ops.readdir(node); | |
},unlink:function (path) { | |
var lookup = FS.lookupPath(path, { parent: true }); | |
var parent = lookup.node; | |
var name = PATH.basename(path); | |
var node = FS.lookupNode(parent, name); | |
var err = FS.mayDelete(parent, name, false); | |
if (err) { | |
// POSIX says unlink should set EPERM, not EISDIR | |
if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM; | |
throw new FS.ErrnoError(err); | |
} | |
if (!parent.node_ops.unlink) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
if (FS.isMountpoint(node)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBUSY); | |
} | |
try { | |
if (FS.trackingDelegate['willDeletePath']) { | |
FS.trackingDelegate['willDeletePath'](path); | |
} | |
} catch(e) { | |
console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message); | |
} | |
parent.node_ops.unlink(parent, name); | |
FS.destroyNode(node); | |
try { | |
if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path); | |
} catch(e) { | |
console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message); | |
} | |
},readlink:function (path) { | |
var lookup = FS.lookupPath(path); | |
var link = lookup.node; | |
if (!link) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOENT); | |
} | |
if (!link.node_ops.readlink) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
return link.node_ops.readlink(link); | |
},stat:function (path, dontFollow) { | |
var lookup = FS.lookupPath(path, { follow: !dontFollow }); | |
var node = lookup.node; | |
if (!node) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOENT); | |
} | |
if (!node.node_ops.getattr) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
return node.node_ops.getattr(node); | |
},lstat:function (path) { | |
return FS.stat(path, true); | |
},chmod:function (path, mode, dontFollow) { | |
var node; | |
if (typeof path === 'string') { | |
var lookup = FS.lookupPath(path, { follow: !dontFollow }); | |
node = lookup.node; | |
} else { | |
node = path; | |
} | |
if (!node.node_ops.setattr) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
node.node_ops.setattr(node, { | |
mode: (mode & 4095) | (node.mode & ~4095), | |
timestamp: Date.now() | |
}); | |
},lchmod:function (path, mode) { | |
FS.chmod(path, mode, true); | |
},fchmod:function (fd, mode) { | |
var stream = FS.getStream(fd); | |
if (!stream) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
FS.chmod(stream.node, mode); | |
},chown:function (path, uid, gid, dontFollow) { | |
var node; | |
if (typeof path === 'string') { | |
var lookup = FS.lookupPath(path, { follow: !dontFollow }); | |
node = lookup.node; | |
} else { | |
node = path; | |
} | |
if (!node.node_ops.setattr) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
node.node_ops.setattr(node, { | |
timestamp: Date.now() | |
// we ignore the uid / gid for now | |
}); | |
},lchown:function (path, uid, gid) { | |
FS.chown(path, uid, gid, true); | |
},fchown:function (fd, uid, gid) { | |
var stream = FS.getStream(fd); | |
if (!stream) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
FS.chown(stream.node, uid, gid); | |
},truncate:function (path, len) { | |
if (len < 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
var node; | |
if (typeof path === 'string') { | |
var lookup = FS.lookupPath(path, { follow: true }); | |
node = lookup.node; | |
} else { | |
node = path; | |
} | |
if (!node.node_ops.setattr) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
if (FS.isDir(node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EISDIR); | |
} | |
if (!FS.isFile(node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
var err = FS.nodePermissions(node, 'w'); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
node.node_ops.setattr(node, { | |
size: len, | |
timestamp: Date.now() | |
}); | |
},ftruncate:function (fd, len) { | |
var stream = FS.getStream(fd); | |
if (!stream) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
if ((stream.flags & 2097155) === 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
FS.truncate(stream.node, len); | |
},utime:function (path, atime, mtime) { | |
var lookup = FS.lookupPath(path, { follow: true }); | |
var node = lookup.node; | |
node.node_ops.setattr(node, { | |
timestamp: Math.max(atime, mtime) | |
}); | |
},open:function (path, flags, mode, fd_start, fd_end) { | |
if (path === "") { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOENT); | |
} | |
flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags; | |
mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode; | |
if ((flags & 64)) { | |
mode = (mode & 4095) | 32768; | |
} else { | |
mode = 0; | |
} | |
var node; | |
if (typeof path === 'object') { | |
node = path; | |
} else { | |
path = PATH.normalize(path); | |
try { | |
var lookup = FS.lookupPath(path, { | |
follow: !(flags & 131072) | |
}); | |
node = lookup.node; | |
} catch (e) { | |
// ignore | |
} | |
} | |
// perhaps we need to create the node | |
var created = false; | |
if ((flags & 64)) { | |
if (node) { | |
// if O_CREAT and O_EXCL are set, error out if the node already exists | |
if ((flags & 128)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EEXIST); | |
} | |
} else { | |
// node doesn't exist, try to create it | |
node = FS.mknod(path, mode, 0); | |
created = true; | |
} | |
} | |
if (!node) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOENT); | |
} | |
// can't truncate a device | |
if (FS.isChrdev(node.mode)) { | |
flags &= ~512; | |
} | |
// check permissions, if this is not a file we just created now (it is ok to | |
// create and write to a file with read-only permissions; it is read-only | |
// for later use) | |
if (!created) { | |
var err = FS.mayOpen(node, flags); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
} | |
// do truncation if necessary | |
if ((flags & 512)) { | |
FS.truncate(node, 0); | |
} | |
// we've already handled these, don't pass down to the underlying vfs | |
flags &= ~(128 | 512); | |
// register the stream with the filesystem | |
var stream = FS.createStream({ | |
node: node, | |
path: FS.getPath(node), // we want the absolute path to the node | |
flags: flags, | |
seekable: true, | |
position: 0, | |
stream_ops: node.stream_ops, | |
// used by the file family libc calls (fopen, fwrite, ferror, etc.) | |
ungotten: [], | |
error: false | |
}, fd_start, fd_end); | |
// call the new stream's open function | |
if (stream.stream_ops.open) { | |
stream.stream_ops.open(stream); | |
} | |
if (Module['logReadFiles'] && !(flags & 1)) { | |
if (!FS.readFiles) FS.readFiles = {}; | |
if (!(path in FS.readFiles)) { | |
FS.readFiles[path] = 1; | |
Module['printErr']('read file: ' + path); | |
} | |
} | |
try { | |
if (FS.trackingDelegate['onOpenFile']) { | |
var trackingFlags = 0; | |
if ((flags & 2097155) !== 1) { | |
trackingFlags |= FS.tracking.openFlags.READ; | |
} | |
if ((flags & 2097155) !== 0) { | |
trackingFlags |= FS.tracking.openFlags.WRITE; | |
} | |
FS.trackingDelegate['onOpenFile'](path, trackingFlags); | |
} | |
} catch(e) { | |
console.log("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: " + e.message); | |
} | |
return stream; | |
},close:function (stream) { | |
try { | |
if (stream.stream_ops.close) { | |
stream.stream_ops.close(stream); | |
} | |
} catch (e) { | |
throw e; | |
} finally { | |
FS.closeStream(stream.fd); | |
} | |
},llseek:function (stream, offset, whence) { | |
if (!stream.seekable || !stream.stream_ops.llseek) { | |
throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); | |
} | |
stream.position = stream.stream_ops.llseek(stream, offset, whence); | |
stream.ungotten = []; | |
return stream.position; | |
},read:function (stream, buffer, offset, length, position) { | |
if (length < 0 || position < 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
if ((stream.flags & 2097155) === 1) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
if (FS.isDir(stream.node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EISDIR); | |
} | |
if (!stream.stream_ops.read) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
var seeking = true; | |
if (typeof position === 'undefined') { | |
position = stream.position; | |
seeking = false; | |
} else if (!stream.seekable) { | |
throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); | |
} | |
var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); | |
if (!seeking) stream.position += bytesRead; | |
return bytesRead; | |
},write:function (stream, buffer, offset, length, position, canOwn) { | |
if (length < 0 || position < 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
if ((stream.flags & 2097155) === 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
if (FS.isDir(stream.node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EISDIR); | |
} | |
if (!stream.stream_ops.write) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
if (stream.flags & 1024) { | |
// seek to the end before writing in append mode | |
FS.llseek(stream, 0, 2); | |
} | |
var seeking = true; | |
if (typeof position === 'undefined') { | |
position = stream.position; | |
seeking = false; | |
} else if (!stream.seekable) { | |
throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); | |
} | |
var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); | |
if (!seeking) stream.position += bytesWritten; | |
try { | |
if (stream.path && FS.trackingDelegate['onWriteToFile']) FS.trackingDelegate['onWriteToFile'](stream.path); | |
} catch(e) { | |
console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: " + e.message); | |
} | |
return bytesWritten; | |
},allocate:function (stream, offset, length) { | |
if (offset < 0 || length <= 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
if ((stream.flags & 2097155) === 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENODEV); | |
} | |
if (!stream.stream_ops.allocate) { | |
throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP); | |
} | |
stream.stream_ops.allocate(stream, offset, length); | |
},mmap:function (stream, buffer, offset, length, position, prot, flags) { | |
// TODO if PROT is PROT_WRITE, make sure we have write access | |
if ((stream.flags & 2097155) === 1) { | |
throw new FS.ErrnoError(ERRNO_CODES.EACCES); | |
} | |
if (!stream.stream_ops.mmap) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENODEV); | |
} | |
return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags); | |
},ioctl:function (stream, cmd, arg) { | |
if (!stream.stream_ops.ioctl) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTTY); | |
} | |
return stream.stream_ops.ioctl(stream, cmd, arg); | |
},readFile:function (path, opts) { | |
opts = opts || {}; | |
opts.flags = opts.flags || 'r'; | |
opts.encoding = opts.encoding || 'binary'; | |
if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') { | |
throw new Error('Invalid encoding type "' + opts.encoding + '"'); | |
} | |
var ret; | |
var stream = FS.open(path, opts.flags); | |
var stat = FS.stat(path); | |
var length = stat.size; | |
var buf = new Uint8Array(length); | |
FS.read(stream, buf, 0, length, 0); | |
if (opts.encoding === 'utf8') { | |
ret = ''; | |
var utf8 = new Runtime.UTF8Processor(); | |
for (var i = 0; i < length; i++) { | |
ret += utf8.processCChar(buf[i]); | |
} | |
} else if (opts.encoding === 'binary') { | |
ret = buf; | |
} | |
FS.close(stream); | |
return ret; | |
},writeFile:function (path, data, opts) { | |
opts = opts || {}; | |
opts.flags = opts.flags || 'w'; | |
opts.encoding = opts.encoding || 'utf8'; | |
if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') { | |
throw new Error('Invalid encoding type "' + opts.encoding + '"'); | |
} | |
var stream = FS.open(path, opts.flags, opts.mode); | |
if (opts.encoding === 'utf8') { | |
var utf8 = new Runtime.UTF8Processor(); | |
var buf = new Uint8Array(utf8.processJSString(data)); | |
FS.write(stream, buf, 0, buf.length, 0, opts.canOwn); | |
} else if (opts.encoding === 'binary') { | |
FS.write(stream, data, 0, data.length, 0, opts.canOwn); | |
} | |
FS.close(stream); | |
},cwd:function () { | |
return FS.currentPath; | |
},chdir:function (path) { | |
var lookup = FS.lookupPath(path, { follow: true }); | |
if (!FS.isDir(lookup.node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR); | |
} | |
var err = FS.nodePermissions(lookup.node, 'x'); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
FS.currentPath = lookup.path; | |
},createDefaultDirectories:function () { | |
FS.mkdir('/tmp'); | |
FS.mkdir('/home'); | |
FS.mkdir('/home/web_user'); | |
},createDefaultDevices:function () { | |
// create /dev | |
FS.mkdir('/dev'); | |
// setup /dev/null | |
FS.registerDevice(FS.makedev(1, 3), { | |
read: function() { return 0; }, | |
write: function() { return 0; } | |
}); | |
FS.mkdev('/dev/null', FS.makedev(1, 3)); | |
// setup /dev/tty and /dev/tty1 | |
// stderr needs to print output using Module['printErr'] | |
// so we register a second tty just for it. | |
TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); | |
TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); | |
FS.mkdev('/dev/tty', FS.makedev(5, 0)); | |
FS.mkdev('/dev/tty1', FS.makedev(6, 0)); | |
// setup /dev/[u]random | |
var random_device; | |
if (typeof crypto !== 'undefined') { | |
// for modern web browsers | |
var randomBuffer = new Uint8Array(1); | |
random_device = function() { crypto.getRandomValues(randomBuffer); return randomBuffer[0]; }; | |
} else if (ENVIRONMENT_IS_NODE) { | |
// for nodejs | |
random_device = function() { return require('crypto').randomBytes(1)[0]; }; | |
} else { | |
// default for ES5 platforms | |
random_device = function() { return (Math.random()*256)|0; }; | |
} | |
FS.createDevice('/dev', 'random', random_device); | |
FS.createDevice('/dev', 'urandom', random_device); | |
// we're not going to emulate the actual shm device, | |
// just create the tmp dirs that reside in it commonly | |
FS.mkdir('/dev/shm'); | |
FS.mkdir('/dev/shm/tmp'); | |
},createStandardStreams:function () { | |
// TODO deprecate the old functionality of a single | |
// input / output callback and that utilizes FS.createDevice | |
// and instead require a unique set of stream ops | |
// by default, we symlink the standard streams to the | |
// default tty devices. however, if the standard streams | |
// have been overwritten we create a unique device for | |
// them instead. | |
if (Module['stdin']) { | |
FS.createDevice('/dev', 'stdin', Module['stdin']); | |
} else { | |
FS.symlink('/dev/tty', '/dev/stdin'); | |
} | |
if (Module['stdout']) { | |
FS.createDevice('/dev', 'stdout', null, Module['stdout']); | |
} else { | |
FS.symlink('/dev/tty', '/dev/stdout'); | |
} | |
if (Module['stderr']) { | |
FS.createDevice('/dev', 'stderr', null, Module['stderr']); | |
} else { | |
FS.symlink('/dev/tty1', '/dev/stderr'); | |
} | |
// open default streams for the stdin, stdout and stderr devices | |
var stdin = FS.open('/dev/stdin', 'r'); | |
HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin); | |
assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')'); | |
var stdout = FS.open('/dev/stdout', 'w'); | |
HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout); | |
assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')'); | |
var stderr = FS.open('/dev/stderr', 'w'); | |
HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr); | |
assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')'); | |
},ensureErrnoError:function () { | |
if (FS.ErrnoError) return; | |
FS.ErrnoError = function ErrnoError(errno, node) { | |
this.node = node; | |
this.setErrno = function(errno) { | |
this.errno = errno; | |
for (var key in ERRNO_CODES) { | |
if (ERRNO_CODES[key] === errno) { | |
this.code = key; | |
break; | |
} | |
} | |
}; | |
this.setErrno(errno); | |
this.message = ERRNO_MESSAGES[errno]; | |
if (this.stack) this.stack = demangleAll(this.stack); | |
}; | |
FS.ErrnoError.prototype = new Error(); | |
FS.ErrnoError.prototype.constructor = FS.ErrnoError; | |
// Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info) | |
[ERRNO_CODES.ENOENT].forEach(function(code) { | |
FS.genericErrors[code] = new FS.ErrnoError(code); | |
FS.genericErrors[code].stack = '<generic error, no stack>'; | |
}); | |
},staticInit:function () { | |
FS.ensureErrnoError(); | |
FS.nameTable = new Array(4096); | |
FS.mount(MEMFS, {}, '/'); | |
FS.createDefaultDirectories(); | |
FS.createDefaultDevices(); | |
},init:function (input, output, error) { | |
assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)'); | |
FS.init.initialized = true; | |
FS.ensureErrnoError(); | |
// Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here | |
Module['stdin'] = input || Module['stdin']; | |
Module['stdout'] = output || Module['stdout']; | |
Module['stderr'] = error || Module['stderr']; | |
FS.createStandardStreams(); | |
},quit:function () { | |
FS.init.initialized = false; | |
for (var i = 0; i < FS.streams.length; i++) { | |
var stream = FS.streams[i]; | |
if (!stream) { | |
continue; | |
} | |
FS.close(stream); | |
} | |
},getMode:function (canRead, canWrite) { | |
var mode = 0; | |
if (canRead) mode |= 292 | 73; | |
if (canWrite) mode |= 146; | |
return mode; | |
},joinPath:function (parts, forceRelative) { | |
var path = PATH.join.apply(null, parts); | |
if (forceRelative && path[0] == '/') path = path.substr(1); | |
return path; | |
},absolutePath:function (relative, base) { | |
return PATH.resolve(base, relative); | |
},standardizePath:function (path) { | |
return PATH.normalize(path); | |
},findObject:function (path, dontResolveLastLink) { | |
var ret = FS.analyzePath(path, dontResolveLastLink); | |
if (ret.exists) { | |
return ret.object; | |
} else { | |
___setErrNo(ret.error); | |
return null; | |
} | |
},analyzePath:function (path, dontResolveLastLink) { | |
// operate from within the context of the symlink's target | |
try { | |
var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); | |
path = lookup.path; | |
} catch (e) { | |
} | |
var ret = { | |
isRoot: false, exists: false, error: 0, name: null, path: null, object: null, | |
parentExists: false, parentPath: null, parentObject: null | |
}; | |
try { | |
var lookup = FS.lookupPath(path, { parent: true }); | |
ret.parentExists = true; | |
ret.parentPath = lookup.path; | |
ret.parentObject = lookup.node; | |
ret.name = PATH.basename(path); | |
lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); | |
ret.exists = true; | |
ret.path = lookup.path; | |
ret.object = lookup.node; | |
ret.name = lookup.node.name; | |
ret.isRoot = lookup.path === '/'; | |
} catch (e) { | |
ret.error = e.errno; | |
}; | |
return ret; | |
},createFolder:function (parent, name, canRead, canWrite) { | |
var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); | |
var mode = FS.getMode(canRead, canWrite); | |
return FS.mkdir(path, mode); | |
},createPath:function (parent, path, canRead, canWrite) { | |
parent = typeof parent === 'string' ? parent : FS.getPath(parent); | |
var parts = path.split('/').reverse(); | |
while (parts.length) { | |
var part = parts.pop(); | |
if (!part) continue; | |
var current = PATH.join2(parent, part); | |
try { | |
FS.mkdir(current); | |
} catch (e) { | |
// ignore EEXIST | |
} | |
parent = current; | |
} | |
return current; | |
},createFile:function (parent, name, properties, canRead, canWrite) { | |
var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); | |
var mode = FS.getMode(canRead, canWrite); | |
return FS.create(path, mode); | |
},createDataFile:function (parent, name, data, canRead, canWrite, canOwn) { | |
var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent; | |
var mode = FS.getMode(canRead, canWrite); | |
var node = FS.create(path, mode); | |
if (data) { | |
if (typeof data === 'string') { | |
var arr = new Array(data.length); | |
for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i); | |
data = arr; | |
} | |
// make sure we can write to the file | |
FS.chmod(node, mode | 146); | |
var stream = FS.open(node, 'w'); | |
FS.write(stream, data, 0, data.length, 0, canOwn); | |
FS.close(stream); | |
FS.chmod(node, mode); | |
} | |
return node; | |
},createDevice:function (parent, name, input, output) { | |
var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); | |
var mode = FS.getMode(!!input, !!output); | |
if (!FS.createDevice.major) FS.createDevice.major = 64; | |
var dev = FS.makedev(FS.createDevice.major++, 0); | |
// Create a fake device that a set of stream ops to emulate | |
// the old behavior. | |
FS.registerDevice(dev, { | |
open: function(stream) { | |
stream.seekable = false; | |
}, | |
close: function(stream) { | |
// flush any pending line data | |
if (output && output.buffer && output.buffer.length) { | |
output(10); | |
} | |
}, | |
read: function(stream, buffer, offset, length, pos /* ignored */) { | |
var bytesRead = 0; | |
for (var i = 0; i < length; i++) { | |
var result; | |
try { | |
result = input(); | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
if (result === undefined && bytesRead === 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EAGAIN); | |
} | |
if (result === null || result === undefined) break; | |
bytesRead++; | |
buffer[offset+i] = result; | |
} | |
if (bytesRead) { | |
stream.node.timestamp = Date.now(); | |
} | |
return bytesRead; | |
}, | |
write: function(stream, buffer, offset, length, pos) { | |
for (var i = 0; i < length; i++) { | |
try { | |
output(buffer[offset+i]); | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
} | |
if (length) { | |
stream.node.timestamp = Date.now(); | |
} | |
return i; | |
} | |
}); | |
return FS.mkdev(path, mode, dev); | |
},createLink:function (parent, name, target, canRead, canWrite) { | |
var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); | |
return FS.symlink(target, path); | |
},forceLoadFile:function (obj) { | |
if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; | |
var success = true; | |
if (typeof XMLHttpRequest !== 'undefined') { | |
throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread."); | |
} else if (Module['read']) { | |
// Command-line. | |
try { | |
// WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as | |
// read() will try to parse UTF8. | |
obj.contents = intArrayFromString(Module['read'](obj.url), true); | |
obj.usedBytes = obj.contents.length; | |
} catch (e) { | |
success = false; | |
} | |
} else { | |
throw new Error('Cannot load without read() or XMLHttpRequest.'); | |
} | |
if (!success) ___setErrNo(ERRNO_CODES.EIO); | |
return success; | |
},createLazyFile:function (parent, name, url, canRead, canWrite) { | |
// Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse. | |
function LazyUint8Array() { | |
this.lengthKnown = false; | |
this.chunks = []; // Loaded chunks. Index is the chunk number | |
} | |
LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) { | |
if (idx > this.length-1 || idx < 0) { | |
return undefined; | |
} | |
var chunkOffset = idx % this.chunkSize; | |
var chunkNum = (idx / this.chunkSize)|0; | |
return this.getter(chunkNum)[chunkOffset]; | |
} | |
LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) { | |
this.getter = getter; | |
} | |
LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() { | |
// Find length | |
var xhr = new XMLHttpRequest(); | |
xhr.open('HEAD', url, false); | |
xhr.send(null); | |
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); | |
var datalength = Number(xhr.getResponseHeader("Content-length")); | |
var header; | |
var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; | |
var chunkSize = 1024*1024; // Chunk size in bytes | |
if (!hasByteServing) chunkSize = datalength; | |
// Function to get a range from the remote URL. | |
var doXHR = (function(from, to) { | |
if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); | |
if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!"); | |
// TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. | |
var xhr = new XMLHttpRequest(); | |
xhr.open('GET', url, false); | |
if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); | |
// Some hints to the browser that we want binary data. | |
if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer'; | |
if (xhr.overrideMimeType) { | |
xhr.overrideMimeType('text/plain; charset=x-user-defined'); | |
} | |
xhr.send(null); | |
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); | |
if (xhr.response !== undefined) { | |
return new Uint8Array(xhr.response || []); | |
} else { | |
return intArrayFromString(xhr.responseText || '', true); | |
} | |
}); | |
var lazyArray = this; | |
lazyArray.setDataGetter(function(chunkNum) { | |
var start = chunkNum * chunkSize; | |
var end = (chunkNum+1) * chunkSize - 1; // including this byte | |
end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block | |
if (typeof(lazyArray.chunks[chunkNum]) === "undefined") { | |
lazyArray.chunks[chunkNum] = doXHR(start, end); | |
} | |
if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!"); | |
return lazyArray.chunks[chunkNum]; | |
}); | |
this._length = datalength; | |
this._chunkSize = chunkSize; | |
this.lengthKnown = true; | |
} | |
if (typeof XMLHttpRequest !== 'undefined') { | |
if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'; | |
var lazyArray = new LazyUint8Array(); | |
Object.defineProperty(lazyArray, "length", { | |
get: function() { | |
if(!this.lengthKnown) { | |
this.cacheLength(); | |
} | |
return this._length; | |
} | |
}); | |
Object.defineProperty(lazyArray, "chunkSize", { | |
get: function() { | |
if(!this.lengthKnown) { | |
this.cacheLength(); | |
} | |
return this._chunkSize; | |
} | |
}); | |
var properties = { isDevice: false, contents: lazyArray }; | |
} else { | |
var properties = { isDevice: false, url: url }; | |
} | |
var node = FS.createFile(parent, name, properties, canRead, canWrite); | |
// This is a total hack, but I want to get this lazy file code out of the | |
// core of MEMFS. If we want to keep this lazy file concept I feel it should | |
// be its own thin LAZYFS proxying calls to MEMFS. | |
if (properties.contents) { | |
node.contents = properties.contents; | |
} else if (properties.url) { | |
node.contents = null; | |
node.url = properties.url; | |
} | |
// Add a function that defers querying the file size until it is asked the first time. | |
Object.defineProperty(node, "usedBytes", { | |
get: function() { return this.contents.length; } | |
}); | |
// override each stream op with one that tries to force load the lazy file first | |
var stream_ops = {}; | |
var keys = Object.keys(node.stream_ops); | |
keys.forEach(function(key) { | |
var fn = node.stream_ops[key]; | |
stream_ops[key] = function forceLoadLazyFile() { | |
if (!FS.forceLoadFile(node)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
return fn.apply(null, arguments); | |
}; | |
}); | |
// use a custom read function | |
stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) { | |
if (!FS.forceLoadFile(node)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
var contents = stream.node.contents; | |
if (position >= contents.length) | |
return 0; | |
var size = Math.min(contents.length - position, length); | |
assert(size >= 0); | |
if (contents.slice) { // normal array | |
for (var i = 0; i < size; i++) { | |
buffer[offset + i] = contents[position + i]; | |
} | |
} else { | |
for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR | |
buffer[offset + i] = contents.get(position + i); | |
} | |
} | |
return size; | |
}; | |
node.stream_ops = stream_ops; | |
return node; | |
},createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) { | |
Browser.init(); | |
// TODO we should allow people to just pass in a complete filename instead | |
// of parent and name being that we just join them anyways | |
var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent; | |
function processData(byteArray) { | |
function finish(byteArray) { | |
if (!dontCreateFile) { | |
FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn); | |
} | |
if (onload) onload(); | |
removeRunDependency('cp ' + fullname); | |
} | |
var handled = false; | |
Module['preloadPlugins'].forEach(function(plugin) { | |
if (handled) return; | |
if (plugin['canHandle'](fullname)) { | |
plugin['handle'](byteArray, fullname, finish, function() { | |
if (onerror) onerror(); | |
removeRunDependency('cp ' + fullname); | |
}); | |
handled = true; | |
} | |
}); | |
if (!handled) finish(byteArray); | |
} | |
addRunDependency('cp ' + fullname); | |
if (typeof url == 'string') { | |
Browser.asyncLoad(url, function(byteArray) { | |
processData(byteArray); | |
}, onerror); | |
} else { | |
processData(url); | |
} | |
},indexedDB:function () { | |
return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; | |
},DB_NAME:function () { | |
return 'EM_FS_' + window.location.pathname; | |
},DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) { | |
onload = onload || function(){}; | |
onerror = onerror || function(){}; | |
var indexedDB = FS.indexedDB(); | |
try { | |
var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION); | |
} catch (e) { | |
return onerror(e); | |
} | |
openRequest.onupgradeneeded = function openRequest_onupgradeneeded() { | |
console.log('creating db'); | |
var db = openRequest.result; | |
db.createObjectStore(FS.DB_STORE_NAME); | |
}; | |
openRequest.onsuccess = function openRequest_onsuccess() { | |
var db = openRequest.result; | |
var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite'); | |
var files = transaction.objectStore(FS.DB_STORE_NAME); | |
var ok = 0, fail = 0, total = paths.length; | |
function finish() { | |
if (fail == 0) onload(); else onerror(); | |
} | |
paths.forEach(function(path) { | |
var putRequest = files.put(FS.analyzePath(path).object.contents, path); | |
putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() }; | |
putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() }; | |
}); | |
transaction.onerror = onerror; | |
}; | |
openRequest.onerror = onerror; | |
},loadFilesFromDB:function (paths, onload, onerror) { | |
onload = onload || function(){}; | |
onerror = onerror || function(){}; | |
var indexedDB = FS.indexedDB(); | |
try { | |
var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION); | |
} catch (e) { | |
return onerror(e); | |
} | |
openRequest.onupgradeneeded = onerror; // no database to load from | |
openRequest.onsuccess = function openRequest_onsuccess() { | |
var db = openRequest.result; | |
try { | |
var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly'); | |
} catch(e) { | |
onerror(e); | |
return; | |
} | |
var files = transaction.objectStore(FS.DB_STORE_NAME); | |
var ok = 0, fail = 0, total = paths.length; | |
function finish() { | |
if (fail == 0) onload(); else onerror(); | |
} | |
paths.forEach(function(path) { | |
var getRequest = files.get(path); | |
getRequest.onsuccess = function getRequest_onsuccess() { | |
if (FS.analyzePath(path).exists) { | |
FS.unlink(path); | |
} | |
FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true); | |
ok++; | |
if (ok + fail == total) finish(); | |
}; | |
getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() }; | |
}); | |
transaction.onerror = onerror; | |
}; | |
openRequest.onerror = onerror; | |
}}; | |
function _emscripten_set_main_loop_timing(mode, value) { | |
Browser.mainLoop.timingMode = mode; | |
Browser.mainLoop.timingValue = value; | |
if (!Browser.mainLoop.func) { | |
console.error('emscripten_set_main_loop_timing: Cannot set timing mode for main loop since a main loop does not exist! Call emscripten_set_main_loop first to set one up.'); | |
return 1; // Return non-zero on failure, can't set timing mode when there is no main loop. | |
} | |
if (mode == 0 /*EM_TIMING_SETTIMEOUT*/) { | |
Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler() { | |
setTimeout(Browser.mainLoop.runner, value); // doing this each time means that on exception, we stop | |
}; | |
Browser.mainLoop.method = 'timeout'; | |
} else if (mode == 1 /*EM_TIMING_RAF*/) { | |
Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler() { | |
Browser.requestAnimationFrame(Browser.mainLoop.runner); | |
}; | |
Browser.mainLoop.method = 'rAF'; | |
} | |
return 0; | |
}function _emscripten_set_main_loop(func, fps, simulateInfiniteLoop, arg) { | |
Module['noExitRuntime'] = true; | |
assert(!Browser.mainLoop.func, 'emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.'); | |
Browser.mainLoop.func = func; | |
Browser.mainLoop.arg = arg; | |
var thisMainLoopId = Browser.mainLoop.currentlyRunningMainloop; | |
Browser.mainLoop.runner = function Browser_mainLoop_runner() { | |
if (ABORT) return; | |
if (Browser.mainLoop.queue.length > 0) { | |
var start = Date.now(); | |
var blocker = Browser.mainLoop.queue.shift(); | |
blocker.func(blocker.arg); | |
if (Browser.mainLoop.remainingBlockers) { | |
var remaining = Browser.mainLoop.remainingBlockers; | |
var next = remaining%1 == 0 ? remaining-1 : Math.floor(remaining); | |
if (blocker.counted) { | |
Browser.mainLoop.remainingBlockers = next; | |
} else { | |
// not counted, but move the progress along a tiny bit | |
next = next + 0.5; // do not steal all the next one's progress | |
Browser.mainLoop.remainingBlockers = (8*remaining + next)/9; | |
} | |
} | |
console.log('main loop blocker "' + blocker.name + '" took ' + (Date.now() - start) + ' ms'); //, left: ' + Browser.mainLoop.remainingBlockers); | |
Browser.mainLoop.updateStatus(); | |
setTimeout(Browser.mainLoop.runner, 0); | |
return; | |
} | |
// catch pauses from non-main loop sources | |
if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return; | |
// Implement very basic swap interval control | |
Browser.mainLoop.currentFrameNumber = Browser.mainLoop.currentFrameNumber + 1 | 0; | |
if (Browser.mainLoop.timingMode == 1/*EM_TIMING_RAF*/ && Browser.mainLoop.timingValue > 1 && Browser.mainLoop.currentFrameNumber % Browser.mainLoop.timingValue != 0) { | |
// Not the scheduled time to render this frame - skip. | |
Browser.mainLoop.scheduler(); | |
return; | |
} | |
// Signal GL rendering layer that processing of a new frame is about to start. This helps it optimize | |
// VBO double-buffering and reduce GPU stalls. | |
if (Browser.mainLoop.method === 'timeout' && Module.ctx) { | |
Module.printErr('Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!'); | |
Browser.mainLoop.method = ''; // just warn once per call to set main loop | |
} | |
Browser.mainLoop.runIter(function() { | |
if (typeof arg !== 'undefined') { | |
Runtime.dynCall('vi', func, [arg]); | |
} else { | |
Runtime.dynCall('v', func); | |
} | |
}); | |
// catch pauses from the main loop itself | |
if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return; | |
// Queue new audio data. This is important to be right after the main loop invocation, so that we will immediately be able | |
// to queue the newest produced audio samples. | |
// TODO: Consider adding pre- and post- rAF callbacks so that GL.newRenderingFrameStarted() and SDL.audio.queueNewAudioData() | |
// do not need to be hardcoded into this function, but can be more generic. | |
if (typeof SDL === 'object' && SDL.audio && SDL.audio.queueNewAudioData) SDL.audio.queueNewAudioData(); | |
Browser.mainLoop.scheduler(); | |
} | |
if (fps && fps > 0) _emscripten_set_main_loop_timing(0/*EM_TIMING_SETTIMEOUT*/, 1000.0 / fps); | |
else _emscripten_set_main_loop_timing(1/*EM_TIMING_RAF*/, 1); // Do rAF by rendering each frame (no decimating) | |
Browser.mainLoop.scheduler(); | |
if (simulateInfiniteLoop) { | |
throw 'SimulateInfiniteLoop'; | |
} | |
}var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function () { | |
Browser.mainLoop.scheduler = null; | |
Browser.mainLoop.currentlyRunningMainloop++; // Incrementing this signals the previous main loop that it's now become old, and it must return. | |
},resume:function () { | |
Browser.mainLoop.currentlyRunningMainloop++; | |
var timingMode = Browser.mainLoop.timingMode; | |
var timingValue = Browser.mainLoop.timingValue; | |
var func = Browser.mainLoop.func; | |
Browser.mainLoop.func = null; | |
_emscripten_set_main_loop(func, 0, false, Browser.mainLoop.arg); | |
_emscripten_set_main_loop_timing(timingMode, timingValue); | |
},updateStatus:function () { | |
if (Module['setStatus']) { | |
var message = Module['statusMessage'] || 'Please wait...'; | |
var remaining = Browser.mainLoop.remainingBlockers; | |
var expected = Browser.mainLoop.expectedBlockers; | |
if (remaining) { | |
if (remaining < expected) { | |
Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')'); | |
} else { | |
Module['setStatus'](message); | |
} | |
} else { | |
Module['setStatus'](''); | |
} | |
} | |
},runIter:function (func) { | |
if (ABORT) return; | |
if (Module['preMainLoop']) { | |
var preRet = Module['preMainLoop'](); | |
if (preRet === false) { | |
return; // |return false| skips a frame | |
} | |
} | |
try { | |
func(); | |
} catch (e) { | |
if (e instanceof ExitStatus) { | |
return; | |
} else { | |
if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]); | |
throw e; | |
} | |
} | |
if (Module['postMainLoop']) Module['postMainLoop'](); | |
}},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () { | |
if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers | |
if (Browser.initted) return; | |
Browser.initted = true; | |
try { | |
new Blob(); | |
Browser.hasBlobConstructor = true; | |
} catch(e) { | |
Browser.hasBlobConstructor = false; | |
console.log("warning: no blob constructor, cannot create blobs with mimetypes"); | |
} | |
Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null)); | |
Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined; | |
if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') { | |
console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available."); | |
Module.noImageDecoding = true; | |
} | |
// Support for plugins that can process preloaded files. You can add more of these to | |
// your app by creating and appending to Module.preloadPlugins. | |
// | |
// Each plugin is asked if it can handle a file based on the file's name. If it can, | |
// it is given the file's raw data. When it is done, it calls a callback with the file's | |
// (possibly modified) data. For example, a plugin might decompress a file, or it | |
// might create some side data structure for use later (like an Image element, etc.). | |
var imagePlugin = {}; | |
imagePlugin['canHandle'] = function imagePlugin_canHandle(name) { | |
return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name); | |
}; | |
imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) { | |
var b = null; | |
if (Browser.hasBlobConstructor) { | |
try { | |
b = new Blob([byteArray], { type: Browser.getMimetype(name) }); | |
if (b.size !== byteArray.length) { // Safari bug #118630 | |
// Safari's Blob can only take an ArrayBuffer | |
b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) }); | |
} | |
} catch(e) { | |
Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder'); | |
} | |
} | |
if (!b) { | |
var bb = new Browser.BlobBuilder(); | |
bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range | |
b = bb.getBlob(); | |
} | |
var url = Browser.URLObject.createObjectURL(b); | |
assert(typeof url == 'string', 'createObjectURL must return a url as a string'); | |
var img = new Image(); | |
img.onload = function img_onload() { | |
assert(img.complete, 'Image ' + name + ' could not be decoded'); | |
var canvas = document.createElement('canvas'); | |
canvas.width = img.width; | |
canvas.height = img.height; | |
var ctx = canvas.getContext('2d'); | |
ctx.drawImage(img, 0, 0); | |
Module["preloadedImages"][name] = canvas; | |
Browser.URLObject.revokeObjectURL(url); | |
if (onload) onload(byteArray); | |
}; | |
img.onerror = function img_onerror(event) { | |
console.log('Image ' + url + ' could not be decoded'); | |
if (onerror) onerror(); | |
}; | |
img.src = url; | |
}; | |
Module['preloadPlugins'].push(imagePlugin); | |
var audioPlugin = {}; | |
audioPlugin['canHandle'] = function audioPlugin_canHandle(name) { | |
return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 }; | |
}; | |
audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) { | |
var done = false; | |
function finish(audio) { | |
if (done) return; | |
done = true; | |
Module["preloadedAudios"][name] = audio; | |
if (onload) onload(byteArray); | |
} | |
function fail() { | |
if (done) return; | |
done = true; | |
Module["preloadedAudios"][name] = new Audio(); // empty shim | |
if (onerror) onerror(); | |
} | |
if (Browser.hasBlobConstructor) { | |
try { | |
var b = new Blob([byteArray], { type: Browser.getMimetype(name) }); | |
} catch(e) { | |
return fail(); | |
} | |
var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this! | |
assert(typeof url == 'string', 'createObjectURL must return a url as a string'); | |
var audio = new Audio(); | |
audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926 | |
audio.onerror = function audio_onerror(event) { | |
if (done) return; | |
console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach'); | |
function encode64(data) { | |
var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; | |
var PAD = '='; | |
var ret = ''; | |
var leftchar = 0; | |
var leftbits = 0; | |
for (var i = 0; i < data.length; i++) { | |
leftchar = (leftchar << 8) | data[i]; | |
leftbits += 8; | |
while (leftbits >= 6) { | |
var curr = (leftchar >> (leftbits-6)) & 0x3f; | |
leftbits -= 6; | |
ret += BASE[curr]; | |
} | |
} | |
if (leftbits == 2) { | |
ret += BASE[(leftchar&3) << 4]; | |
ret += PAD + PAD; | |
} else if (leftbits == 4) { | |
ret += BASE[(leftchar&0xf) << 2]; | |
ret += PAD; | |
} | |
return ret; | |
} | |
audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray); | |
finish(audio); // we don't wait for confirmation this worked - but it's worth trying | |
}; | |
audio.src = url; | |
// workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror | |
Browser.safeSetTimeout(function() { | |
finish(audio); // try to use it even though it is not necessarily ready to play | |
}, 10000); | |
} else { | |
return fail(); | |
} | |
}; | |
Module['preloadPlugins'].push(audioPlugin); | |
// Canvas event setup | |
var canvas = Module['canvas']; | |
function pointerLockChange() { | |
Browser.pointerLock = document['pointerLockElement'] === canvas || | |
document['mozPointerLockElement'] === canvas || | |
document['webkitPointerLockElement'] === canvas || | |
document['msPointerLockElement'] === canvas; | |
} | |
if (canvas) { | |
// forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module | |
// Module['forcedAspectRatio'] = 4 / 3; | |
canvas.requestPointerLock = canvas['requestPointerLock'] || | |
canvas['mozRequestPointerLock'] || | |
canvas['webkitRequestPointerLock'] || | |
canvas['msRequestPointerLock'] || | |
function(){}; | |
canvas.exitPointerLock = document['exitPointerLock'] || | |
document['mozExitPointerLock'] || | |
document['webkitExitPointerLock'] || | |
document['msExitPointerLock'] || | |
function(){}; // no-op if function does not exist | |
canvas.exitPointerLock = canvas.exitPointerLock.bind(document); | |
document.addEventListener('pointerlockchange', pointerLockChange, false); | |
document.addEventListener('mozpointerlockchange', pointerLockChange, false); | |
document.addEventListener('webkitpointerlockchange', pointerLockChange, false); | |
document.addEventListener('mspointerlockchange', pointerLockChange, false); | |
if (Module['elementPointerLock']) { | |
canvas.addEventListener("click", function(ev) { | |
if (!Browser.pointerLock && canvas.requestPointerLock) { | |
canvas.requestPointerLock(); | |
ev.preventDefault(); | |
} | |
}, false); | |
} | |
} | |
},createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) { | |
if (useWebGL && Module.ctx && canvas == Module.canvas) return Module.ctx; // no need to recreate GL context if it's already been created for this canvas. | |
var ctx; | |
var contextHandle; | |
if (useWebGL) { | |
// For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults. | |
var contextAttributes = { | |
antialias: false, | |
alpha: false | |
}; | |
if (webGLContextAttributes) { | |
for (var attribute in webGLContextAttributes) { | |
contextAttributes[attribute] = webGLContextAttributes[attribute]; | |
} | |
} | |
contextHandle = GL.createContext(canvas, contextAttributes); | |
if (contextHandle) { | |
ctx = GL.getContext(contextHandle).GLctx; | |
} | |
// Set the background of the WebGL canvas to black | |
canvas.style.backgroundColor = "black"; | |
} else { | |
ctx = canvas.getContext('2d'); | |
} | |
if (!ctx) return null; | |
if (setInModule) { | |
if (!useWebGL) assert(typeof GLctx === 'undefined', 'cannot set in module if GLctx is used, but we are a non-GL context that would replace it'); | |
Module.ctx = ctx; | |
if (useWebGL) GL.makeContextCurrent(contextHandle); | |
Module.useWebGL = useWebGL; | |
Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() }); | |
Browser.init(); | |
} | |
return ctx; | |
},destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) { | |
Browser.lockPointer = lockPointer; | |
Browser.resizeCanvas = resizeCanvas; | |
if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true; | |
if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false; | |
var canvas = Module['canvas']; | |
function fullScreenChange() { | |
Browser.isFullScreen = false; | |
var canvasContainer = canvas.parentNode; | |
if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] || | |
document['mozFullScreenElement'] || document['mozFullscreenElement'] || | |
document['fullScreenElement'] || document['fullscreenElement'] || | |
document['msFullScreenElement'] || document['msFullscreenElement'] || | |
document['webkitCurrentFullScreenElement']) === canvasContainer) { | |
canvas.cancelFullScreen = document['cancelFullScreen'] || | |
document['mozCancelFullScreen'] || | |
document['webkitCancelFullScreen'] || | |
document['msExitFullscreen'] || | |
document['exitFullscreen'] || | |
function() {}; | |
canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document); | |
if (Browser.lockPointer) canvas.requestPointerLock(); | |
Browser.isFullScreen = true; | |
if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize(); | |
} else { | |
// remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen | |
canvasContainer.parentNode.insertBefore(canvas, canvasContainer); | |
canvasContainer.parentNode.removeChild(canvasContainer); | |
if (Browser.resizeCanvas) Browser.setWindowedCanvasSize(); | |
} | |
if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen); | |
Browser.updateCanvasDimensions(canvas); | |
} | |
if (!Browser.fullScreenHandlersInstalled) { | |
Browser.fullScreenHandlersInstalled = true; | |
document.addEventListener('fullscreenchange', fullScreenChange, false); | |
document.addEventListener('mozfullscreenchange', fullScreenChange, false); | |
document.addEventListener('webkitfullscreenchange', fullScreenChange, false); | |
document.addEventListener('MSFullscreenChange', fullScreenChange, false); | |
} | |
// create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root | |
var canvasContainer = document.createElement("div"); | |
canvas.parentNode.insertBefore(canvasContainer, canvas); | |
canvasContainer.appendChild(canvas); | |
// use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) | |
canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] || | |
canvasContainer['mozRequestFullScreen'] || | |
canvasContainer['msRequestFullscreen'] || | |
(canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null); | |
canvasContainer.requestFullScreen(); | |
},nextRAF:0,fakeRequestAnimationFrame:function (func) { | |
// try to keep 60fps between calls to here | |
var now = Date.now(); | |
if (Browser.nextRAF === 0) { | |
Browser.nextRAF = now + 1000/60; | |
} else { | |
while (now + 2 >= Browser.nextRAF) { // fudge a little, to avoid timer jitter causing us to do lots of delay:0 | |
Browser.nextRAF += 1000/60; | |
} | |
} | |
var delay = Math.max(Browser.nextRAF - now, 0); | |
setTimeout(func, delay); | |
},requestAnimationFrame:function requestAnimationFrame(func) { | |
if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js) | |
Browser.fakeRequestAnimationFrame(func); | |
} else { | |
if (!window.requestAnimationFrame) { | |
window.requestAnimationFrame = window['requestAnimationFrame'] || | |
window['mozRequestAnimationFrame'] || | |
window['webkitRequestAnimationFrame'] || | |
window['msRequestAnimationFrame'] || | |
window['oRequestAnimationFrame'] || | |
Browser.fakeRequestAnimationFrame; | |
} | |
window.requestAnimationFrame(func); | |
} | |
},safeCallback:function (func) { | |
return function() { | |
if (!ABORT) return func.apply(null, arguments); | |
}; | |
},safeRequestAnimationFrame:function (func) { | |
return Browser.requestAnimationFrame(function() { | |
if (!ABORT) func(); | |
}); | |
},safeSetTimeout:function (func, timeout) { | |
Module['noExitRuntime'] = true; | |
return setTimeout(function() { | |
if (!ABORT) func(); | |
}, timeout); | |
},safeSetInterval:function (func, timeout) { | |
Module['noExitRuntime'] = true; | |
return setInterval(function() { | |
if (!ABORT) func(); | |
}, timeout); | |
},getMimetype:function (name) { | |
return { | |
'jpg': 'image/jpeg', | |
'jpeg': 'image/jpeg', | |
'png': 'image/png', | |
'bmp': 'image/bmp', | |
'ogg': 'audio/ogg', | |
'wav': 'audio/wav', | |
'mp3': 'audio/mpeg' | |
}[name.substr(name.lastIndexOf('.')+1)]; | |
},getUserMedia:function (func) { | |
if(!window.getUserMedia) { | |
window.getUserMedia = navigator['getUserMedia'] || | |
navigator['mozGetUserMedia']; | |
} | |
window.getUserMedia(func); | |
},getMovementX:function (event) { | |
return event['movementX'] || | |
event['mozMovementX'] || | |
event['webkitMovementX'] || | |
0; | |
},getMovementY:function (event) { | |
return event['movementY'] || | |
event['mozMovementY'] || | |
event['webkitMovementY'] || | |
0; | |
},getMouseWheelDelta:function (event) { | |
var delta = 0; | |
switch (event.type) { | |
case 'DOMMouseScroll': | |
delta = event.detail; | |
break; | |
case 'mousewheel': | |
delta = event.wheelDelta; | |
break; | |
case 'wheel': | |
delta = event['deltaY']; | |
break; | |
default: | |
throw 'unrecognized mouse wheel event: ' + event.type; | |
} | |
return delta; | |
},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup | |
if (Browser.pointerLock) { | |
// When the pointer is locked, calculate the coordinates | |
// based on the movement of the mouse. | |
// Workaround for Firefox bug 764498 | |
if (event.type != 'mousemove' && | |
('mozMovementX' in event)) { | |
Browser.mouseMovementX = Browser.mouseMovementY = 0; | |
} else { | |
Browser.mouseMovementX = Browser.getMovementX(event); | |
Browser.mouseMovementY = Browser.getMovementY(event); | |
} | |
// check if SDL is available | |
if (typeof SDL != "undefined") { | |
Browser.mouseX = SDL.mouseX + Browser.mouseMovementX; | |
Browser.mouseY = SDL.mouseY + Browser.mouseMovementY; | |
} else { | |
// just add the mouse delta to the current absolut mouse position | |
// FIXME: ideally this should be clamped against the canvas size and zero | |
Browser.mouseX += Browser.mouseMovementX; | |
Browser.mouseY += Browser.mouseMovementY; | |
} | |
} else { | |
// Otherwise, calculate the movement based on the changes | |
// in the coordinates. | |
var rect = Module["canvas"].getBoundingClientRect(); | |
var cw = Module["canvas"].width; | |
var ch = Module["canvas"].height; | |
// Neither .scrollX or .pageXOffset are defined in a spec, but | |
// we prefer .scrollX because it is currently in a spec draft. | |
// (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/) | |
var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset); | |
var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset); | |
// If this assert lands, it's likely because the browser doesn't support scrollX or pageXOffset | |
// and we have no viable fallback. | |
assert((typeof scrollX !== 'undefined') && (typeof scrollY !== 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.'); | |
if (event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchmove') { | |
var touch = event.touch; | |
if (touch === undefined) { | |
return; // the "touch" property is only defined in SDL | |
} | |
var adjustedX = touch.pageX - (scrollX + rect.left); | |
var adjustedY = touch.pageY - (scrollY + rect.top); | |
adjustedX = adjustedX * (cw / rect.width); | |
adjustedY = adjustedY * (ch / rect.height); | |
var coords = { x: adjustedX, y: adjustedY }; | |
if (event.type === 'touchstart') { | |
Browser.lastTouches[touch.identifier] = coords; | |
Browser.touches[touch.identifier] = coords; | |
} else if (event.type === 'touchend' || event.type === 'touchmove') { | |
Browser.lastTouches[touch.identifier] = Browser.touches[touch.identifier]; | |
Browser.touches[touch.identifier] = { x: adjustedX, y: adjustedY }; | |
} | |
return; | |
} | |
var x = event.pageX - (scrollX + rect.left); | |
var y = event.pageY - (scrollY + rect.top); | |
// the canvas might be CSS-scaled compared to its backbuffer; | |
// SDL-using content will want mouse coordinates in terms | |
// of backbuffer units. | |
x = x * (cw / rect.width); | |
y = y * (ch / rect.height); | |
Browser.mouseMovementX = x - Browser.mouseX; | |
Browser.mouseMovementY = y - Browser.mouseY; | |
Browser.mouseX = x; | |
Browser.mouseY = y; | |
} | |
},xhrLoad:function (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)) { // file URLs can return 0 | |
onload(xhr.response); | |
} else { | |
onerror(); | |
} | |
}; | |
xhr.onerror = onerror; | |
xhr.send(null); | |
},asyncLoad:function (url, onload, onerror, noRunDep) { | |
Browser.xhrLoad(url, function(arrayBuffer) { | |
assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).'); | |
onload(new Uint8Array(arrayBuffer)); | |
if (!noRunDep) removeRunDependency('al ' + url); | |
}, function(event) { | |
if (onerror) { | |
onerror(); | |
} else { | |
throw 'Loading data file "' + url + '" failed.'; | |
} | |
}); | |
if (!noRunDep) addRunDependency('al ' + url); | |
},resizeListeners:[],updateResizeListeners:function () { | |
var canvas = Module['canvas']; | |
Browser.resizeListeners.forEach(function(listener) { | |
listener(canvas.width, canvas.height); | |
}); | |
},setCanvasSize:function (width, height, noUpdates) { | |
var canvas = Module['canvas']; | |
Browser.updateCanvasDimensions(canvas, width, height); | |
if (!noUpdates) Browser.updateResizeListeners(); | |
},windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () { | |
// check if SDL is available | |
if (typeof SDL != "undefined") { | |
var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]; | |
flags = flags | 0x00800000; // set SDL_FULLSCREEN flag | |
HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags | |
} | |
Browser.updateResizeListeners(); | |
},setWindowedCanvasSize:function () { | |
// check if SDL is available | |
if (typeof SDL != "undefined") { | |
var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]; | |
flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag | |
HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags | |
} | |
Browser.updateResizeListeners(); | |
},updateCanvasDimensions:function (canvas, wNative, hNative) { | |
if (wNative && hNative) { | |
canvas.widthNative = wNative; | |
canvas.heightNative = hNative; | |
} else { | |
wNative = canvas.widthNative; | |
hNative = canvas.heightNative; | |
} | |
var w = wNative; | |
var h = hNative; | |
if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) { | |
if (w/h < Module['forcedAspectRatio']) { | |
w = Math.round(h * Module['forcedAspectRatio']); | |
} else { | |
h = Math.round(w / Module['forcedAspectRatio']); | |
} | |
} | |
if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] || | |
document['mozFullScreenElement'] || document['mozFullscreenElement'] || | |
document['fullScreenElement'] || document['fullscreenElement'] || | |
document['msFullScreenElement'] || document['msFullscreenElement'] || | |
document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) { | |
var factor = Math.min(screen.width / w, screen.height / h); | |
w = Math.round(w * factor); | |
h = Math.round(h * factor); | |
} | |
if (Browser.resizeCanvas) { | |
if (canvas.width != w) canvas.width = w; | |
if (canvas.height != h) canvas.height = h; | |
if (typeof canvas.style != 'undefined') { | |
canvas.style.removeProperty( "width"); | |
canvas.style.removeProperty("height"); | |
} | |
} else { | |
if (canvas.width != wNative) canvas.width = wNative; | |
if (canvas.height != hNative) canvas.height = hNative; | |
if (typeof canvas.style != 'undefined') { | |
if (w != wNative || h != hNative) { | |
canvas.style.setProperty( "width", w + "px", "important"); | |
canvas.style.setProperty("height", h + "px", "important"); | |
} else { | |
canvas.style.removeProperty( "width"); | |
canvas.style.removeProperty("height"); | |
} | |
} | |
} | |
},wgetRequests:{},nextWgetRequestHandle:0,getNextWgetRequestHandle:function () { | |
var handle = Browser.nextWgetRequestHandle; | |
Browser.nextWgetRequestHandle++; | |
return handle; | |
}}; | |
function _malloc(bytes) { | |
/* Over-allocate to make sure it is byte-aligned by 8. | |
* This will leak memory, but this is only the dummy | |
* implementation (replaced by dlmalloc normally) so | |
* not an issue. | |
*/ | |
var ptr = Runtime.dynamicAlloc(bytes + 8); | |
return (ptr+8) & 0xFFFFFFF8; | |
} | |
Module["_malloc"] = _malloc; | |
function _free() { | |
} | |
Module["_free"] = _free; | |
var _environ=allocate(1, "i32*", ALLOC_STATIC);var ___environ=_environ;function ___buildEnvironment(env) { | |
// WARNING: Arbitrary limit! | |
var MAX_ENV_VALUES = 64; | |
var TOTAL_ENV_SIZE = 1024; | |
// Statically allocate memory for the environment. | |
var poolPtr; | |
var envPtr; | |
if (!___buildEnvironment.called) { | |
___buildEnvironment.called = true; | |
// Set default values. Use string keys for Closure Compiler compatibility. | |
ENV['USER'] = 'web_user'; | |
ENV['PATH'] = '/'; | |
ENV['PWD'] = '/'; | |
ENV['HOME'] = '/home/web_user'; | |
ENV['LANG'] = 'C'; | |
ENV['_'] = Module['thisProgram']; | |
// Allocate memory. | |
poolPtr = allocate(TOTAL_ENV_SIZE, 'i8', ALLOC_STATIC); | |
envPtr = allocate(MAX_ENV_VALUES * 4, | |
'i8*', ALLOC_STATIC); | |
HEAP32[((envPtr)>>2)]=poolPtr; | |
HEAP32[((_environ)>>2)]=envPtr; | |
} else { | |
envPtr = HEAP32[((_environ)>>2)]; | |
poolPtr = HEAP32[((envPtr)>>2)]; | |
} | |
// Collect key=value lines. | |
var strings = []; | |
var totalSize = 0; | |
for (var key in env) { | |
if (typeof env[key] === 'string') { | |
var line = key + '=' + env[key]; | |
strings.push(line); | |
totalSize += line.length; | |
} | |
} | |
if (totalSize > TOTAL_ENV_SIZE) { | |
throw new Error('Environment size exceeded TOTAL_ENV_SIZE!'); | |
} | |
// Make new. | |
var ptrSize = 4; | |
for (var i = 0; i < strings.length; i++) { | |
var line = strings[i]; | |
writeAsciiToMemory(line, poolPtr); | |
HEAP32[(((envPtr)+(i * ptrSize))>>2)]=poolPtr; | |
poolPtr += line.length + 1; | |
} | |
HEAP32[(((envPtr)+(strings.length * ptrSize))>>2)]=0; | |
}var ENV={};function _getenv(name) { | |
// char *getenv(const char *name); | |
// http://pubs.opengroup.org/onlinepubs/009695399/functions/getenv.html | |
if (name === 0) return 0; | |
name = Pointer_stringify(name); | |
if (!ENV.hasOwnProperty(name)) return 0; | |
if (_getenv.ret) _free(_getenv.ret); | |
_getenv.ret = allocate(intArrayFromString(ENV[name]), 'i8', ALLOC_NORMAL); | |
return _getenv.ret; | |
} | |
function _putenv(string) { | |
// int putenv(char *string); | |
// http://pubs.opengroup.org/onlinepubs/009695399/functions/putenv.html | |
// WARNING: According to the standard (and the glibc implementation), the | |
// string is taken by reference so future changes are reflected. | |
// We copy it instead, possibly breaking some uses. | |
if (string === 0) { | |
___setErrNo(ERRNO_CODES.EINVAL); | |
return -1; | |
} | |
string = Pointer_stringify(string); | |
var splitPoint = string.indexOf('=') | |
if (string === '' || string.indexOf('=') === -1) { | |
___setErrNo(ERRNO_CODES.EINVAL); | |
return -1; | |
} | |
var name = string.slice(0, splitPoint); | |
var value = string.slice(splitPoint + 1); | |
if (!(name in ENV) || ENV[name] !== value) { | |
ENV[name] = value; | |
___buildEnvironment(ENV); | |
} | |
return 0; | |
} | |
function _SDL_RWFromConstMem(mem, size) { | |
var id = SDL.rwops.length; // TODO: recycle ids when they are null | |
SDL.rwops.push({ bytes: mem, count: size }); | |
return id; | |
}function _TTF_FontHeight(font) { | |
var fontData = SDL.fonts[font]; | |
return fontData.size; | |
}function _TTF_RenderText_Solid(font, text, color) { | |
// XXX the font and color are ignored | |
text = Pointer_stringify(text) || ' '; // if given an empty string, still return a valid surface | |
var fontData = SDL.fonts[font]; | |
var w = SDL.estimateTextWidth(fontData, text); | |
var h = fontData.size; | |
var color = SDL.loadColorToCSSRGB(color); // XXX alpha breaks fonts? | |
var fontString = h + 'px ' + fontData.name; | |
var surf = SDL.makeSurface(w, h, 0, false, 'text:' + text); // bogus numbers.. | |
var surfData = SDL.surfaces[surf]; | |
surfData.ctx.save(); | |
surfData.ctx.fillStyle = color; | |
surfData.ctx.font = fontString; | |
surfData.ctx.textBaseline = 'top'; | |
surfData.ctx.fillText(text, 0, 0); | |
surfData.ctx.restore(); | |
return surf; | |
}function _Mix_HaltMusic() { | |
var audio = SDL.music.audio; | |
if (audio) { | |
audio.src = audio.src; // rewind <media> element | |
audio.currentPosition = 0; // rewind Web Audio graph playback. | |
audio.pause(); | |
} | |
SDL.music.audio = null; | |
if (SDL.hookMusicFinished) { | |
Runtime.dynCall('v', SDL.hookMusicFinished); | |
} | |
return 0; | |
}function _Mix_PlayMusic(id, loops) { | |
// Pause old music if it exists. | |
if (SDL.music.audio) { | |
if (!SDL.music.audio.paused) Module.printErr('Music is already playing. ' + SDL.music.source); | |
SDL.music.audio.pause(); | |
} | |
var info = SDL.audios[id]; | |
var audio; | |
if (info.webAudio) { // Play via Web Audio API | |
// Create an instance of the WebAudio object. | |
audio = {}; | |
audio.resource = info; // This new webAudio object is an instance that refers to this existing resource. | |
audio.paused = false; | |
audio.currentPosition = 0; | |
audio.play = function() { SDL.playWebAudio(this); } | |
audio.pause = function() { SDL.pauseWebAudio(this); } | |
} else if (info.audio) { // Play via the <audio> element | |
audio = info.audio; | |
} | |
audio['onended'] = function() { if (SDL.music.audio == this) _Mix_HaltMusic(); } // will send callback | |
audio.loop = loops != 0; // TODO: handle N loops for finite N | |
audio.volume = SDL.music.volume; | |
SDL.music.audio = audio; | |
audio.play(); | |
return 0; | |
}function _Mix_FreeChunk(id) { | |
SDL.audios[id] = null; | |
}function _Mix_LoadWAV_RW(rwopsID, freesrc) { | |
var rwops = SDL.rwops[rwopsID]; | |
if (rwops === undefined) | |
return 0; | |
var filename = ''; | |
var audio; | |
var webAudio; | |
var bytes; | |
if (rwops.filename !== undefined) { | |
filename = PATH.resolve(rwops.filename); | |
var raw = Module["preloadedAudios"][filename]; | |
if (!raw) { | |
if (raw === null) Module.printErr('Trying to reuse preloaded audio, but freePreloadedMediaOnUse is set!'); | |
if (!Module.noAudioDecoding) Runtime.warnOnce('Cannot find preloaded audio ' + filename); | |
// see if we can read the file-contents from the in-memory FS | |
try { | |
bytes = FS.readFile(filename); | |
} catch (e) { | |
Module.printErr('Couldn\'t find file for: ' + filename); | |
return 0; | |
} | |
} | |
if (Module['freePreloadedMediaOnUse']) { | |
Module["preloadedAudios"][filename] = null; | |
} | |
audio = raw; | |
} | |
else if (rwops.bytes !== undefined) { | |
// For Web Audio context buffer decoding, we must make a clone of the audio data, but for <media> element, | |
// a view to existing data is sufficient. | |
if (SDL.webAudioAvailable()) bytes = HEAPU8.buffer.slice(rwops.bytes, rwops.bytes + rwops.count); | |
else bytes = HEAPU8.subarray(rwops.bytes, rwops.bytes + rwops.count); | |
} | |
else { | |
return 0; | |
} | |
var arrayBuffer = bytes ? bytes.buffer || bytes : bytes; | |
// To allow user code to work around browser bugs with audio playback on <audio> elements an Web Audio, enable | |
// the user code to hook in a callback to decide on a file basis whether each file should use Web Audio or <audio> for decoding and playback. | |
// In particular, see https://bugzilla.mozilla.org/show_bug.cgi?id=654787 and ?id=1012801 for tradeoffs. | |
var canPlayWithWebAudio = Module['SDL_canPlayWithWebAudio'] === undefined || Module['SDL_canPlayWithWebAudio'](filename, arrayBuffer); | |
if (bytes !== undefined && SDL.webAudioAvailable() && canPlayWithWebAudio) { | |
audio = undefined; | |
webAudio = {}; | |
// The audio decoding process is asynchronous, which gives trouble if user code plays the audio data back immediately | |
// after loading. Therefore prepare an array of callback handlers to run when this audio decoding is complete, which | |
// will then start the playback (with some delay). | |
webAudio.onDecodeComplete = []; // While this member array exists, decoding hasn't finished yet. | |
function onDecodeComplete(data) { | |
webAudio.decodedBuffer = data; | |
// Call all handlers that were waiting for this decode to finish, and clear the handler list. | |
webAudio.onDecodeComplete.forEach(function(e) { e(); }); | |
webAudio.onDecodeComplete = undefined; // Don't allow more callback handlers since audio has finished decoding. | |
} | |
SDL.audioContext['decodeAudioData'](arrayBuffer, onDecodeComplete); | |
} else if (audio === undefined && bytes) { | |
// Here, we didn't find a preloaded audio but we either were passed a filepath for | |
// which we loaded bytes, or we were passed some bytes | |
var blob = new Blob([bytes], {type: rwops.mimetype}); | |
var url = URL.createObjectURL(blob); | |
audio = new Audio(); | |
audio.src = url; | |
audio.mozAudioChannelType = 'content'; // bugzilla 910340 | |
} | |
var id = SDL.audios.length; | |
// Keep the loaded audio in the audio arrays, ready for playback | |
SDL.audios.push({ | |
source: filename, | |
audio: audio, // Points to the <audio> element, if loaded | |
webAudio: webAudio // Points to a Web Audio -specific resource object, if loaded | |
}); | |
return id; | |
}function _Mix_PlayChannel(channel, id, loops) { | |
// TODO: handle fixed amount of N loops. Currently loops either 0 or infinite times. | |
// Get the audio element associated with the ID | |
var info = SDL.audios[id]; | |
if (!info) return -1; | |
if (!info.audio && !info.webAudio) return -1; | |
// If the user asks us to allocate a channel automatically, get the first | |
// free one. | |
if (channel == -1) { | |
for (var i = SDL.channelMinimumNumber; i < SDL.numChannels; i++) { | |
if (!SDL.channels[i].audio) { | |
channel = i; | |
break; | |
} | |
} | |
if (channel == -1) { | |
Module.printErr('All ' + SDL.numChannels + ' channels in use!'); | |
return -1; | |
} | |
} | |
var channelInfo = SDL.channels[channel]; | |
var audio; | |
if (info.webAudio) { | |
// Create an instance of the WebAudio object. | |
audio = {}; | |
audio.resource = info; // This new object is an instance that refers to this existing resource. | |
audio.paused = false; | |
audio.currentPosition = 0; | |
// Make our instance look similar to the instance of a <media> to make api simple. | |
audio.play = function() { SDL.playWebAudio(this); } | |
audio.pause = function() { SDL.pauseWebAudio(this); } | |
} else { | |
// We clone the audio node to utilize the preloaded audio buffer, since | |
// the browser has already preloaded the audio file. | |
audio = info.audio.cloneNode(true); | |
audio.numChannels = info.audio.numChannels; | |
audio.frequency = info.audio.frequency; | |
} | |
audio['onended'] = function SDL_audio_onended() { // TODO: cache these | |
if (channelInfo.audio == this) { channelInfo.audio.paused = true; channelInfo.audio = null; } | |
if (SDL.channelFinished) Runtime.getFuncWrapper(SDL.channelFinished, 'vi')(channel); | |
} | |
channelInfo.audio = audio; | |
// TODO: handle N loops. Behavior matches Mix_PlayMusic | |
audio.loop = loops != 0; | |
audio.volume = channelInfo.volume; | |
audio.play(); | |
return channel; | |
}function _SDL_PauseAudio(pauseOn) { | |
if (!SDL.audio) { | |
return; | |
} | |
if (pauseOn) { | |
if (SDL.audio.timer !== undefined) { | |
clearTimeout(SDL.audio.timer); | |
SDL.audio.numAudioTimersPending = 0; | |
SDL.audio.timer = undefined; | |
} | |
} else if (!SDL.audio.timer) { | |
// Start the audio playback timer callback loop. | |
SDL.audio.numAudioTimersPending = 1; | |
SDL.audio.timer = Browser.safeSetTimeout(SDL.audio.caller, 1); | |
} | |
SDL.audio.paused = pauseOn; | |
}function _SDL_CloseAudio() { | |
if (SDL.audio) { | |
_SDL_PauseAudio(1); | |
_free(SDL.audio.buffer); | |
SDL.audio = null; | |
SDL.allocateChannels(0); | |
} | |
}function _SDL_FreeRW(rwopsID) { | |
SDL.rwops[rwopsID] = null; | |
while (SDL.rwops.length > 0 && SDL.rwops[SDL.rwops.length-1] === null) { | |
SDL.rwops.pop(); | |
} | |
}function _IMG_Load_RW(rwopsID, freeSrc) { | |
try { | |
// stb_image integration support | |
function cleanup() { | |
if (rwops && freeSrc) _SDL_FreeRW(rwopsID); | |
}; | |
function addCleanup(func) { | |
var old = cleanup; | |
cleanup = function added_cleanup() { | |
old(); | |
func(); | |
} | |
} | |
function callStbImage(func, params) { | |
var x = Module['_malloc'](4); | |
var y = Module['_malloc'](4); | |
var comp = Module['_malloc'](4); | |
addCleanup(function() { | |
Module['_free'](x); | |
Module['_free'](y); | |
Module['_free'](comp); | |
if (data) Module['_stbi_image_free'](data); | |
}); | |
var data = Module['_' + func].apply(null, params.concat([x, y, comp, 0])); | |
if (!data) return null; | |
return { | |
rawData: true, | |
data: data, | |
width: HEAP32[((x)>>2)], | |
height: HEAP32[((y)>>2)], | |
size: HEAP32[((x)>>2)] * HEAP32[((y)>>2)] * HEAP32[((comp)>>2)], | |
bpp: HEAP32[((comp)>>2)] | |
}; | |
} | |
var rwops = SDL.rwops[rwopsID]; | |
if (rwops === undefined) { | |
return 0; | |
} | |
var filename = rwops.filename; | |
if (filename === undefined) { | |
Runtime.warnOnce('Only file names that have been preloaded are supported for IMG_Load_RW. Consider using STB_IMAGE=1 if you want synchronous image decoding (see settings.js)'); | |
return 0; | |
} | |
if (!raw) { | |
filename = PATH.resolve(filename); | |
var raw = Module["preloadedImages"][filename]; | |
if (!raw) { | |
if (raw === null) Module.printErr('Trying to reuse preloaded image, but freePreloadedMediaOnUse is set!'); | |
Runtime.warnOnce('Cannot find preloaded image ' + filename); | |
Runtime.warnOnce('Cannot find preloaded image ' + filename + '. Consider using STB_IMAGE=1 if you want synchronous image decoding (see settings.js)'); | |
return 0; | |
} else if (Module['freePreloadedMediaOnUse']) { | |
Module["preloadedImages"][filename] = null; | |
} | |
} | |
var surf = SDL.makeSurface(raw.width, raw.height, 0, false, 'load:' + filename); | |
var surfData = SDL.surfaces[surf]; | |
surfData.ctx.globalCompositeOperation = "copy"; | |
if (!raw.rawData) { | |
surfData.ctx.drawImage(raw, 0, 0, raw.width, raw.height, 0, 0, raw.width, raw.height); | |
} else { | |
var imageData = surfData.ctx.getImageData(0, 0, surfData.width, surfData.height); | |
if (raw.bpp == 4) { | |
// rgba | |
imageData.data.set(HEAPU8.subarray((raw.data),(raw.data+raw.size))); | |
} else if (raw.bpp == 3) { | |
// rgb | |
var pixels = raw.size/3; | |
var data = imageData.data; | |
var sourcePtr = raw.data; | |
var destPtr = 0; | |
for (var i = 0; i < pixels; i++) { | |
data[destPtr++] = HEAPU8[((sourcePtr++)>>0)]; | |
data[destPtr++] = HEAPU8[((sourcePtr++)>>0)]; | |
data[destPtr++] = HEAPU8[((sourcePtr++)>>0)]; | |
data[destPtr++] = 255; | |
} | |
} else if (raw.bpp == 1) { | |
// grayscale | |
var pixels = raw.size; | |
var data = imageData.data; | |
var sourcePtr = raw.data; | |
var destPtr = 0; | |
for (var i = 0; i < pixels; i++) { | |
var value = HEAPU8[((sourcePtr++)>>0)]; | |
data[destPtr++] = value; | |
data[destPtr++] = value; | |
data[destPtr++] = value; | |
data[destPtr++] = 255; | |
} | |
} else { | |
Module.printErr('cannot handle bpp ' + raw.bpp); | |
return 0; | |
} | |
surfData.ctx.putImageData(imageData, 0, 0); | |
} | |
surfData.ctx.globalCompositeOperation = "source-over"; | |
// XXX SDL does not specify that loaded images must have available pixel data, in fact | |
// there are cases where you just want to blit them, so you just need the hardware | |
// accelerated version. However, code everywhere seems to assume that the pixels | |
// are in fact available, so we retrieve it here. This does add overhead though. | |
_SDL_LockSurface(surf); | |
surfData.locked--; // The surface is not actually locked in this hack | |
if (SDL.GL) { | |
// After getting the pixel data, we can free the canvas and context if we do not need to do 2D canvas blitting | |
surfData.canvas = surfData.ctx = null; | |
} | |
return surf; | |
} finally { | |
cleanup(); | |
} | |
} | |
function _SDL_RWFromFile(_name, mode) { | |
var id = SDL.rwops.length; // TODO: recycle ids when they are null | |
var name = Pointer_stringify(_name) | |
SDL.rwops.push({ filename: name, mimetype: Browser.getMimetype(name) }); | |
return id; | |
}function _IMG_Load(filename){ | |
var rwops = _SDL_RWFromFile(filename); | |
var result = _IMG_Load_RW(rwops, 1); | |
return result; | |
}function _SDL_UpperBlitScaled(src, srcrect, dst, dstrect) { | |
return SDL.blitSurface(src, srcrect, dst, dstrect, true); | |
}function _SDL_UpperBlit(src, srcrect, dst, dstrect) { | |
return SDL.blitSurface(src, srcrect, dst, dstrect, false); | |
}function _SDL_GetTicks() { | |
return (Date.now() - SDL.startTime)|0; | |
}var SDL={defaults:{width:320,height:200,copyOnLock:true,discardOnLock:false,opaqueFrontBuffer:true},version:null,surfaces:{},canvasPool:[],events:[],fonts:[null],audios:[null],rwops:[null],music:{audio:null,volume:1},mixerFrequency:22050,mixerFormat:32784,mixerNumChannels:2,mixerChunkSize:1024,channelMinimumNumber:0,GL:false,glAttributes:{0:3,1:3,2:2,3:0,4:0,5:1,6:16,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0,15:1,16:0,17:0,18:0},keyboardState:null,keyboardMap:{},canRequestFullscreen:false,isRequestingFullscreen:false,textInput:false,startTime:null,initFlags:0,buttonState:0,modState:0,DOMButtons:[0,0,0],DOMEventToSDLEvent:{},TOUCH_DEFAULT_ID:0,eventHandler:null,eventHandlerContext:null,keyCodes:{16:1249,17:1248,18:1250,20:1081,33:1099,34:1102,35:1101,36:1098,37:1104,38:1106,39:1103,40:1105,44:316,45:1097,46:127,91:1251,93:1125,96:1122,97:1113,98:1114,99:1115,100:1116,101:1117,102:1118,103:1119,104:1120,105:1121,106:1109,107:1111,109:1110,110:1123,111:1108,112:1082,113:1083,114:1084,115:1085,116:1086,117:1087,118:1088,119:1089,120:1090,121:1091,122:1092,123:1093,124:1128,125:1129,126:1130,127:1131,128:1132,129:1133,130:1134,131:1135,132:1136,133:1137,134:1138,135:1139,144:1107,160:94,161:33,162:34,163:35,164:36,165:37,166:38,167:95,168:40,169:41,170:42,171:43,172:124,173:45,174:123,175:125,176:126,181:127,182:129,183:128,188:44,190:46,191:47,192:96,219:91,220:92,221:93,222:39},scanCodes:{8:42,9:43,13:40,27:41,32:44,35:204,39:53,44:54,46:55,47:56,48:39,49:30,50:31,51:32,52:33,53:34,54:35,55:36,56:37,57:38,58:203,59:51,61:46,91:47,92:49,93:48,96:52,97:4,98:5,99:6,100:7,101:8,102:9,103:10,104:11,105:12,106:13,107:14,108:15,109:16,110:17,111:18,112:19,113:20,114:21,115:22,116:23,117:24,118:25,119:26,120:27,121:28,122:29,127:76,305:224,308:226,316:70},loadRect:function (rect) { | |
return { | |
x: HEAP32[((rect + 0)>>2)], | |
y: HEAP32[((rect + 4)>>2)], | |
w: HEAP32[((rect + 8)>>2)], | |
h: HEAP32[((rect + 12)>>2)] | |
}; | |
},updateRect:function (rect, r) { | |
HEAP32[((rect)>>2)]=r.x; | |
HEAP32[(((rect)+(4))>>2)]=r.y; | |
HEAP32[(((rect)+(8))>>2)]=r.w; | |
HEAP32[(((rect)+(12))>>2)]=r.h; | |
},intersectionOfRects:function (first, second) { | |
var leftX = Math.max(first.x, second.x); | |
var leftY = Math.max(first.y, second.y); | |
var rightX = Math.min(first.x + first.w, second.x + second.w); | |
var rightY = Math.min(first.y + first.h, second.y + second.h); | |
return { | |
x: leftX, | |
y: leftY, | |
w: Math.max(leftX, rightX) - leftX, | |
h: Math.max(leftY, rightY) - leftY | |
} | |
},checkPixelFormat:function (fmt) { | |
// Canvas screens are always RGBA. | |
var format = HEAP32[((fmt)>>2)]; | |
if (format != -2042224636) { | |
Runtime.warnOnce('Unsupported pixel format!'); | |
} | |
},loadColorToCSSRGB:function (color) { | |
var rgba = HEAP32[((color)>>2)]; | |
return 'rgb(' + (rgba&255) + ',' + ((rgba >> 8)&255) + ',' + ((rgba >> 16)&255) + ')'; | |
},loadColorToCSSRGBA:function (color) { | |
var rgba = HEAP32[((color)>>2)]; | |
return 'rgba(' + (rgba&255) + ',' + ((rgba >> 8)&255) + ',' + ((rgba >> 16)&255) + ',' + (((rgba >> 24)&255)/255) + ')'; | |
},translateColorToCSSRGBA:function (rgba) { | |
return 'rgba(' + (rgba&0xff) + ',' + (rgba>>8 & 0xff) + ',' + (rgba>>16 & 0xff) + ',' + (rgba>>>24)/0xff + ')'; | |
},translateRGBAToCSSRGBA:function (r, g, b, a) { | |
return 'rgba(' + (r&0xff) + ',' + (g&0xff) + ',' + (b&0xff) + ',' + (a&0xff)/255 + ')'; | |
},translateRGBAToColor:function (r, g, b, a) { | |
return r | g << 8 | b << 16 | a << 24; | |
},makeSurface:function (width, height, flags, usePageCanvas, source, rmask, gmask, bmask, amask) { | |
flags = flags || 0; | |
var is_SDL_HWSURFACE = flags & 0x00000001; | |
var is_SDL_HWPALETTE = flags & 0x00200000; | |
var is_SDL_OPENGL = flags & 0x04000000; | |
var surf = _malloc(60); | |
var pixelFormat = _malloc(44); | |
//surface with SDL_HWPALETTE flag is 8bpp surface (1 byte) | |
var bpp = is_SDL_HWPALETTE ? 1 : 4; | |
var buffer = 0; | |
// preemptively initialize this for software surfaces, | |
// otherwise it will be lazily initialized inside of SDL_LockSurface | |
if (!is_SDL_HWSURFACE && !is_SDL_OPENGL) { | |
buffer = _malloc(width * height * 4); | |
} | |
HEAP32[((surf)>>2)]=flags; | |
HEAP32[(((surf)+(4))>>2)]=pixelFormat; | |
HEAP32[(((surf)+(8))>>2)]=width; | |
HEAP32[(((surf)+(12))>>2)]=height; | |
HEAP32[(((surf)+(16))>>2)]=width * bpp; // assuming RGBA or indexed for now, | |
// since that is what ImageData gives us in browsers | |
HEAP32[(((surf)+(20))>>2)]=buffer; | |
HEAP32[(((surf)+(36))>>2)]=0; | |
HEAP32[(((surf)+(40))>>2)]=0; | |
HEAP32[(((surf)+(44))>>2)]=Module["canvas"].width; | |
HEAP32[(((surf)+(48))>>2)]=Module["canvas"].height; | |
HEAP32[(((surf)+(56))>>2)]=1; | |
HEAP32[((pixelFormat)>>2)]=-2042224636; | |
HEAP32[(((pixelFormat)+(4))>>2)]=0;// TODO | |
HEAP8[(((pixelFormat)+(8))>>0)]=bpp * 8; | |
HEAP8[(((pixelFormat)+(9))>>0)]=bpp; | |
HEAP32[(((pixelFormat)+(12))>>2)]=rmask || 0x000000ff; | |
HEAP32[(((pixelFormat)+(16))>>2)]=gmask || 0x0000ff00; | |
HEAP32[(((pixelFormat)+(20))>>2)]=bmask || 0x00ff0000; | |
HEAP32[(((pixelFormat)+(24))>>2)]=amask || 0xff000000; | |
// Decide if we want to use WebGL or not | |
SDL.GL = SDL.GL || is_SDL_OPENGL; | |
var canvas; | |
if (!usePageCanvas) { | |
if (SDL.canvasPool.length > 0) { | |
canvas = SDL.canvasPool.pop(); | |
} else { | |
canvas = document.createElement('canvas'); | |
} | |
canvas.width = width; | |
canvas.height = height; | |
} else { | |
canvas = Module['canvas']; | |
} | |
var webGLContextAttributes = { | |
antialias: ((SDL.glAttributes[13 /*SDL_GL_MULTISAMPLEBUFFERS*/] != 0) && (SDL.glAttributes[14 /*SDL_GL_MULTISAMPLESAMPLES*/] > 1)), | |
depth: (SDL.glAttributes[6 /*SDL_GL_DEPTH_SIZE*/] > 0), | |
stencil: (SDL.glAttributes[7 /*SDL_GL_STENCIL_SIZE*/] > 0) | |
}; | |
var ctx = Browser.createContext(canvas, is_SDL_OPENGL, usePageCanvas, webGLContextAttributes); | |
SDL.surfaces[surf] = { | |
width: width, | |
height: height, | |
canvas: canvas, | |
ctx: ctx, | |
surf: surf, | |
buffer: buffer, | |
pixelFormat: pixelFormat, | |
alpha: 255, | |
flags: flags, | |
locked: 0, | |
usePageCanvas: usePageCanvas, | |
source: source, | |
isFlagSet: function(flag) { | |
return flags & flag; | |
} | |
}; | |
return surf; | |
},copyIndexedColorData:function (surfData, rX, rY, rW, rH) { | |
// HWPALETTE works with palette | |
// setted by SDL_SetColors | |
if (!surfData.colors) { | |
return; | |
} | |
var fullWidth = Module['canvas'].width; | |
var fullHeight = Module['canvas'].height; | |
var startX = rX || 0; | |
var startY = rY || 0; | |
var endX = (rW || (fullWidth - startX)) + startX; | |
var endY = (rH || (fullHeight - startY)) + startY; | |
var buffer = surfData.buffer; | |
if (!surfData.image.data32) { | |
surfData.image.data32 = new Uint32Array(surfData.image.data.buffer); | |
} | |
var data32 = surfData.image.data32; | |
var colors32 = surfData.colors32; | |
for (var y = startY; y < endY; ++y) { | |
var base = y * fullWidth; | |
for (var x = startX; x < endX; ++x) { | |
data32[base + x] = colors32[HEAPU8[((buffer + base + x)>>0)]]; | |
} | |
} | |
},freeSurface:function (surf) { | |
var refcountPointer = surf + 56; | |
var refcount = HEAP32[((refcountPointer)>>2)]; | |
if (refcount > 1) { | |
HEAP32[((refcountPointer)>>2)]=refcount - 1; | |
return; | |
} | |
var info = SDL.surfaces[surf]; | |
if (!info.usePageCanvas && info.canvas) SDL.canvasPool.push(info.canvas); | |
if (info.buffer) _free(info.buffer); | |
_free(info.pixelFormat); | |
_free(surf); | |
SDL.surfaces[surf] = null; | |
if (surf === SDL.screen) { | |
SDL.screen = null; | |
} | |
},blitSurface__deps:["SDL_LockSurface"],blitSurface:function (src, srcrect, dst, dstrect, scale) { | |
var srcData = SDL.surfaces[src]; | |
var dstData = SDL.surfaces[dst]; | |
var sr, dr; | |
if (srcrect) { | |
sr = SDL.loadRect(srcrect); | |
} else { | |
sr = { x: 0, y: 0, w: srcData.width, h: srcData.height }; | |
} | |
if (dstrect) { | |
dr = SDL.loadRect(dstrect); | |
} else { | |
dr = { x: 0, y: 0, w: srcData.width, h: srcData.height }; | |
} | |
if (dstData.clipRect) { | |
var widthScale = (!scale || sr.w === 0) ? 1 : sr.w / dr.w; | |
var heightScale = (!scale || sr.h === 0) ? 1 : sr.h / dr.h; | |
dr = SDL.intersectionOfRects(dstData.clipRect, dr); | |
sr.w = dr.w * widthScale; | |
sr.h = dr.h * heightScale; | |
if (dstrect) { | |
SDL.updateRect(dstrect, dr); | |
} | |
} | |
var blitw, blitr; | |
if (scale) { | |
blitw = dr.w; blith = dr.h; | |
} else { | |
blitw = sr.w; blith = sr.h; | |
} | |
if (sr.w === 0 || sr.h === 0 || blitw === 0 || blith === 0) { | |
return 0; | |
} | |
var oldAlpha = dstData.ctx.globalAlpha; | |
dstData.ctx.globalAlpha = srcData.alpha/255; | |
dstData.ctx.drawImage(srcData.canvas, sr.x, sr.y, sr.w, sr.h, dr.x, dr.y, blitw, blith); | |
dstData.ctx.globalAlpha = oldAlpha; | |
if (dst != SDL.screen) { | |
// XXX As in IMG_Load, for compatibility we write out |pixels| | |
Runtime.warnOnce('WARNING: copying canvas data to memory for compatibility'); | |
_SDL_LockSurface(dst); | |
dstData.locked--; // The surface is not actually locked in this hack | |
} | |
return 0; | |
},downFingers:{},savedKeydown:null,receiveEvent:function (event) { | |
function unpressAllPressedKeys() { | |
// Un-press all pressed keys: TODO | |
for (var code in SDL.keyboardMap) { | |
SDL.events.push({ | |
type: 'keyup', | |
keyCode: SDL.keyboardMap[code] | |
}); | |
} | |
}; | |
switch(event.type) { | |
case 'touchstart': case 'touchmove': { | |
event.preventDefault(); | |
var touches = []; | |
// Clear out any touchstart events that we've already processed | |
if (event.type === 'touchstart') { | |
for (var i = 0; i < event.touches.length; i++) { | |
var touch = event.touches[i]; | |
if (SDL.downFingers[touch.identifier] != true) { | |
SDL.downFingers[touch.identifier] = true; | |
touches.push(touch); | |
} | |
} | |
} else { | |
touches = event.touches; | |
} | |
var firstTouch = touches[0]; | |
if (event.type == 'touchstart') { | |
SDL.DOMButtons[0] = 1; | |
} | |
var mouseEventType; | |
switch(event.type) { | |
case 'touchstart': mouseEventType = 'mousedown'; break; | |
case 'touchmove': mouseEventType = 'mousemove'; break; | |
} | |
var mouseEvent = { | |
type: mouseEventType, | |
button: 0, | |
pageX: firstTouch.clientX, | |
pageY: firstTouch.clientY | |
}; | |
SDL.events.push(mouseEvent); | |
for (var i = 0; i < touches.length; i++) { | |
var touch = touches[i]; | |
SDL.events.push({ | |
type: event.type, | |
touch: touch | |
}); | |
}; | |
break; | |
} | |
case 'touchend': { | |
event.preventDefault(); | |
// Remove the entry in the SDL.downFingers hash | |
// because the finger is no longer down. | |
for(var i = 0; i < event.changedTouches.length; i++) { | |
var touch = event.changedTouches[i]; | |
if (SDL.downFingers[touch.identifier] === true) { | |
delete SDL.downFingers[touch.identifier]; | |
} | |
} | |
var mouseEvent = { | |
type: 'mouseup', | |
button: 0, | |
pageX: event.changedTouches[0].clientX, | |
pageY: event.changedTouches[0].clientY | |
}; | |
SDL.DOMButtons[0] = 0; | |
SDL.events.push(mouseEvent); | |
for (var i = 0; i < event.changedTouches.length; i++) { | |
var touch = event.changedTouches[i]; | |
SDL.events.push({ | |
type: 'touchend', | |
touch: touch | |
}); | |
}; | |
break; | |
} | |
case 'DOMMouseScroll': case 'mousewheel': case 'wheel': | |
var delta = -Browser.getMouseWheelDelta(event); // Flip the wheel direction to translate from browser wheel direction (+:down) to SDL direction (+:up) | |
delta = (delta == 0) ? 0 : (delta > 0 ? Math.max(delta, 1) : Math.min(delta, -1)); // Quantize to integer so that minimum scroll is at least +/- 1. | |
// Simulate old-style SDL events representing mouse wheel input as buttons | |
var button = delta > 0 ? 3 /*SDL_BUTTON_WHEELUP-1*/ : 4 /*SDL_BUTTON_WHEELDOWN-1*/; // Subtract one since JS->C marshalling is defined to add one back. | |
SDL.events.push({ type: 'mousedown', button: button, pageX: event.pageX, pageY: event.pageY }); | |
SDL.events.push({ type: 'mouseup', button: button, pageX: event.pageX, pageY: event.pageY }); | |
// Pass a delta motion event. | |
SDL.events.push({ type: 'wheel', deltaX: 0, deltaY: delta }); | |
event.preventDefault(); // If we don't prevent this, then 'wheel' event will be sent again by the browser as 'DOMMouseScroll' and we will receive this same event the second time. | |
break; | |
case 'mousemove': | |
if (SDL.DOMButtons[0] === 1) { | |
SDL.events.push({ | |
type: 'touchmove', | |
touch: { | |
identifier: 0, | |
deviceID: -1, | |
pageX: event.pageX, | |
pageY: event.pageY | |
} | |
}); | |
} | |
if (Browser.pointerLock) { | |
// workaround for firefox bug 750111 | |
if ('mozMovementX' in event) { | |
event['movementX'] = event['mozMovementX']; | |
event['movementY'] = event['mozMovementY']; | |
} | |
// workaround for Firefox bug 782777 | |
if (event['movementX'] == 0 && event['movementY'] == 0) { | |
// ignore a mousemove event if it doesn't contain any movement info | |
// (without pointer lock, we infer movement from pageX/pageY, so this check is unnecessary) | |
event.preventDefault(); | |
return; | |
} | |
} | |
// fall through | |
case 'keydown': case 'keyup': case 'keypress': case 'mousedown': case 'mouseup': | |
// If we preventDefault on keydown events, the subsequent keypress events | |
// won't fire. However, it's fine (and in some cases necessary) to | |
// preventDefault for keys that don't generate a character. Otherwise, | |
// preventDefault is the right thing to do in general. | |
if (event.type !== 'keydown' || (!SDL.unicode && !SDL.textInput) || (event.keyCode === 8 /* backspace */ || event.keyCode === 9 /* tab */)) { | |
event.preventDefault(); | |
} | |
if (event.type == 'mousedown') { | |
SDL.DOMButtons[event.button] = 1; | |
SDL.events.push({ | |
type: 'touchstart', | |
touch: { | |
identifier: 0, | |
deviceID: -1, | |
pageX: event.pageX, | |
pageY: event.pageY | |
} | |
}); | |
} else if (event.type == 'mouseup') { | |
// ignore extra ups, can happen if we leave the canvas while pressing down, then return, | |
// since we add a mouseup in that case | |
if (!SDL.DOMButtons[event.button]) { | |
return; | |
} | |
SDL.events.push({ | |
type: 'touchend', | |
touch: { | |
identifier: 0, | |
deviceID: -1, | |
pageX: event.pageX, | |
pageY: event.pageY | |
} | |
}); | |
SDL.DOMButtons[event.button] = 0; | |
} | |
// We can only request fullscreen as the result of user input. | |
// Due to this limitation, we toggle a boolean on keydown which | |
// SDL_WM_ToggleFullScreen will check and subsequently set another | |
// flag indicating for us to request fullscreen on the following | |
// keyup. This isn't perfect, but it enables SDL_WM_ToggleFullScreen | |
// to work as the result of a keypress (which is an extremely | |
// common use case). | |
if (event.type === 'keydown' || event.type === 'mousedown') { | |
SDL.canRequestFullscreen = true; | |
} else if (event.type === 'keyup' || event.type === 'mouseup') { | |
if (SDL.isRequestingFullscreen) { | |
Module['requestFullScreen'](true, true); | |
SDL.isRequestingFullscreen = false; | |
} | |
SDL.canRequestFullscreen = false; | |
} | |
// SDL expects a unicode character to be passed to its keydown events. | |
// Unfortunately, the browser APIs only provide a charCode property on | |
// keypress events, so we must backfill in keydown events with their | |
// subsequent keypress event's charCode. | |
if (event.type === 'keypress' && SDL.savedKeydown) { | |
// charCode is read-only | |
SDL.savedKeydown.keypressCharCode = event.charCode; | |
SDL.savedKeydown = null; | |
} else if (event.type === 'keydown') { | |
SDL.savedKeydown = event; | |
} | |
// Don't push keypress events unless SDL_StartTextInput has been called. | |
if (event.type !== 'keypress' || SDL.textInput) { | |
SDL.events.push(event); | |
} | |
break; | |
case 'mouseout': | |
// Un-press all pressed mouse buttons, because we might miss the release outside of the canvas | |
for (var i = 0; i < 3; i++) { | |
if (SDL.DOMButtons[i]) { | |
SDL.events.push({ | |
type: 'mouseup', | |
button: i, | |
pageX: event.pageX, | |
pageY: event.pageY | |
}); | |
SDL.DOMButtons[i] = 0; | |
} | |
} | |
event.preventDefault(); | |
break; | |
case 'focus': | |
SDL.events.push(event); | |
event.preventDefault(); | |
break; | |
case 'blur': | |
SDL.events.push(event); | |
unpressAllPressedKeys(); | |
event.preventDefault(); | |
break; | |
case 'visibilitychange': | |
SDL.events.push({ | |
type: 'visibilitychange', | |
visible: !document.hidden | |
}); | |
unpressAllPressedKeys(); | |
event.preventDefault(); | |
break; | |
case 'unload': | |
if (Browser.mainLoop.runner) { | |
SDL.events.push(event); | |
// Force-run a main event loop, since otherwise this event will never be caught! | |
Browser.mainLoop.runner(); | |
} | |
return; | |
case 'resize': | |
SDL.events.push(event); | |
// manually triggered resize event doesn't have a preventDefault member | |
if (event.preventDefault) { | |
event.preventDefault(); | |
} | |
break; | |
} | |
if (SDL.events.length >= 10000) { | |
Module.printErr('SDL event queue full, dropping events'); | |
SDL.events = SDL.events.slice(0, 10000); | |
} | |
// If we have a handler installed, this will push the events to the app | |
// instead of the app polling for them. | |
SDL.flushEventsToHandler(); | |
return; | |
},lookupKeyCodeForEvent:function (event) { | |
var code = event.keyCode; | |
if (code >= 65 && code <= 90) { | |
code += 32; // make lowercase for SDL | |
} else { | |
code = SDL.keyCodes[event.keyCode] || event.keyCode; | |
// If this is one of the modifier keys (224 | 1<<10 - 227 | 1<<10), and the event specifies that it is | |
// a right key, add 4 to get the right key SDL key code. | |
if (event.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT && code >= (224 | 1<<10) && code <= (227 | 1<<10)) { | |
code += 4; | |
} | |
} | |
return code; | |
},handleEvent:function (event) { | |
if (event.handled) return; | |
event.handled = true; | |
switch (event.type) { | |
case 'touchstart': case 'touchend': case 'touchmove': { | |
Browser.calculateMouseEvent(event); | |
break; | |
} | |
case 'keydown': case 'keyup': { | |
var down = event.type === 'keydown'; | |
var code = SDL.lookupKeyCodeForEvent(event); | |
HEAP8[(((SDL.keyboardState)+(code))>>0)]=down; | |
// TODO: lmeta, rmeta, numlock, capslock, KMOD_MODE, KMOD_RESERVED | |
SDL.modState = (HEAP8[(((SDL.keyboardState)+(1248))>>0)] ? 0x0040 : 0) | // KMOD_LCTRL | |
(HEAP8[(((SDL.keyboardState)+(1249))>>0)] ? 0x0001 : 0) | // KMOD_LSHIFT | |
(HEAP8[(((SDL.keyboardState)+(1250))>>0)] ? 0x0100 : 0) | // KMOD_LALT | |
(HEAP8[(((SDL.keyboardState)+(1252))>>0)] ? 0x0080 : 0) | // KMOD_RCTRL | |
(HEAP8[(((SDL.keyboardState)+(1253))>>0)] ? 0x0002 : 0) | // KMOD_RSHIFT | |
(HEAP8[(((SDL.keyboardState)+(1254))>>0)] ? 0x0200 : 0); // KMOD_RALT | |
if (down) { | |
SDL.keyboardMap[code] = event.keyCode; // save the DOM input, which we can use to unpress it during blur | |
} else { | |
delete SDL.keyboardMap[code]; | |
} | |
break; | |
} | |
case 'mousedown': case 'mouseup': | |
if (event.type == 'mousedown') { | |
// SDL_BUTTON(x) is defined as (1 << ((x)-1)). SDL buttons are 1-3, | |
// and DOM buttons are 0-2, so this means that the below formula is | |
// correct. | |
SDL.buttonState |= 1 << event.button; | |
} else if (event.type == 'mouseup') { | |
SDL.buttonState &= ~(1 << event.button); | |
} | |
// fall through | |
case 'mousemove': { | |
Browser.calculateMouseEvent(event); | |
break; | |
} | |
} | |
},flushEventsToHandler:function () { | |
if (!SDL.eventHandler) return; | |
// All SDLEvents take the same amount of memory | |
var sdlEventPtr = allocate(28, "i8", ALLOC_STACK); | |
while (SDL.pollEvent(sdlEventPtr)) { | |
Runtime.dynCall('iii', SDL.eventHandler, [SDL.eventHandlerContext, sdlEventPtr]); | |
} | |
},pollEvent:function (ptr) { | |
if (SDL.initFlags & 0x200 && SDL.joystickEventState) { | |
// If SDL_INIT_JOYSTICK was supplied AND the joystick system is configured | |
// to automatically query for events, query for joystick events. | |
SDL.queryJoysticks(); | |
} | |
if (ptr) { | |
while (SDL.events.length > 0) { | |
if (SDL.makeCEvent(SDL.events.shift(), ptr) !== false) return 1; | |
} | |
return 0; | |
} else { | |
// XXX: somewhat risky in that we do not check if the event is real or not (makeCEvent returns false) if no pointer supplied | |
return SDL.events.length > 0; | |
} | |
},makeCEvent:function (event, ptr) { | |
if (typeof event === 'number') { | |
// This is a pointer to a copy of a native C event that was SDL_PushEvent'ed | |
_memcpy(ptr, event, 28); | |
_free(event); // the copy is no longer needed | |
return; | |
} | |
SDL.handleEvent(event); | |
switch (event.type) { | |
case 'keydown': case 'keyup': { | |
var down = event.type === 'keydown'; | |
//Module.print('Received key event: ' + event.keyCode); | |
var key = SDL.lookupKeyCodeForEvent(event); | |
var scan; | |
if (key >= 1024) { | |
scan = key - 1024; | |
} else { | |
scan = SDL.scanCodes[key] || key; | |
} | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP8[(((ptr)+(8))>>0)]=down ? 1 : 0; | |
HEAP8[(((ptr)+(9))>>0)]=0; // TODO | |
HEAP32[(((ptr)+(12))>>2)]=scan; | |
HEAP32[(((ptr)+(16))>>2)]=key; | |
HEAP16[(((ptr)+(20))>>1)]=SDL.modState; | |
// some non-character keys (e.g. backspace and tab) won't have keypressCharCode set, fill in with the keyCode. | |
HEAP32[(((ptr)+(24))>>2)]=event.keypressCharCode || key; | |
break; | |
} | |
case 'keypress': { | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
// Not filling in windowID for now | |
var cStr = intArrayFromString(String.fromCharCode(event.charCode)); | |
for (var i = 0; i < cStr.length; ++i) { | |
HEAP8[(((ptr)+(8 + i))>>0)]=cStr[i]; | |
} | |
break; | |
} | |
case 'mousedown': case 'mouseup': case 'mousemove': { | |
if (event.type != 'mousemove') { | |
var down = event.type === 'mousedown'; | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP32[(((ptr)+(4))>>2)]=0; | |
HEAP32[(((ptr)+(8))>>2)]=0; | |
HEAP32[(((ptr)+(12))>>2)]=0; | |
HEAP8[(((ptr)+(16))>>0)]=event.button+1; // DOM buttons are 0-2, SDL 1-3 | |
HEAP8[(((ptr)+(17))>>0)]=down ? 1 : 0; | |
HEAP32[(((ptr)+(20))>>2)]=Browser.mouseX; | |
HEAP32[(((ptr)+(24))>>2)]=Browser.mouseY; | |
} else { | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP32[(((ptr)+(4))>>2)]=0; | |
HEAP32[(((ptr)+(8))>>2)]=0; | |
HEAP32[(((ptr)+(12))>>2)]=0; | |
HEAP32[(((ptr)+(16))>>2)]=SDL.buttonState; | |
HEAP32[(((ptr)+(20))>>2)]=Browser.mouseX; | |
HEAP32[(((ptr)+(24))>>2)]=Browser.mouseY; | |
HEAP32[(((ptr)+(28))>>2)]=Browser.mouseMovementX; | |
HEAP32[(((ptr)+(32))>>2)]=Browser.mouseMovementY; | |
} | |
break; | |
} | |
case 'wheel': { | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP32[(((ptr)+(16))>>2)]=event.deltaX; | |
HEAP32[(((ptr)+(20))>>2)]=event.deltaY; | |
break; | |
} | |
case 'touchstart': case 'touchend': case 'touchmove': { | |
var touch = event.touch; | |
if (!Browser.touches[touch.identifier]) break; | |
var w = Module['canvas'].width; | |
var h = Module['canvas'].height; | |
var x = Browser.touches[touch.identifier].x / w; | |
var y = Browser.touches[touch.identifier].y / h; | |
var lx = Browser.lastTouches[touch.identifier].x / w; | |
var ly = Browser.lastTouches[touch.identifier].y / h; | |
var dx = x - lx; | |
var dy = y - ly; | |
if (touch['deviceID'] === undefined) touch.deviceID = SDL.TOUCH_DEFAULT_ID; | |
if (dx === 0 && dy === 0 && event.type === 'touchmove') return false; // don't send these if nothing happened | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP32[(((ptr)+(4))>>2)]=_SDL_GetTicks(); | |
(tempI64 = [touch.deviceID>>>0,(tempDouble=touch.deviceID,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((ptr)+(8))>>2)]=tempI64[0],HEAP32[(((ptr)+(12))>>2)]=tempI64[1]); | |
(tempI64 = [touch.identifier>>>0,(tempDouble=touch.identifier,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((ptr)+(16))>>2)]=tempI64[0],HEAP32[(((ptr)+(20))>>2)]=tempI64[1]); | |
HEAPF32[(((ptr)+(24))>>2)]=x; | |
HEAPF32[(((ptr)+(28))>>2)]=y; | |
HEAPF32[(((ptr)+(32))>>2)]=dx; | |
HEAPF32[(((ptr)+(36))>>2)]=dy; | |
if (touch.force !== undefined) { | |
HEAPF32[(((ptr)+(40))>>2)]=touch.force; | |
} else { // No pressure data, send a digital 0/1 pressure. | |
HEAPF32[(((ptr)+(40))>>2)]=event.type == "touchend" ? 0 : 1; | |
} | |
break; | |
} | |
case 'unload': { | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
break; | |
} | |
case 'resize': { | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP32[(((ptr)+(4))>>2)]=event.w; | |
HEAP32[(((ptr)+(8))>>2)]=event.h; | |
break; | |
} | |
case 'joystick_button_up': case 'joystick_button_down': { | |
var state = event.type === 'joystick_button_up' ? 0 : 1; | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP8[(((ptr)+(4))>>0)]=event.index; | |
HEAP8[(((ptr)+(5))>>0)]=event.button; | |
HEAP8[(((ptr)+(6))>>0)]=state; | |
break; | |
} | |
case 'joystick_axis_motion': { | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP8[(((ptr)+(4))>>0)]=event.index; | |
HEAP8[(((ptr)+(5))>>0)]=event.axis; | |
HEAP32[(((ptr)+(8))>>2)]=SDL.joystickAxisValueConversion(event.value); | |
break; | |
} | |
case 'focus': { | |
var SDL_WINDOWEVENT_FOCUS_GAINED = 12 /* SDL_WINDOWEVENT_FOCUS_GAINED */; | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP32[(((ptr)+(4))>>2)]=0; | |
HEAP8[(((ptr)+(8))>>0)]=SDL_WINDOWEVENT_FOCUS_GAINED; | |
break; | |
} | |
case 'blur': { | |
var SDL_WINDOWEVENT_FOCUS_LOST = 13 /* SDL_WINDOWEVENT_FOCUS_LOST */; | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP32[(((ptr)+(4))>>2)]=0; | |
HEAP8[(((ptr)+(8))>>0)]=SDL_WINDOWEVENT_FOCUS_LOST; | |
break; | |
} | |
case 'visibilitychange': { | |
var SDL_WINDOWEVENT_SHOWN = 1 /* SDL_WINDOWEVENT_SHOWN */; | |
var SDL_WINDOWEVENT_HIDDEN = 2 /* SDL_WINDOWEVENT_HIDDEN */; | |
var visibilityEventID = event.visible ? SDL_WINDOWEVENT_SHOWN : SDL_WINDOWEVENT_HIDDEN; | |
HEAP32[((ptr)>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP32[(((ptr)+(4))>>2)]=0; | |
HEAP8[(((ptr)+(8))>>0)]=visibilityEventID; | |
break; | |
} | |
default: throw 'Unhandled SDL event: ' + event.type; | |
} | |
},estimateTextWidth:function (fontData, text) { | |
var h = fontData.size; | |
var fontString = h + 'px ' + fontData.name; | |
var tempCtx = SDL.ttfContext; | |
assert(tempCtx, 'TTF_Init must have been called'); | |
tempCtx.save(); | |
tempCtx.font = fontString; | |
var ret = tempCtx.measureText(text).width | 0; | |
tempCtx.restore(); | |
return ret; | |
},allocateChannels:function (num) { // called from Mix_AllocateChannels and init | |
if (SDL.numChannels && SDL.numChannels >= num && num != 0) return; | |
SDL.numChannels = num; | |
SDL.channels = []; | |
for (var i = 0; i < num; i++) { | |
SDL.channels[i] = { | |
audio: null, | |
volume: 1.0 | |
}; | |
} | |
},setGetVolume:function (info, volume) { | |
if (!info) return 0; | |
var ret = info.volume * 128; // MIX_MAX_VOLUME | |
if (volume != -1) { | |
info.volume = Math.min(Math.max(volume, 0), 128) / 128; | |
if (info.audio) { | |
try { | |
info.audio.volume = info.volume; // For <audio> element | |
if (info.audio.webAudioGainNode) info.audio.webAudioGainNode['gain']['value'] = info.volume; // For WebAudio playback | |
} catch(e) { | |
Module.printErr('setGetVolume failed to set audio volume: ' + e); | |
} | |
} | |
} | |
return ret; | |
},setPannerPosition:function (info, x, y, z) { | |
if (!info) return 0; | |
if (info.audio) { | |
if (info.audio.webAudioPannerNode) | |
info.audio.webAudioPannerNode['setPosition'](x, y, z); | |
} | |
return ret; | |
},playWebAudio:function (audio) { | |
if (!audio) return; | |
if (audio.webAudioNode) return; // This instance is already playing, don't start again. | |
if (!SDL.webAudioAvailable()) return; | |
try { | |
var webAudio = audio.resource.webAudio; | |
audio.paused = false; | |
if (!webAudio.decodedBuffer) { | |
if (webAudio.onDecodeComplete === undefined) abort("Cannot play back audio object that was not loaded"); | |
webAudio.onDecodeComplete.push(function() { if (!audio.paused) SDL.playWebAudio(audio); }); | |
return; | |
} | |
audio.webAudioNode = SDL.audioContext['createBufferSource'](); | |
audio.webAudioNode['buffer'] = webAudio.decodedBuffer; | |
audio.webAudioNode['loop'] = audio.loop; | |
audio.webAudioNode['onended'] = function() { audio['onended'](); } // For <media> element compatibility, route the onended signal to the instance. | |
audio.webAudioPannerNode = SDL.audioContext['createPanner'](); | |
audio.webAudioPannerNode['panningModel'] = 'equalpower'; | |
// Add an intermediate gain node to control volume. | |
audio.webAudioGainNode = SDL.audioContext['createGain'](); | |
audio.webAudioGainNode['gain']['value'] = audio.volume; | |
audio.webAudioNode['connect'](audio.webAudioPannerNode); | |
audio.webAudioPannerNode['connect'](audio.webAudioGainNode); | |
audio.webAudioGainNode['connect'](SDL.audioContext['destination']); | |
audio.webAudioNode['start'](0, audio.currentPosition); | |
audio.startTime = SDL.audioContext['currentTime'] - audio.currentPosition; | |
} catch(e) { | |
Module.printErr('playWebAudio failed: ' + e); | |
} | |
},pauseWebAudio:function (audio) { | |
if (!audio) return; | |
if (audio.webAudioNode) { | |
try { | |
// Remember where we left off, so that if/when we resume, we can restart the playback at a proper place. | |
audio.currentPosition = (SDL.audioContext['currentTime'] - audio.startTime) % audio.resource.webAudio.decodedBuffer.duration; | |
// Important: When we reach here, the audio playback is stopped by the user. But when calling .stop() below, the Web Audio | |
// graph will send the onended signal, but we don't want to process that, since pausing should not clear/destroy the audio | |
// channel. | |
audio.webAudioNode['onended'] = undefined; | |
audio.webAudioNode.stop(); | |
audio.webAudioNode = undefined; | |
} catch(e) { | |
Module.printErr('pauseWebAudio failed: ' + e); | |
} | |
} | |
audio.paused = true; | |
},openAudioContext:function () { | |
// Initialize Web Audio API if we haven't done so yet. Note: Only initialize Web Audio context ever once on the web page, | |
// since initializing multiple times fails on Chrome saying 'audio resources have been exhausted'. | |
if (!SDL.audioContext) { | |
if (typeof(AudioContext) !== 'undefined') SDL.audioContext = new AudioContext(); | |
else if (typeof(webkitAudioContext) !== 'undefined') SDL.audioContext = new webkitAudioContext(); | |
} | |
},webAudioAvailable:function () { return !!SDL.audioContext; },fillWebAudioBufferFromHeap:function (heapPtr, sizeSamplesPerChannel, dstAudioBuffer) { | |
// The input audio data is interleaved across the channels, i.e. [L, R, L, R, L, R, ...] and is either 8-bit or 16-bit as | |
// supported by the SDL API. The output audio wave data for Web Audio API must be in planar buffers of [-1,1]-normalized Float32 data, | |
// so perform a buffer conversion for the data. | |
var numChannels = SDL.audio.channels; | |
for(var c = 0; c < numChannels; ++c) { | |
var channelData = dstAudioBuffer['getChannelData'](c); | |
if (channelData.length != sizeSamplesPerChannel) { | |
throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + sizeSamplesPerChannel + ' samples!'; | |
} | |
if (SDL.audio.format == 0x8010 /*AUDIO_S16LSB*/) { | |
for(var j = 0; j < sizeSamplesPerChannel; ++j) { | |
channelData[j] = (HEAP16[(((heapPtr)+((j*numChannels + c)*2))>>1)]) / 0x8000; | |
} | |
} else if (SDL.audio.format == 0x0008 /*AUDIO_U8*/) { | |
for(var j = 0; j < sizeSamplesPerChannel; ++j) { | |
var v = (HEAP8[(((heapPtr)+(j*numChannels + c))>>0)]); | |
channelData[j] = ((v >= 0) ? v-128 : v+128) /128; | |
} | |
} | |
} | |
},debugSurface:function (surfData) { | |
console.log('dumping surface ' + [surfData.surf, surfData.source, surfData.width, surfData.height]); | |
var image = surfData.ctx.getImageData(0, 0, surfData.width, surfData.height); | |
var data = image.data; | |
var num = Math.min(surfData.width, surfData.height); | |
for (var i = 0; i < num; i++) { | |
console.log(' diagonal ' + i + ':' + [data[i*surfData.width*4 + i*4 + 0], data[i*surfData.width*4 + i*4 + 1], data[i*surfData.width*4 + i*4 + 2], data[i*surfData.width*4 + i*4 + 3]]); | |
} | |
},joystickEventState:1,lastJoystickState:{},joystickNamePool:{},recordJoystickState:function (joystick, state) { | |
// Standardize button state. | |
var buttons = new Array(state.buttons.length); | |
for (var i = 0; i < state.buttons.length; i++) { | |
buttons[i] = SDL.getJoystickButtonState(state.buttons[i]); | |
} | |
SDL.lastJoystickState[joystick] = { | |
buttons: buttons, | |
axes: state.axes.slice(0), | |
timestamp: state.timestamp, | |
index: state.index, | |
id: state.id | |
}; | |
},getJoystickButtonState:function (button) { | |
if (typeof button === 'object') { | |
// Current gamepad API editor's draft (Firefox Nightly) | |
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#idl-def-GamepadButton | |
return button.pressed; | |
} else { | |
// Current gamepad API working draft (Firefox / Chrome Stable) | |
// http://www.w3.org/TR/2012/WD-gamepad-20120529/#gamepad-interface | |
return button > 0; | |
} | |
},queryJoysticks:function () { | |
for (var joystick in SDL.lastJoystickState) { | |
var state = SDL.getGamepad(joystick - 1); | |
var prevState = SDL.lastJoystickState[joystick]; | |
// Check only if the timestamp has differed. | |
// NOTE: Timestamp is not available in Firefox. | |
if (typeof state.timestamp !== 'number' || state.timestamp !== prevState.timestamp) { | |
var i; | |
for (i = 0; i < state.buttons.length; i++) { | |
var buttonState = SDL.getJoystickButtonState(state.buttons[i]); | |
// NOTE: The previous state already has a boolean representation of | |
// its button, so no need to standardize its button state here. | |
if (buttonState !== prevState.buttons[i]) { | |
// Insert button-press event. | |
SDL.events.push({ | |
type: buttonState ? 'joystick_button_down' : 'joystick_button_up', | |
joystick: joystick, | |
index: joystick - 1, | |
button: i | |
}); | |
} | |
} | |
for (i = 0; i < state.axes.length; i++) { | |
if (state.axes[i] !== prevState.axes[i]) { | |
// Insert axes-change event. | |
SDL.events.push({ | |
type: 'joystick_axis_motion', | |
joystick: joystick, | |
index: joystick - 1, | |
axis: i, | |
value: state.axes[i] | |
}); | |
} | |
} | |
SDL.recordJoystickState(joystick, state); | |
} | |
} | |
},joystickAxisValueConversion:function (value) { | |
// Ensures that 0 is 0, 1 is 32767, and -1 is 32768. | |
return Math.ceil(((value+1) * 32767.5) - 32768); | |
},getGamepads:function () { | |
var fcn = navigator.getGamepads || navigator.webkitGamepads || navigator.mozGamepads || navigator.gamepads || navigator.webkitGetGamepads; | |
if (fcn !== undefined) { | |
// The function must be applied on the navigator object. | |
return fcn.apply(navigator); | |
} else { | |
return []; | |
} | |
},getGamepad:function (deviceIndex) { | |
var gamepads = SDL.getGamepads(); | |
if (gamepads.length > deviceIndex && deviceIndex >= 0) { | |
return gamepads[deviceIndex]; | |
} | |
return null; | |
}};function _SDL_LockSurface(surf) { | |
var surfData = SDL.surfaces[surf]; | |
surfData.locked++; | |
if (surfData.locked > 1) return 0; | |
if (!surfData.buffer) { | |
surfData.buffer = _malloc(surfData.width * surfData.height * 4); | |
HEAP32[(((surf)+(20))>>2)]=surfData.buffer; | |
} | |
// Mark in C/C++-accessible SDL structure | |
// SDL_Surface has the following fields: Uint32 flags, SDL_PixelFormat *format; int w, h; Uint16 pitch; void *pixels; ... | |
// So we have fields all of the same size, and 5 of them before us. | |
// TODO: Use macros like in library.js | |
HEAP32[(((surf)+(20))>>2)]=surfData.buffer; | |
if (surf == SDL.screen && Module.screenIsReadOnly && surfData.image) return 0; | |
if (SDL.defaults.discardOnLock) { | |
if (!surfData.image) { | |
surfData.image = surfData.ctx.createImageData(surfData.width, surfData.height); | |
} | |
if (!SDL.defaults.opaqueFrontBuffer) return; | |
} else { | |
surfData.image = surfData.ctx.getImageData(0, 0, surfData.width, surfData.height); | |
} | |
// Emulate desktop behavior and kill alpha values on the locked surface. (very costly!) Set SDL.defaults.opaqueFrontBuffer = false | |
// if you don't want this. | |
if (surf == SDL.screen && SDL.defaults.opaqueFrontBuffer) { | |
var data = surfData.image.data; | |
var num = data.length; | |
for (var i = 0; i < num/4; i++) { | |
data[i*4+3] = 255; // opacity, as canvases blend alpha | |
} | |
} | |
if (SDL.defaults.copyOnLock && !SDL.defaults.discardOnLock) { | |
// Copy pixel data to somewhere accessible to 'C/C++' | |
if (surfData.isFlagSet(0x00200000 /* SDL_HWPALETTE */)) { | |
// If this is neaded then | |
// we should compact the data from 32bpp to 8bpp index. | |
// I think best way to implement this is use | |
// additional colorMap hash (color->index). | |
// Something like this: | |
// | |
// var size = surfData.width * surfData.height; | |
// var data = ''; | |
// for (var i = 0; i<size; i++) { | |
// var color = SDL.translateRGBAToColor( | |
// surfData.image.data[i*4 ], | |
// surfData.image.data[i*4 +1], | |
// surfData.image.data[i*4 +2], | |
// 255); | |
// var index = surfData.colorMap[color]; | |
// HEAP8[(((surfData.buffer)+(i))>>0)]=index; | |
// } | |
throw 'CopyOnLock is not supported for SDL_LockSurface with SDL_HWPALETTE flag set' + new Error().stack; | |
} else { | |
HEAPU8.set(surfData.image.data, surfData.buffer); | |
} | |
} | |
return 0; | |
} | |
Module["_strlen"] = _strlen; | |
function _emscripten_memcpy_big(dest, src, num) { | |
HEAPU8.set(HEAPU8.subarray(src, src+num), dest); | |
return dest; | |
} | |
Module["_memcpy"] = _memcpy; | |
function _emscripten_asm_const(code) { | |
Runtime.getAsmConst(code, 0)(); | |
} | |
function _SDL_UnlockSurface(surf) { | |
assert(!SDL.GL); // in GL mode we do not keep around 2D canvases and contexts | |
var surfData = SDL.surfaces[surf]; | |
if (!surfData.locked || --surfData.locked > 0) { | |
return; | |
} | |
// Copy pixel data to image | |
if (surfData.isFlagSet(0x00200000 /* SDL_HWPALETTE */)) { | |
SDL.copyIndexedColorData(surfData); | |
} else if (!surfData.colors) { | |
var data = surfData.image.data; | |
var buffer = surfData.buffer; | |
assert(buffer % 4 == 0, 'Invalid buffer offset: ' + buffer); | |
var src = buffer >> 2; | |
var dst = 0; | |
var isScreen = surf == SDL.screen; | |
var num; | |
if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { | |
// IE10/IE11: ImageData objects are backed by the deprecated CanvasPixelArray, | |
// not UInt8ClampedArray. These don't have buffers, so we need to revert | |
// to copying a byte at a time. We do the undefined check because modern | |
// browsers do not define CanvasPixelArray anymore. | |
num = data.length; | |
while (dst < num) { | |
var val = HEAP32[src]; // This is optimized. Instead, we could do HEAP32[(((buffer)+(dst))>>2)]; | |
data[dst ] = val & 0xff; | |
data[dst+1] = (val >> 8) & 0xff; | |
data[dst+2] = (val >> 16) & 0xff; | |
data[dst+3] = isScreen ? 0xff : ((val >> 24) & 0xff); | |
src++; | |
dst += 4; | |
} | |
} else { | |
var data32 = new Uint32Array(data.buffer); | |
if (isScreen && SDL.defaults.opaqueFrontBuffer) { | |
num = data32.length; | |
while (dst < num) { | |
// HEAP32[src++] is an optimization. Instead, we could do HEAP32[(((buffer)+(dst))>>2)]; | |
data32[dst++] = HEAP32[src++] | 0xff000000; | |
} | |
} else { | |
data32.set(HEAP32.subarray(src, src + data32.length)); | |
} | |
} | |
} else { | |
var width = Module['canvas'].width; | |
var height = Module['canvas'].height; | |
var s = surfData.buffer; | |
var data = surfData.image.data; | |
var colors = surfData.colors; // TODO: optimize using colors32 | |
for (var y = 0; y < height; y++) { | |
var base = y*width*4; | |
for (var x = 0; x < width; x++) { | |
// See comment above about signs | |
var val = HEAPU8[((s++)>>0)] * 4; | |
var start = base + x*4; | |
data[start] = colors[val]; | |
data[start+1] = colors[val+1]; | |
data[start+2] = colors[val+2]; | |
} | |
s += width*3; | |
} | |
} | |
// Copy to canvas | |
surfData.ctx.putImageData(surfData.image, 0, 0); | |
// Note that we save the image, so future writes are fast. But, memory is not yet released | |
} | |
function _sbrk(bytes) { | |
// Implement a Linux-like 'memory area' for our 'process'. | |
// Changes the size of the memory area by |bytes|; returns the | |
// address of the previous top ('break') of the memory area | |
// We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP | |
var self = _sbrk; | |
if (!self.called) { | |
DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned | |
self.called = true; | |
assert(Runtime.dynamicAlloc); | |
self.alloc = Runtime.dynamicAlloc; | |
Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') }; | |
} | |
var ret = DYNAMICTOP; | |
if (bytes != 0) self.alloc(bytes); | |
return ret; // Previous break location. | |
} | |
function _SDL_Init(initFlags) { | |
SDL.startTime = Date.now(); | |
SDL.initFlags = initFlags; | |
// capture all key events. we just keep down and up, but also capture press to prevent default actions | |
if (!Module['doNotCaptureKeyboard']) { | |
var keyboardListeningElement = Module['keyboardListeningElement'] || document; | |
keyboardListeningElement.addEventListener("keydown", SDL.receiveEvent); | |
keyboardListeningElement.addEventListener("keyup", SDL.receiveEvent); | |
keyboardListeningElement.addEventListener("keypress", SDL.receiveEvent); | |
window.addEventListener("focus", SDL.receiveEvent); | |
window.addEventListener("blur", SDL.receiveEvent); | |
document.addEventListener("visibilitychange", SDL.receiveEvent); | |
} | |
if (initFlags & 0x200) { | |
// SDL_INIT_JOYSTICK | |
// Firefox will not give us Joystick data unless we register this NOP | |
// callback. | |
// https://bugzilla.mozilla.org/show_bug.cgi?id=936104 | |
addEventListener("gamepadconnected", function() {}); | |
} | |
window.addEventListener("unload", SDL.receiveEvent); | |
SDL.keyboardState = _malloc(0x10000); // Our SDL needs 512, but 64K is safe for older SDLs | |
_memset(SDL.keyboardState, 0, 0x10000); | |
// Initialize this structure carefully for closure | |
SDL.DOMEventToSDLEvent['keydown'] = 0x300 /* SDL_KEYDOWN */; | |
SDL.DOMEventToSDLEvent['keyup'] = 0x301 /* SDL_KEYUP */; | |
SDL.DOMEventToSDLEvent['keypress'] = 0x303 /* SDL_TEXTINPUT */; | |
SDL.DOMEventToSDLEvent['mousedown'] = 0x401 /* SDL_MOUSEBUTTONDOWN */; | |
SDL.DOMEventToSDLEvent['mouseup'] = 0x402 /* SDL_MOUSEBUTTONUP */; | |
SDL.DOMEventToSDLEvent['mousemove'] = 0x400 /* SDL_MOUSEMOTION */; | |
SDL.DOMEventToSDLEvent['wheel'] = 0x403 /* SDL_MOUSEWHEEL */; | |
SDL.DOMEventToSDLEvent['touchstart'] = 0x700 /* SDL_FINGERDOWN */; | |
SDL.DOMEventToSDLEvent['touchend'] = 0x701 /* SDL_FINGERUP */; | |
SDL.DOMEventToSDLEvent['touchmove'] = 0x702 /* SDL_FINGERMOTION */; | |
SDL.DOMEventToSDLEvent['unload'] = 0x100 /* SDL_QUIT */; | |
SDL.DOMEventToSDLEvent['resize'] = 0x7001 /* SDL_VIDEORESIZE/SDL_EVENT_COMPAT2 */; | |
SDL.DOMEventToSDLEvent['visibilitychange'] = 0x200 /* SDL_WINDOWEVENT */; | |
SDL.DOMEventToSDLEvent['focus'] = 0x200 /* SDL_WINDOWEVENT */; | |
SDL.DOMEventToSDLEvent['blur'] = 0x200 /* SDL_WINDOWEVENT */; | |
// These are not technically DOM events; the HTML gamepad API is poll-based. | |
// However, we define them here, as the rest of the SDL code assumes that | |
// all SDL events originate as DOM events. | |
SDL.DOMEventToSDLEvent['joystick_axis_motion'] = 0x600 /* SDL_JOYAXISMOTION */; | |
SDL.DOMEventToSDLEvent['joystick_button_down'] = 0x603 /* SDL_JOYBUTTONDOWN */; | |
SDL.DOMEventToSDLEvent['joystick_button_up'] = 0x604 /* SDL_JOYBUTTONUP */; | |
return 0; // success | |
} | |
function ___errno_location() { | |
return ___errno_state; | |
} | |
function _SDL_AudioQuit() { | |
for (var i = 0; i < SDL.numChannels; ++i) { | |
if (SDL.channels[i].audio) { | |
SDL.channels[i].audio.pause(); | |
SDL.channels[i].audio = undefined; | |
} | |
} | |
if (SDL.music.audio) SDL.music.audio.pause(); | |
SDL.music.audio = undefined; | |
}function _SDL_Quit() { | |
_SDL_AudioQuit(); | |
Module.print('SDL_Quit called (and ignored)'); | |
} | |
function _time(ptr) { | |
var ret = (Date.now()/1000)|0; | |
if (ptr) { | |
HEAP32[((ptr)>>2)]=ret; | |
} | |
return ret; | |
} | |
___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0; | |
var GLctx; GL.init() | |
FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice; | |
__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor(); | |
if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); } | |
Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) }; | |
Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) }; | |
Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) }; | |
Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() }; | |
Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() }; | |
Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() } | |
___buildEnvironment(ENV); | |
STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP); | |
staticSealed = true; // seal the static portion of memory | |
STACK_MAX = STACK_BASE + TOTAL_STACK; | |
DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX); | |
assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack"); | |
Module.asmGlobalArg = { "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }; | |
Module.asmLibraryArg = { "abort": abort, "assert": assert, "min": Math_min, "_putenv": _putenv, "_emscripten_asm_const": _emscripten_asm_const, "_SDL_SetVideoMode": _SDL_SetVideoMode, "_IMG_Load": _IMG_Load, "_TTF_FontHeight": _TTF_FontHeight, "_SDL_CloseAudio": _SDL_CloseAudio, "_SDL_PauseAudio": _SDL_PauseAudio, "_SDL_GetTicks": _SDL_GetTicks, "___buildEnvironment": ___buildEnvironment, "_fflush": _fflush, "_SDL_LockSurface": _SDL_LockSurface, "___setErrNo": ___setErrNo, "_emscripten_set_main_loop_timing": _emscripten_set_main_loop_timing, "_sbrk": _sbrk, "_SDL_Init": _SDL_Init, "_Mix_PlayChannel": _Mix_PlayChannel, "_TTF_RenderText_Solid": _TTF_RenderText_Solid, "_Mix_LoadWAV_RW": _Mix_LoadWAV_RW, "_sysconf": _sysconf, "_IMG_Load_RW": _IMG_Load_RW, "_Mix_PlayMusic": _Mix_PlayMusic, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_getenv": _getenv, "_Mix_FreeChunk": _Mix_FreeChunk, "_SDL_UpperBlitScaled": _SDL_UpperBlitScaled, "_SDL_AudioQuit": _SDL_AudioQuit, "_emscripten_set_main_loop": _emscripten_set_main_loop, "___errno_location": ___errno_location, "_SDL_UnlockSurface": _SDL_UnlockSurface, "_abort": _abort, "_time": _time, "_Mix_HaltMusic": _Mix_HaltMusic, "_SDL_FreeRW": _SDL_FreeRW, "_SDL_UpperBlit": _SDL_UpperBlit, "_SDL_RWFromConstMem": _SDL_RWFromConstMem, "_SDL_Quit": _SDL_Quit, "_SDL_RWFromFile": _SDL_RWFromFile, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity }; | |
// EMSCRIPTEN_START_ASM | |
var asm = (function(global, env, buffer) { | |
'almost asm'; | |
var HEAP8 = new global.Int8Array(buffer); | |
var HEAP16 = new global.Int16Array(buffer); | |
var HEAP32 = new global.Int32Array(buffer); | |
var HEAPU8 = new global.Uint8Array(buffer); | |
var HEAPU16 = new global.Uint16Array(buffer); | |
var HEAPU32 = new global.Uint32Array(buffer); | |
var HEAPF32 = new global.Float32Array(buffer); | |
var HEAPF64 = new global.Float64Array(buffer); | |
var STACKTOP=env.STACKTOP|0; | |
var STACK_MAX=env.STACK_MAX|0; | |
var tempDoublePtr=env.tempDoublePtr|0; | |
var ABORT=env.ABORT|0; | |
var __THREW__ = 0; | |
var threwValue = 0; | |
var setjmpId = 0; | |
var undef = 0; | |
var nan = +env.NaN, inf = +env.Infinity; | |
var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0; | |
var tempRet0 = 0; | |
var tempRet1 = 0; | |
var tempRet2 = 0; | |
var tempRet3 = 0; | |
var tempRet4 = 0; | |
var tempRet5 = 0; | |
var tempRet6 = 0; | |
var tempRet7 = 0; | |
var tempRet8 = 0; | |
var tempRet9 = 0; | |
var Math_floor=global.Math.floor; | |
var Math_abs=global.Math.abs; | |
var Math_sqrt=global.Math.sqrt; | |
var Math_pow=global.Math.pow; | |
var Math_cos=global.Math.cos; | |
var Math_sin=global.Math.sin; | |
var Math_tan=global.Math.tan; | |
var Math_acos=global.Math.acos; | |
var Math_asin=global.Math.asin; | |
var Math_atan=global.Math.atan; | |
var Math_atan2=global.Math.atan2; | |
var Math_exp=global.Math.exp; | |
var Math_log=global.Math.log; | |
var Math_ceil=global.Math.ceil; | |
var Math_imul=global.Math.imul; | |
var abort=env.abort; | |
var assert=env.assert; | |
var Math_min=env.min; | |
var _putenv=env._putenv; | |
var _emscripten_asm_const=env._emscripten_asm_const; | |
var _SDL_SetVideoMode=env._SDL_SetVideoMode; | |
var _IMG_Load=env._IMG_Load; | |
var _TTF_FontHeight=env._TTF_FontHeight; | |
var _SDL_CloseAudio=env._SDL_CloseAudio; | |
var _SDL_PauseAudio=env._SDL_PauseAudio; | |
var _SDL_GetTicks=env._SDL_GetTicks; | |
var ___buildEnvironment=env.___buildEnvironment; | |
var _fflush=env._fflush; | |
var _SDL_LockSurface=env._SDL_LockSurface; | |
var ___setErrNo=env.___setErrNo; | |
var _emscripten_set_main_loop_timing=env._emscripten_set_main_loop_timing; | |
var _sbrk=env._sbrk; | |
var _SDL_Init=env._SDL_Init; | |
var _Mix_PlayChannel=env._Mix_PlayChannel; | |
var _TTF_RenderText_Solid=env._TTF_RenderText_Solid; | |
var _Mix_LoadWAV_RW=env._Mix_LoadWAV_RW; | |
var _sysconf=env._sysconf; | |
var _IMG_Load_RW=env._IMG_Load_RW; | |
var _Mix_PlayMusic=env._Mix_PlayMusic; | |
var _emscripten_memcpy_big=env._emscripten_memcpy_big; | |
var _getenv=env._getenv; | |
var _Mix_FreeChunk=env._Mix_FreeChunk; | |
var _SDL_UpperBlitScaled=env._SDL_UpperBlitScaled; | |
var _SDL_AudioQuit=env._SDL_AudioQuit; | |
var _emscripten_set_main_loop=env._emscripten_set_main_loop; | |
var ___errno_location=env.___errno_location; | |
var _SDL_UnlockSurface=env._SDL_UnlockSurface; | |
var _abort=env._abort; | |
var _time=env._time; | |
var _Mix_HaltMusic=env._Mix_HaltMusic; | |
var _SDL_FreeRW=env._SDL_FreeRW; | |
var _SDL_UpperBlit=env._SDL_UpperBlit; | |
var _SDL_RWFromConstMem=env._SDL_RWFromConstMem; | |
var _SDL_Quit=env._SDL_Quit; | |
var _SDL_RWFromFile=env._SDL_RWFromFile; | |
var tempFloat = 0.0; | |
// EMSCRIPTEN_START_FUNCS | |
function stackAlloc(size) { | |
size = size|0; | |
var ret = 0; | |
ret = STACKTOP; | |
STACKTOP = (STACKTOP + size)|0; | |
STACKTOP = (STACKTOP + 15)&-16; | |
if ((STACKTOP|0) >= (STACK_MAX|0)) abort(); | |
return ret|0; | |
} | |
function stackSave() { | |
return STACKTOP|0; | |
} | |
function stackRestore(top) { | |
top = top|0; | |
STACKTOP = top; | |
} | |
function setThrew(threw, value) { | |
threw = threw|0; | |
value = value|0; | |
if ((__THREW__|0) == 0) { | |
__THREW__ = threw; | |
threwValue = value; | |
} | |
} | |
function copyTempFloat(ptr) { | |
ptr = ptr|0; | |
HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0]; | |
HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0]; | |
HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0]; | |
HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0]; | |
} | |
function copyTempDouble(ptr) { | |
ptr = ptr|0; | |
HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0]; | |
HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0]; | |
HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0]; | |
HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0]; | |
HEAP8[tempDoublePtr+4>>0] = HEAP8[ptr+4>>0]; | |
HEAP8[tempDoublePtr+5>>0] = HEAP8[ptr+5>>0]; | |
HEAP8[tempDoublePtr+6>>0] = HEAP8[ptr+6>>0]; | |
HEAP8[tempDoublePtr+7>>0] = HEAP8[ptr+7>>0]; | |
} | |
function setTempRet0(value) { | |
value = value|0; | |
tempRet0 = value; | |
} | |
function getTempRet0() { | |
return tempRet0|0; | |
} | |
function _main($argc,$argv) { | |
$argc = $argc|0; | |
$argv = $argv|0; | |
var $0 = 0, $1 = 0, $10 = 0, $11 = 0, $12 = 0, $13 = 0, $14 = 0, $15 = 0, $16 = 0, $17 = 0, $18 = 0, $19 = 0, $2 = 0, $20 = 0, $21 = 0, $22 = 0, $23 = 0, $24 = 0, $25 = 0, $26 = 0; | |
var $27 = 0, $28 = 0, $29 = 0, $3 = 0, $30 = 0, $31 = 0, $32 = 0, $33 = 0, $34 = 0, $35 = 0, $36 = 0, $37 = 0, $38 = 0, $39 = 0, $4 = 0, $40 = 0, $41 = 0, $42 = 0, $43 = 0, $44 = 0; | |
var $5 = 0, $6 = 0, $7 = 0, $8 = 0, $9 = 0, $pixels = 0, $screen = 0, $x = 0, $y = 0, label = 0, sp = 0; | |
sp = STACKTOP; | |
STACKTOP = STACKTOP + 32|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort(); | |
$0 = 0; | |
$1 = $argc; | |
$2 = $argv; | |
(_SDL_Init(32)|0); | |
$3 = (_SDL_SetVideoMode(600,450,32,134217729)|0); | |
$screen = $3; | |
$4 = $screen; | |
(_SDL_LockSurface(($4|0))|0); | |
$5 = $screen; | |
$6 = (($5) + 20|0); | |
$7 = HEAP32[$6>>2]|0; | |
$pixels = $7; | |
$x = 0; | |
while(1) { | |
$8 = $x; | |
$9 = $screen; | |
$10 = (($9) + 8|0); | |
$11 = HEAP32[$10>>2]|0; | |
$12 = ($8|0)<($11|0); | |
if (!($12)) { | |
break; | |
} | |
$y = 0; | |
while(1) { | |
$13 = $y; | |
$14 = $screen; | |
$15 = (($14) + 12|0); | |
$16 = HEAP32[$15>>2]|0; | |
$17 = ($13|0)<($16|0); | |
if (!($17)) { | |
break; | |
} | |
$18 = $x; | |
$19 = ($18|0)<(300); | |
if ($19) { | |
$20 = $y; | |
$21 = ($20|0)<(200); | |
$22 = $21 ? 863480456 : -1439467572; | |
$35 = $22; | |
} else { | |
$23 = $y; | |
$24 = ($23|0)<(200); | |
$25 = $24 ? 6728311 : -1442814311; | |
$35 = $25; | |
} | |
$26 = $x; | |
$27 = $y; | |
$28 = $screen; | |
$29 = (($28) + 12|0); | |
$30 = HEAP32[$29>>2]|0; | |
$31 = Math_imul($27, $30)|0; | |
$32 = (($26) + ($31))|0; | |
$33 = $pixels; | |
$34 = (($33) + ($32<<2)|0); | |
HEAP32[$34>>2] = $35; | |
$36 = $y; | |
$37 = (($36) + 1)|0; | |
$y = $37; | |
} | |
$38 = $x; | |
$39 = (($38) + 1)|0; | |
$x = $39; | |
} | |
$40 = $screen; | |
_SDL_UnlockSurface(($40|0)); | |
$41 = $screen; | |
(_SDL_LockSurface(($41|0))|0); | |
$42 = $screen; | |
_SDL_UnlockSurface(($42|0)); | |
$43 = $screen; | |
(_SDL_LockSurface(($43|0))|0); | |
$44 = $screen; | |
_SDL_UnlockSurface(($44|0)); | |
_SDL_Quit(); | |
_emscripten_asm_const((8|0)); | |
STACKTOP = sp;return 0; | |
} | |
function _malloc($bytes) { | |
$bytes = $bytes|0; | |
var $$$i = 0, $$3$i = 0, $$4$i = 0, $$pre = 0, $$pre$i = 0, $$pre$i$i = 0, $$pre$i25 = 0, $$pre$i25$i = 0, $$pre$phi$i$iZ2D = 0, $$pre$phi$i26$iZ2D = 0, $$pre$phi$i26Z2D = 0, $$pre$phi$iZ2D = 0, $$pre$phi58$i$iZ2D = 0, $$pre$phiZ2D = 0, $$pre57$i$i = 0, $$rsize$0$i = 0, $$rsize$3$i = 0, $$sum = 0, $$sum$i$i = 0, $$sum$i$i$i = 0; | |
var $$sum$i14$i = 0, $$sum$i15$i = 0, $$sum$i18$i = 0, $$sum$i21$i = 0, $$sum$i2334 = 0, $$sum$i32 = 0, $$sum$i35 = 0, $$sum1 = 0, $$sum1$i = 0, $$sum1$i$i = 0, $$sum1$i16$i = 0, $$sum1$i22$i = 0, $$sum1$i24 = 0, $$sum10 = 0, $$sum10$i = 0, $$sum10$i$i = 0, $$sum10$pre$i$i = 0, $$sum107$i = 0, $$sum108$i = 0, $$sum109$i = 0; | |
var $$sum11$i = 0, $$sum11$i$i = 0, $$sum11$i24$i = 0, $$sum110$i = 0, $$sum111$i = 0, $$sum1112 = 0, $$sum112$i = 0, $$sum113$i = 0, $$sum114$i = 0, $$sum115$i = 0, $$sum116$i = 0, $$sum117$i = 0, $$sum118$i = 0, $$sum119$i = 0, $$sum12$i = 0, $$sum12$i$i = 0, $$sum120$i = 0, $$sum13$i = 0, $$sum13$i$i = 0, $$sum14$i$i = 0; | |
var $$sum14$pre$i = 0, $$sum15$i = 0, $$sum15$i$i = 0, $$sum16$i = 0, $$sum16$i$i = 0, $$sum17$i = 0, $$sum17$i$i = 0, $$sum18$i = 0, $$sum1819$i$i = 0, $$sum2 = 0, $$sum2$i = 0, $$sum2$i$i = 0, $$sum2$i$i$i = 0, $$sum2$i17$i = 0, $$sum2$i19$i = 0, $$sum2$i23$i = 0, $$sum2$pre$i = 0, $$sum20$i$i = 0, $$sum21$i$i = 0, $$sum22$i$i = 0; | |
var $$sum23$i$i = 0, $$sum24$i$i = 0, $$sum25$i$i = 0, $$sum26$pre$i$i = 0, $$sum27$i$i = 0, $$sum28$i$i = 0, $$sum29$i$i = 0, $$sum3$i = 0, $$sum3$i$i = 0, $$sum3$i27 = 0, $$sum30$i$i = 0, $$sum3132$i$i = 0, $$sum34$i$i = 0, $$sum3536$i$i = 0, $$sum3738$i$i = 0, $$sum39$i$i = 0, $$sum4 = 0, $$sum4$i = 0, $$sum4$i28 = 0, $$sum40$i$i = 0; | |
var $$sum41$i$i = 0, $$sum42$i$i = 0, $$sum5$i = 0, $$sum5$i$i = 0, $$sum56 = 0, $$sum6$i = 0, $$sum67$i$i = 0, $$sum7$i = 0, $$sum8$i = 0, $$sum8$pre = 0, $$sum9 = 0, $$sum9$i = 0, $$sum9$i$i = 0, $$tsize$1$i = 0, $$v$0$i = 0, $0 = 0, $1 = 0, $10 = 0, $100 = 0, $1000 = 0; | |
var $1001 = 0, $1002 = 0, $1003 = 0, $1004 = 0, $1005 = 0, $1006 = 0, $1007 = 0, $1008 = 0, $1009 = 0, $101 = 0, $1010 = 0, $1011 = 0, $1012 = 0, $1013 = 0, $1014 = 0, $1015 = 0, $1016 = 0, $1017 = 0, $1018 = 0, $1019 = 0; | |
var $102 = 0, $1020 = 0, $1021 = 0, $1022 = 0, $1023 = 0, $1024 = 0, $1025 = 0, $1026 = 0, $1027 = 0, $1028 = 0, $1029 = 0, $103 = 0, $1030 = 0, $1031 = 0, $1032 = 0, $1033 = 0, $1034 = 0, $1035 = 0, $1036 = 0, $1037 = 0; | |
var $1038 = 0, $1039 = 0, $104 = 0, $1040 = 0, $1041 = 0, $1042 = 0, $1043 = 0, $1044 = 0, $1045 = 0, $1046 = 0, $1047 = 0, $1048 = 0, $1049 = 0, $105 = 0, $1050 = 0, $1051 = 0, $1052 = 0, $1053 = 0, $1054 = 0, $1055 = 0; | |
var $1056 = 0, $1057 = 0, $1058 = 0, $1059 = 0, $106 = 0, $1060 = 0, $1061 = 0, $1062 = 0, $1063 = 0, $1064 = 0, $1065 = 0, $1066 = 0, $1067 = 0, $1068 = 0, $1069 = 0, $107 = 0, $1070 = 0, $1071 = 0, $1072 = 0, $1073 = 0; | |
var $1074 = 0, $1075 = 0, $1076 = 0, $1077 = 0, $1078 = 0, $1079 = 0, $108 = 0, $109 = 0, $11 = 0, $110 = 0, $111 = 0, $112 = 0, $113 = 0, $114 = 0, $115 = 0, $116 = 0, $117 = 0, $118 = 0, $119 = 0, $12 = 0; | |
var $120 = 0, $121 = 0, $122 = 0, $123 = 0, $124 = 0, $125 = 0, $126 = 0, $127 = 0, $128 = 0, $129 = 0, $13 = 0, $130 = 0, $131 = 0, $132 = 0, $133 = 0, $134 = 0, $135 = 0, $136 = 0, $137 = 0, $138 = 0; | |
var $139 = 0, $14 = 0, $140 = 0, $141 = 0, $142 = 0, $143 = 0, $144 = 0, $145 = 0, $146 = 0, $147 = 0, $148 = 0, $149 = 0, $15 = 0, $150 = 0, $151 = 0, $152 = 0, $153 = 0, $154 = 0, $155 = 0, $156 = 0; | |
var $157 = 0, $158 = 0, $159 = 0, $16 = 0, $160 = 0, $161 = 0, $162 = 0, $163 = 0, $164 = 0, $165 = 0, $166 = 0, $167 = 0, $168 = 0, $169 = 0, $17 = 0, $170 = 0, $171 = 0, $172 = 0, $173 = 0, $174 = 0; | |
var $175 = 0, $176 = 0, $177 = 0, $178 = 0, $179 = 0, $18 = 0, $180 = 0, $181 = 0, $182 = 0, $183 = 0, $184 = 0, $185 = 0, $186 = 0, $187 = 0, $188 = 0, $189 = 0, $19 = 0, $190 = 0, $191 = 0, $192 = 0; | |
var $193 = 0, $194 = 0, $195 = 0, $196 = 0, $197 = 0, $198 = 0, $199 = 0, $2 = 0, $20 = 0, $200 = 0, $201 = 0, $202 = 0, $203 = 0, $204 = 0, $205 = 0, $206 = 0, $207 = 0, $208 = 0, $209 = 0, $21 = 0; | |
var $210 = 0, $211 = 0, $212 = 0, $213 = 0, $214 = 0, $215 = 0, $216 = 0, $217 = 0, $218 = 0, $219 = 0, $22 = 0, $220 = 0, $221 = 0, $222 = 0, $223 = 0, $224 = 0, $225 = 0, $226 = 0, $227 = 0, $228 = 0; | |
var $229 = 0, $23 = 0, $230 = 0, $231 = 0, $232 = 0, $233 = 0, $234 = 0, $235 = 0, $236 = 0, $237 = 0, $238 = 0, $239 = 0, $24 = 0, $240 = 0, $241 = 0, $242 = 0, $243 = 0, $244 = 0, $245 = 0, $246 = 0; | |
var $247 = 0, $248 = 0, $249 = 0, $25 = 0, $250 = 0, $251 = 0, $252 = 0, $253 = 0, $254 = 0, $255 = 0, $256 = 0, $257 = 0, $258 = 0, $259 = 0, $26 = 0, $260 = 0, $261 = 0, $262 = 0, $263 = 0, $264 = 0; | |
var $265 = 0, $266 = 0, $267 = 0, $268 = 0, $269 = 0, $27 = 0, $270 = 0, $271 = 0, $272 = 0, $273 = 0, $274 = 0, $275 = 0, $276 = 0, $277 = 0, $278 = 0, $279 = 0, $28 = 0, $280 = 0, $281 = 0, $282 = 0; | |
var $283 = 0, $284 = 0, $285 = 0, $286 = 0, $287 = 0, $288 = 0, $289 = 0, $29 = 0, $290 = 0, $291 = 0, $292 = 0, $293 = 0, $294 = 0, $295 = 0, $296 = 0, $297 = 0, $298 = 0, $299 = 0, $3 = 0, $30 = 0; | |
var $300 = 0, $301 = 0, $302 = 0, $303 = 0, $304 = 0, $305 = 0, $306 = 0, $307 = 0, $308 = 0, $309 = 0, $31 = 0, $310 = 0, $311 = 0, $312 = 0, $313 = 0, $314 = 0, $315 = 0, $316 = 0, $317 = 0, $318 = 0; | |
var $319 = 0, $32 = 0, $320 = 0, $321 = 0, $322 = 0, $323 = 0, $324 = 0, $325 = 0, $326 = 0, $327 = 0, $328 = 0, $329 = 0, $33 = 0, $330 = 0, $331 = 0, $332 = 0, $333 = 0, $334 = 0, $335 = 0, $336 = 0; | |
var $337 = 0, $338 = 0, $339 = 0, $34 = 0, $340 = 0, $341 = 0, $342 = 0, $343 = 0, $344 = 0, $345 = 0, $346 = 0, $347 = 0, $348 = 0, $349 = 0, $35 = 0, $350 = 0, $351 = 0, $352 = 0, $353 = 0, $354 = 0; | |
var $355 = 0, $356 = 0, $357 = 0, $358 = 0, $359 = 0, $36 = 0, $360 = 0, $361 = 0, $362 = 0, $363 = 0, $364 = 0, $365 = 0, $366 = 0, $367 = 0, $368 = 0, $369 = 0, $37 = 0, $370 = 0, $371 = 0, $372 = 0; | |
var $373 = 0, $374 = 0, $375 = 0, $376 = 0, $377 = 0, $378 = 0, $379 = 0, $38 = 0, $380 = 0, $381 = 0, $382 = 0, $383 = 0, $384 = 0, $385 = 0, $386 = 0, $387 = 0, $388 = 0, $389 = 0, $39 = 0, $390 = 0; | |
var $391 = 0, $392 = 0, $393 = 0, $394 = 0, $395 = 0, $396 = 0, $397 = 0, $398 = 0, $399 = 0, $4 = 0, $40 = 0, $400 = 0, $401 = 0, $402 = 0, $403 = 0, $404 = 0, $405 = 0, $406 = 0, $407 = 0, $408 = 0; | |
var $409 = 0, $41 = 0, $410 = 0, $411 = 0, $412 = 0, $413 = 0, $414 = 0, $415 = 0, $416 = 0, $417 = 0, $418 = 0, $419 = 0, $42 = 0, $420 = 0, $421 = 0, $422 = 0, $423 = 0, $424 = 0, $425 = 0, $426 = 0; | |
var $427 = 0, $428 = 0, $429 = 0, $43 = 0, $430 = 0, $431 = 0, $432 = 0, $433 = 0, $434 = 0, $435 = 0, $436 = 0, $437 = 0, $438 = 0, $439 = 0, $44 = 0, $440 = 0, $441 = 0, $442 = 0, $443 = 0, $444 = 0; | |
var $445 = 0, $446 = 0, $447 = 0, $448 = 0, $449 = 0, $45 = 0, $450 = 0, $451 = 0, $452 = 0, $453 = 0, $454 = 0, $455 = 0, $456 = 0, $457 = 0, $458 = 0, $459 = 0, $46 = 0, $460 = 0, $461 = 0, $462 = 0; | |
var $463 = 0, $464 = 0, $465 = 0, $466 = 0, $467 = 0, $468 = 0, $469 = 0, $47 = 0, $470 = 0, $471 = 0, $472 = 0, $473 = 0, $474 = 0, $475 = 0, $476 = 0, $477 = 0, $478 = 0, $479 = 0, $48 = 0, $480 = 0; | |
var $481 = 0, $482 = 0, $483 = 0, $484 = 0, $485 = 0, $486 = 0, $487 = 0, $488 = 0, $489 = 0, $49 = 0, $490 = 0, $491 = 0, $492 = 0, $493 = 0, $494 = 0, $495 = 0, $496 = 0, $497 = 0, $498 = 0, $499 = 0; | |
var $5 = 0, $50 = 0, $500 = 0, $501 = 0, $502 = 0, $503 = 0, $504 = 0, $505 = 0, $506 = 0, $507 = 0, $508 = 0, $509 = 0, $51 = 0, $510 = 0, $511 = 0, $512 = 0, $513 = 0, $514 = 0, $515 = 0, $516 = 0; | |
var $517 = 0, $518 = 0, $519 = 0, $52 = 0, $520 = 0, $521 = 0, $522 = 0, $523 = 0, $524 = 0, $525 = 0, $526 = 0, $527 = 0, $528 = 0, $529 = 0, $53 = 0, $530 = 0, $531 = 0, $532 = 0, $533 = 0, $534 = 0; | |
var $535 = 0, $536 = 0, $537 = 0, $538 = 0, $539 = 0, $54 = 0, $540 = 0, $541 = 0, $542 = 0, $543 = 0, $544 = 0, $545 = 0, $546 = 0, $547 = 0, $548 = 0, $549 = 0, $55 = 0, $550 = 0, $551 = 0, $552 = 0; | |
var $553 = 0, $554 = 0, $555 = 0, $556 = 0, $557 = 0, $558 = 0, $559 = 0, $56 = 0, $560 = 0, $561 = 0, $562 = 0, $563 = 0, $564 = 0, $565 = 0, $566 = 0, $567 = 0, $568 = 0, $569 = 0, $57 = 0, $570 = 0; | |
var $571 = 0, $572 = 0, $573 = 0, $574 = 0, $575 = 0, $576 = 0, $577 = 0, $578 = 0, $579 = 0, $58 = 0, $580 = 0, $581 = 0, $582 = 0, $583 = 0, $584 = 0, $585 = 0, $586 = 0, $587 = 0, $588 = 0, $589 = 0; | |
var $59 = 0, $590 = 0, $591 = 0, $592 = 0, $593 = 0, $594 = 0, $595 = 0, $596 = 0, $597 = 0, $598 = 0, $599 = 0, $6 = 0, $60 = 0, $600 = 0, $601 = 0, $602 = 0, $603 = 0, $604 = 0, $605 = 0, $606 = 0; | |
var $607 = 0, $608 = 0, $609 = 0, $61 = 0, $610 = 0, $611 = 0, $612 = 0, $613 = 0, $614 = 0, $615 = 0, $616 = 0, $617 = 0, $618 = 0, $619 = 0, $62 = 0, $620 = 0, $621 = 0, $622 = 0, $623 = 0, $624 = 0; | |
var $625 = 0, $626 = 0, $627 = 0, $628 = 0, $629 = 0, $63 = 0, $630 = 0, $631 = 0, $632 = 0, $633 = 0, $634 = 0, $635 = 0, $636 = 0, $637 = 0, $638 = 0, $639 = 0, $64 = 0, $640 = 0, $641 = 0, $642 = 0; | |
var $643 = 0, $644 = 0, $645 = 0, $646 = 0, $647 = 0, $648 = 0, $649 = 0, $65 = 0, $650 = 0, $651 = 0, $652 = 0, $653 = 0, $654 = 0, $655 = 0, $656 = 0, $657 = 0, $658 = 0, $659 = 0, $66 = 0, $660 = 0; | |
var $661 = 0, $662 = 0, $663 = 0, $664 = 0, $665 = 0, $666 = 0, $667 = 0, $668 = 0, $669 = 0, $67 = 0, $670 = 0, $671 = 0, $672 = 0, $673 = 0, $674 = 0, $675 = 0, $676 = 0, $677 = 0, $678 = 0, $679 = 0; | |
var $68 = 0, $680 = 0, $681 = 0, $682 = 0, $683 = 0, $684 = 0, $685 = 0, $686 = 0, $687 = 0, $688 = 0, $689 = 0, $69 = 0, $690 = 0, $691 = 0, $692 = 0, $693 = 0, $694 = 0, $695 = 0, $696 = 0, $697 = 0; | |
var $698 = 0, $699 = 0, $7 = 0, $70 = 0, $700 = 0, $701 = 0, $702 = 0, $703 = 0, $704 = 0, $705 = 0, $706 = 0, $707 = 0, $708 = 0, $709 = 0, $71 = 0, $710 = 0, $711 = 0, $712 = 0, $713 = 0, $714 = 0; | |
var $715 = 0, $716 = 0, $717 = 0, $718 = 0, $719 = 0, $72 = 0, $720 = 0, $721 = 0, $722 = 0, $723 = 0, $724 = 0, $725 = 0, $726 = 0, $727 = 0, $728 = 0, $729 = 0, $73 = 0, $730 = 0, $731 = 0, $732 = 0; | |
var $733 = 0, $734 = 0, $735 = 0, $736 = 0, $737 = 0, $738 = 0, $739 = 0, $74 = 0, $740 = 0, $741 = 0, $742 = 0, $743 = 0, $744 = 0, $745 = 0, $746 = 0, $747 = 0, $748 = 0, $749 = 0, $75 = 0, $750 = 0; | |
var $751 = 0, $752 = 0, $753 = 0, $754 = 0, $755 = 0, $756 = 0, $757 = 0, $758 = 0, $759 = 0, $76 = 0, $760 = 0, $761 = 0, $762 = 0, $763 = 0, $764 = 0, $765 = 0, $766 = 0, $767 = 0, $768 = 0, $769 = 0; | |
var $77 = 0, $770 = 0, $771 = 0, $772 = 0, $773 = 0, $774 = 0, $775 = 0, $776 = 0, $777 = 0, $778 = 0, $779 = 0, $78 = 0, $780 = 0, $781 = 0, $782 = 0, $783 = 0, $784 = 0, $785 = 0, $786 = 0, $787 = 0; | |
var $788 = 0, $789 = 0, $79 = 0, $790 = 0, $791 = 0, $792 = 0, $793 = 0, $794 = 0, $795 = 0, $796 = 0, $797 = 0, $798 = 0, $799 = 0, $8 = 0, $80 = 0, $800 = 0, $801 = 0, $802 = 0, $803 = 0, $804 = 0; | |
var $805 = 0, $806 = 0, $807 = 0, $808 = 0, $809 = 0, $81 = 0, $810 = 0, $811 = 0, $812 = 0, $813 = 0, $814 = 0, $815 = 0, $816 = 0, $817 = 0, $818 = 0, $819 = 0, $82 = 0, $820 = 0, $821 = 0, $822 = 0; | |
var $823 = 0, $824 = 0, $825 = 0, $826 = 0, $827 = 0, $828 = 0, $829 = 0, $83 = 0, $830 = 0, $831 = 0, $832 = 0, $833 = 0, $834 = 0, $835 = 0, $836 = 0, $837 = 0, $838 = 0, $839 = 0, $84 = 0, $840 = 0; | |
var $841 = 0, $842 = 0, $843 = 0, $844 = 0, $845 = 0, $846 = 0, $847 = 0, $848 = 0, $849 = 0, $85 = 0, $850 = 0, $851 = 0, $852 = 0, $853 = 0, $854 = 0, $855 = 0, $856 = 0, $857 = 0, $858 = 0, $859 = 0; | |
var $86 = 0, $860 = 0, $861 = 0, $862 = 0, $863 = 0, $864 = 0, $865 = 0, $866 = 0, $867 = 0, $868 = 0, $869 = 0, $87 = 0, $870 = 0, $871 = 0, $872 = 0, $873 = 0, $874 = 0, $875 = 0, $876 = 0, $877 = 0; | |
var $878 = 0, $879 = 0, $88 = 0, $880 = 0, $881 = 0, $882 = 0, $883 = 0, $884 = 0, $885 = 0, $886 = 0, $887 = 0, $888 = 0, $889 = 0, $89 = 0, $890 = 0, $891 = 0, $892 = 0, $893 = 0, $894 = 0, $895 = 0; | |
var $896 = 0, $897 = 0, $898 = 0, $899 = 0, $9 = 0, $90 = 0, $900 = 0, $901 = 0, $902 = 0, $903 = 0, $904 = 0, $905 = 0, $906 = 0, $907 = 0, $908 = 0, $909 = 0, $91 = 0, $910 = 0, $911 = 0, $912 = 0; | |
var $913 = 0, $914 = 0, $915 = 0, $916 = 0, $917 = 0, $918 = 0, $919 = 0, $92 = 0, $920 = 0, $921 = 0, $922 = 0, $923 = 0, $924 = 0, $925 = 0, $926 = 0, $927 = 0, $928 = 0, $929 = 0, $93 = 0, $930 = 0; | |
var $931 = 0, $932 = 0, $933 = 0, $934 = 0, $935 = 0, $936 = 0, $937 = 0, $938 = 0, $939 = 0, $94 = 0, $940 = 0, $941 = 0, $942 = 0, $943 = 0, $944 = 0, $945 = 0, $946 = 0, $947 = 0, $948 = 0, $949 = 0; | |
var $95 = 0, $950 = 0, $951 = 0, $952 = 0, $953 = 0, $954 = 0, $955 = 0, $956 = 0, $957 = 0, $958 = 0, $959 = 0, $96 = 0, $960 = 0, $961 = 0, $962 = 0, $963 = 0, $964 = 0, $965 = 0, $966 = 0, $967 = 0; | |
var $968 = 0, $969 = 0, $97 = 0, $970 = 0, $971 = 0, $972 = 0, $973 = 0, $974 = 0, $975 = 0, $976 = 0, $977 = 0, $978 = 0, $979 = 0, $98 = 0, $980 = 0, $981 = 0, $982 = 0, $983 = 0, $984 = 0, $985 = 0; | |
var $986 = 0, $987 = 0, $988 = 0, $989 = 0, $99 = 0, $990 = 0, $991 = 0, $992 = 0, $993 = 0, $994 = 0, $995 = 0, $996 = 0, $997 = 0, $998 = 0, $999 = 0, $F$0$i$i = 0, $F1$0$i = 0, $F4$0 = 0, $F4$0$i$i = 0, $F5$0$i = 0; | |
var $I1$0$c$i$i = 0, $I1$0$i$i = 0, $I7$0$i = 0, $I7$0$i$i = 0, $K12$025$i = 0, $K2$014$i$i = 0, $K8$052$i$i = 0, $R$0$i = 0, $R$0$i$i = 0, $R$0$i18 = 0, $R$1$i = 0, $R$1$i$i = 0, $R$1$i20 = 0, $RP$0$i = 0, $RP$0$i$i = 0, $RP$0$i17 = 0, $T$0$lcssa$i = 0, $T$0$lcssa$i$i = 0, $T$0$lcssa$i28$i = 0, $T$013$i$i = 0; | |
var $T$024$i = 0, $T$051$i$i = 0, $br$0$i = 0, $cond$i = 0, $cond$i$i = 0, $cond$i21 = 0, $exitcond$i$i = 0, $i$02$i$i = 0, $idx$0$i = 0, $mem$0 = 0, $nb$0 = 0, $notlhs$i = 0, $notrhs$i = 0, $oldfirst$0$i$i = 0, $or$cond$i = 0, $or$cond$i29 = 0, $or$cond1$i = 0, $or$cond10$i = 0, $or$cond19$i = 0, $or$cond2$i = 0; | |
var $or$cond49$i = 0, $or$cond5$i = 0, $or$cond6$i = 0, $or$cond8$not$i = 0, $or$cond9$i = 0, $qsize$0$i$i = 0, $rsize$0$i = 0, $rsize$0$i15 = 0, $rsize$1$i = 0, $rsize$2$i = 0, $rsize$3$lcssa$i = 0, $rsize$329$i = 0, $rst$0$i = 0, $rst$1$i = 0, $sizebits$0$i = 0, $sp$0$i$i = 0, $sp$0$i$i$i = 0, $sp$075$i = 0, $sp$168$i = 0, $ssize$0$$i = 0; | |
var $ssize$0$i = 0, $ssize$1$i = 0, $ssize$2$i = 0, $t$0$i = 0, $t$0$i14 = 0, $t$1$i = 0, $t$2$ph$i = 0, $t$2$v$3$i = 0, $t$228$i = 0, $tbase$0$i = 0, $tbase$247$i = 0, $tsize$0$i = 0, $tsize$0323841$i = 0, $tsize$1$i = 0, $tsize$246$i = 0, $v$0$i = 0, $v$0$i16 = 0, $v$1$i = 0, $v$2$i = 0, $v$3$lcssa$i = 0; | |
var $v$330$i = 0, label = 0, sp = 0; | |
sp = STACKTOP; | |
$0 = ($bytes>>>0)<(245); | |
do { | |
if ($0) { | |
$1 = ($bytes>>>0)<(11); | |
if ($1) { | |
$5 = 16; | |
} else { | |
$2 = (($bytes) + 11)|0; | |
$3 = $2 & -8; | |
$5 = $3; | |
} | |
$4 = $5 >>> 3; | |
$6 = HEAP32[24>>2]|0; | |
$7 = $6 >>> $4; | |
$8 = $7 & 3; | |
$9 = ($8|0)==(0); | |
if (!($9)) { | |
$10 = $7 & 1; | |
$11 = $10 ^ 1; | |
$12 = (($11) + ($4))|0; | |
$13 = $12 << 1; | |
$14 = ((24 + ($13<<2)|0) + 40|0); | |
$$sum10 = (($13) + 2)|0; | |
$15 = ((24 + ($$sum10<<2)|0) + 40|0); | |
$16 = HEAP32[$15>>2]|0; | |
$17 = (($16) + 8|0); | |
$18 = HEAP32[$17>>2]|0; | |
$19 = ($14|0)==($18|0); | |
do { | |
if ($19) { | |
$20 = 1 << $12; | |
$21 = $20 ^ -1; | |
$22 = $6 & $21; | |
HEAP32[24>>2] = $22; | |
} else { | |
$23 = HEAP32[((24 + 16|0))>>2]|0; | |
$24 = ($18>>>0)<($23>>>0); | |
if ($24) { | |
_abort(); | |
// unreachable; | |
} | |
$25 = (($18) + 12|0); | |
$26 = HEAP32[$25>>2]|0; | |
$27 = ($26|0)==($16|0); | |
if ($27) { | |
HEAP32[$25>>2] = $14; | |
HEAP32[$15>>2] = $18; | |
break; | |
} else { | |
_abort(); | |
// unreachable; | |
} | |
} | |
} while(0); | |
$28 = $12 << 3; | |
$29 = $28 | 3; | |
$30 = (($16) + 4|0); | |
HEAP32[$30>>2] = $29; | |
$$sum1112 = $28 | 4; | |
$31 = (($16) + ($$sum1112)|0); | |
$32 = HEAP32[$31>>2]|0; | |
$33 = $32 | 1; | |
HEAP32[$31>>2] = $33; | |
$mem$0 = $17; | |
STACKTOP = sp;return ($mem$0|0); | |
} | |
$34 = HEAP32[((24 + 8|0))>>2]|0; | |
$35 = ($5>>>0)>($34>>>0); | |
if ($35) { | |
$36 = ($7|0)==(0); | |
if (!($36)) { | |
$37 = $7 << $4; | |
$38 = 2 << $4; | |
$39 = (0 - ($38))|0; | |
$40 = $38 | $39; | |
$41 = $37 & $40; | |
$42 = (0 - ($41))|0; | |
$43 = $41 & $42; | |
$44 = (($43) + -1)|0; | |
$45 = $44 >>> 12; | |
$46 = $45 & 16; | |
$47 = $44 >>> $46; | |
$48 = $47 >>> 5; | |
$49 = $48 & 8; | |
$50 = $49 | $46; | |
$51 = $47 >>> $49; | |
$52 = $51 >>> 2; | |
$53 = $52 & 4; | |
$54 = $50 | $53; | |
$55 = $51 >>> $53; | |
$56 = $55 >>> 1; | |
$57 = $56 & 2; | |
$58 = $54 | $57; | |
$59 = $55 >>> $57; | |
$60 = $59 >>> 1; | |
$61 = $60 & 1; | |
$62 = $58 | $61; | |
$63 = $59 >>> $61; | |
$64 = (($62) + ($63))|0; | |
$65 = $64 << 1; | |
$66 = ((24 + ($65<<2)|0) + 40|0); | |
$$sum4 = (($65) + 2)|0; | |
$67 = ((24 + ($$sum4<<2)|0) + 40|0); | |
$68 = HEAP32[$67>>2]|0; | |
$69 = (($68) + 8|0); | |
$70 = HEAP32[$69>>2]|0; | |
$71 = ($66|0)==($70|0); | |
do { | |
if ($71) { | |
$72 = 1 << $64; | |
$73 = $72 ^ -1; | |
$74 = $6 & $73; | |
HEAP32[24>>2] = $74; | |
} else { | |
$75 = HEAP32[((24 + 16|0))>>2]|0; | |
$76 = ($70>>>0)<($75>>>0); | |
if ($76) { | |
_abort(); | |
// unreachable; | |
} | |
$77 = (($70) + 12|0); | |
$78 = HEAP32[$77>>2]|0; | |
$79 = ($78|0)==($68|0); | |
if ($79) { | |
HEAP32[$77>>2] = $66; | |
HEAP32[$67>>2] = $70; | |
break; | |
} else { | |
_abort(); | |
// unreachable; | |
} | |
} | |
} while(0); | |
$80 = $64 << 3; | |
$81 = (($80) - ($5))|0; | |
$82 = $5 | 3; | |
$83 = (($68) + 4|0); | |
HEAP32[$83>>2] = $82; | |
$84 = (($68) + ($5)|0); | |
$85 = $81 | 1; | |
$$sum56 = $5 | 4; | |
$86 = (($68) + ($$sum56)|0); | |
HEAP32[$86>>2] = $85; | |
$87 = (($68) + ($80)|0); | |
HEAP32[$87>>2] = $81; | |
$88 = HEAP32[((24 + 8|0))>>2]|0; | |
$89 = ($88|0)==(0); | |
if (!($89)) { | |
$90 = HEAP32[((24 + 20|0))>>2]|0; | |
$91 = $88 >>> 3; | |
$92 = $91 << 1; | |
$93 = ((24 + ($92<<2)|0) + 40|0); | |
$94 = HEAP32[24>>2]|0; | |
$95 = 1 << $91; | |
$96 = $94 & $95; | |
$97 = ($96|0)==(0); | |
if ($97) { | |
$98 = $94 | $95; | |
HEAP32[24>>2] = $98; | |
$$sum8$pre = (($92) + 2)|0; | |
$$pre = ((24 + ($$sum8$pre<<2)|0) + 40|0); | |
$$pre$phiZ2D = $$pre;$F4$0 = $93; | |
} else { | |
$$sum9 = (($92) + 2)|0; | |
$99 = ((24 + ($$sum9<<2)|0) + 40|0); | |
$100 = HEAP32[$99>>2]|0; | |
$101 = HEAP32[((24 + 16|0))>>2]|0; | |
$102 = ($100>>>0)<($101>>>0); | |
if ($102) { | |
_abort(); | |
// unreachable; | |
} else { | |
$$pre$phiZ2D = $99;$F4$0 = $100; | |
} | |
} | |
HEAP32[$$pre$phiZ2D>>2] = $90; | |
$103 = (($F4$0) + 12|0); | |
HEAP32[$103>>2] = $90; | |
$104 = (($90) + 8|0); | |
HEAP32[$104>>2] = $F4$0; | |
$105 = (($90) + 12|0); | |
HEAP32[$105>>2] = $93; | |
} | |
HEAP32[((24 + 8|0))>>2] = $81; | |
HEAP32[((24 + 20|0))>>2] = $84; | |
$mem$0 = $69; | |
STACKTOP = sp;return ($mem$0|0); | |
} | |
$106 = HEAP32[((24 + 4|0))>>2]|0; | |
$107 = ($106|0)==(0); | |
if ($107) { | |
$nb$0 = $5; | |
} else { | |
$108 = (0 - ($106))|0; | |
$109 = $106 & $108; | |
$110 = (($109) + -1)|0; | |
$111 = $110 >>> 12; | |
$112 = $111 & 16; | |
$113 = $110 >>> $112; | |
$114 = $113 >>> 5; | |
$115 = $114 & 8; | |
$116 = $115 | $112; | |
$117 = $113 >>> $115; | |
$118 = $117 >>> 2; | |
$119 = $118 & 4; | |
$120 = $116 | $119; | |
$121 = $117 >>> $119; | |
$122 = $121 >>> 1; | |
$123 = $122 & 2; | |
$124 = $120 | $123; | |
$125 = $121 >>> $123; | |
$126 = $125 >>> 1; | |
$127 = $126 & 1; | |
$128 = $124 | $127; | |
$129 = $125 >>> $127; | |
$130 = (($128) + ($129))|0; | |
$131 = ((24 + ($130<<2)|0) + 304|0); | |
$132 = HEAP32[$131>>2]|0; | |
$133 = (($132) + 4|0); | |
$134 = HEAP32[$133>>2]|0; | |
$135 = $134 & -8; | |
$136 = (($135) - ($5))|0; | |
$rsize$0$i = $136;$t$0$i = $132;$v$0$i = $132; | |
while(1) { | |
$137 = (($t$0$i) + 16|0); | |
$138 = HEAP32[$137>>2]|0; | |
$139 = ($138|0)==(0|0); | |
if ($139) { | |
$140 = (($t$0$i) + 20|0); | |
$141 = HEAP32[$140>>2]|0; | |
$142 = ($141|0)==(0|0); | |
if ($142) { | |
break; | |
} else { | |
$144 = $141; | |
} | |
} else { | |
$144 = $138; | |
} | |
$143 = (($144) + 4|0); | |
$145 = HEAP32[$143>>2]|0; | |
$146 = $145 & -8; | |
$147 = (($146) - ($5))|0; | |
$148 = ($147>>>0)<($rsize$0$i>>>0); | |
$$rsize$0$i = $148 ? $147 : $rsize$0$i; | |
$$v$0$i = $148 ? $144 : $v$0$i; | |
$rsize$0$i = $$rsize$0$i;$t$0$i = $144;$v$0$i = $$v$0$i; | |
} | |
$149 = HEAP32[((24 + 16|0))>>2]|0; | |
$150 = ($v$0$i>>>0)<($149>>>0); | |
if ($150) { | |
_abort(); | |
// unreachable; | |
} | |
$151 = (($v$0$i) + ($5)|0); | |
$152 = ($v$0$i>>>0)<($151>>>0); | |
if (!($152)) { | |
_abort(); | |
// unreachable; | |
} | |
$153 = (($v$0$i) + 24|0); | |
$154 = HEAP32[$153>>2]|0; | |
$155 = (($v$0$i) + 12|0); | |
$156 = HEAP32[$155>>2]|0; | |
$157 = ($156|0)==($v$0$i|0); | |
do { | |
if ($157) { | |
$167 = (($v$0$i) + 20|0); | |
$168 = HEAP32[$167>>2]|0; | |
$169 = ($168|0)==(0|0); | |
if ($169) { | |
$170 = (($v$0$i) + 16|0); | |
$171 = HEAP32[$170>>2]|0; | |
$172 = ($171|0)==(0|0); | |
if ($172) { | |
$R$1$i = 0; | |
break; | |
} else { | |
$R$0$i = $171;$RP$0$i = $170; | |
} | |
} else { | |
$R$0$i = $168;$RP$0$i = $167; | |
} | |
while(1) { | |
$173 = (($R$0$i) + 20|0); | |
$174 = HEAP32[$173>>2]|0; | |
$175 = ($174|0)==(0|0); | |
if (!($175)) { | |
$R$0$i = $174;$RP$0$i = $173; | |
continue; | |
} | |
$176 = (($R$0$i) + 16|0); | |
$177 = HEAP32[$176>>2]|0; | |
$178 = ($177|0)==(0|0); | |
if ($178) { | |
break; | |
} else { | |
$R$0$i = $177;$RP$0$i = $176; | |
} | |
} | |
$179 = ($RP$0$i>>>0)<($149>>>0); | |
if ($179) { | |
_abort(); | |
// unreachable; | |
} else { | |
HEAP32[$RP$0$i>>2] = 0; | |
$R$1$i = $R$0$i; | |
break; | |
} | |
} else { | |
$158 = (($v$0$i) + 8|0); | |
$159 = HEAP32[$158>>2]|0; | |
$160 = ($159>>>0)<($149>>>0); | |
if ($160) { | |
_abort(); | |
// unreachable; | |
} | |
$161 = (($159) + 12|0); | |
$162 = HEAP32[$161>>2]|0; | |
$163 = ($162|0)==($v$0$i|0); | |
if (!($163)) { | |
_abort(); | |
// unreachable; | |
} | |
$164 = (($156) + 8|0); | |
$165 = HEAP32[$164>>2]|0; | |
$166 = ($165|0)==($v$0$i|0); | |
if ($166) { | |
HEAP32[$161>>2] = $156; | |
HEAP32[$164>>2] = $159; | |
$R$1$i = $156; | |
break; | |
} else { | |
_abort(); | |
// unreachable; | |
} | |
} | |
} while(0); | |
$180 = ($154|0)==(0|0); | |
do { | |
if (!($180)) { | |
$181 = (($v$0$i) + 28|0); | |
$182 = HEAP32[$181>>2]|0; | |
$183 = ((24 + ($182<<2)|0) + 304|0); | |
$184 = HEAP32[$183>>2]|0; | |
$185 = ($v$0$i|0)==($184|0); | |
if ($185) { | |
HEAP32[$183>>2] = $R$1$i; | |
$cond$i = ($R$1$i|0)==(0|0); | |
if ($cond$i) { | |
$186 = 1 << $182; | |
$187 = $186 ^ -1; | |
$188 = HEAP32[((24 + 4|0))>>2]|0; | |
$189 = $188 & $187; | |
HEAP32[((24 + 4|0))>>2] = $189; | |
break; | |
} | |
} else { | |
$190 = HEAP32[((24 + 16|0))>>2]|0; | |
$191 = ($154>>>0)<($190>>>0); | |
if ($191) { | |
_abort(); | |
// unreachable; | |
} | |
$192 = (($154) + 16|0); | |
$193 = HEAP32[$192>>2]|0; | |
$194 = ($193|0)==($v$0$i|0); | |
if ($194) { | |
HEAP32[$192>>2] = $R$1$i; | |
} else { | |
$195 = (($154) + 20|0); | |
HEAP32[$195>>2] = $R$1$i; | |
} | |
$196 = ($R$1$i|0)==(0|0); | |
if ($196) { | |
break; | |
} | |
} | |
$197 = HEAP32[((24 + 16|0))>>2]|0; | |
$198 = ($R$1$i>>>0)<($197>>>0); | |
if ($198) { | |
_abort(); | |
// unreachable; | |
} | |
$199 = (($R$1$i) + 24|0); | |
HEAP32[$199>>2] = $154; | |
$200 = (($v$0$i) + 16|0); | |
$201 = HEAP32[$200>>2]|0; | |
$202 = ($201|0)==(0|0); | |
do { | |
if (!($202)) { | |
$203 = HEAP32[((24 + 16|0))>>2]|0; | |
$204 = ($201>>>0)<($203>>>0); | |
if ($204) { | |
_abort(); | |
// unreachable; | |
} else { | |
$205 = (($R$1$i) + 16|0); | |
HEAP32[$205>>2] = $201; | |
$206 = (($201) + 24|0); | |
HEAP32[$206>>2] = $R$1$i; | |
break; | |
} | |
} | |
} while(0); | |
$207 = (($v$0$i) + 20|0); | |
$208 = HEAP32[$207>>2]|0; | |
$209 = ($208|0)==(0|0); | |
if (!($209)) { | |
$210 = HEAP32[((24 + 16|0))>>2]|0; | |
$211 = ($208>>>0)<($210>>>0); | |
if ($211) { | |
_abort(); | |
// unreachable; | |
} else { | |
$212 = (($R$1$i) + 20|0); | |
HEAP32[$212>>2] = $208; | |
$213 = (($208) + 24|0); | |
HEAP32[$213>>2] = $R$1$i; | |
break; | |
} | |
} | |
} | |
} while(0); | |
$214 = ($rsize$0$i>>>0)<(16); | |
if ($214) { | |
$215 = (($rsize$0$i) + ($5))|0; | |
$216 = $215 | 3; | |
$217 = (($v$0$i) + 4|0); | |
HEAP32[$217>>2] = $216; | |
$$sum4$i = (($215) + 4)|0; | |
$218 = (($v$0$i) + ($$sum4$i)|0); | |
$219 = HEAP32[$218>>2]|0; | |
$220 = $219 | 1; | |
HEAP32[$218>>2] = $220; | |
} else { | |
$221 = $5 | 3; | |
$222 = (($v$0$i) + 4|0); | |
HEAP32[$222>>2] = $221; | |
$223 = $rsize$0$i | 1; | |
$$sum$i35 = $5 | 4; | |
$224 = (($v$0$i) + ($$sum$i35)|0); | |
HEAP32[$224>>2] = $223; | |
$$sum1$i = (($rsize$0$i) + ($5))|0; | |
$225 = (($v$0$i) + ($$sum1$i)|0); | |
HEAP32[$225>>2] = $rsize$0$i; | |
$226 = HEAP32[((24 + 8|0))>>2]|0; | |
$227 = ($226|0)==(0); | |
if (!($227)) { | |
$228 = HEAP32[((24 + 20|0))>>2]|0; | |
$229 = $226 >>> 3; | |
$230 = $229 << 1; | |
$231 = ((24 + ($230<<2)|0) + 40|0); | |
$232 = HEAP32[24>>2]|0; | |
$233 = 1 << $229; | |
$234 = $232 & $233; | |
$235 = ($234|0)==(0); | |
if ($235) { | |
$236 = $232 | $233; | |
HEAP32[24>>2] = $236; | |
$$sum2$pre$i = (($230) + 2)|0; | |
$$pre$i = ((24 + ($$sum2$pre$i<<2)|0) + 40|0); | |
$$pre$phi$iZ2D = $$pre$i;$F1$0$i = $231; | |
} else { | |
$$sum3$i = (($230) + 2)|0; | |
$237 = ((24 + ($$sum3$i<<2)|0) + 40|0); | |
$238 = HEAP32[$237>>2]|0; | |
$239 = HEAP32[((24 + 16|0))>>2]|0; | |
$240 = ($238>>>0)<($239>>>0); | |
if ($240) { | |
_abort(); | |
// unreachable; | |
} else { | |
$$pre$phi$iZ2D = $237;$F1$0$i = $238; | |
} | |
} | |
HEAP32[$$pre$phi$iZ2D>>2] = $228; | |
$241 = (($F1$0$i) + 12|0); | |
HEAP32[$241>>2] = $228; | |
$242 = (($228) + 8|0); | |
HEAP32[$242>>2] = $F1$0$i; | |
$243 = (($228) + 12|0); | |
HEAP32[$243>>2] = $231; | |
} | |
HEAP32[((24 + 8|0))>>2] = $rsize$0$i; | |
HEAP32[((24 + 20|0))>>2] = $151; | |
} | |
$244 = (($v$0$i) + 8|0); | |
$mem$0 = $244; | |
STACKTOP = sp;return ($mem$0|0); | |
} | |
} else { | |
$nb$0 = $5; | |
} | |
} else { | |
$245 = ($bytes>>>0)>(4294967231); | |
if ($245) { | |
$nb$0 = -1; | |
} else { | |
$246 = (($bytes) + 11)|0; | |
$247 = $246 & -8; | |
$248 = HEAP32[((24 + 4|0))>>2]|0; | |
$249 = ($248|0)==(0); | |
if ($249) { | |
$nb$0 = $247; | |
} else { | |
$250 = (0 - ($247))|0; | |
$251 = $246 >>> 8; | |
$252 = ($251|0)==(0); | |
if ($252) { | |
$idx$0$i = 0; | |
} else { | |
$253 = ($247>>>0)>(16777215); | |
if ($253) { | |
$idx$0$i = 31; | |
} else { | |
$254 = (($251) + 1048320)|0; | |
$255 = $254 >>> 16; | |
$256 = $255 & 8; | |
$257 = $251 << $256; | |
$258 = (($257) + 520192)|0; | |
$259 = $258 >>> 16; | |
$260 = $259 & 4; | |
$261 = $260 | $256; | |
$262 = $257 << $260; | |
$263 = (($262) + 245760)|0; | |
$264 = $263 >>> 16; | |
$265 = $264 & 2; | |
$266 = $261 | $265; | |
$267 = (14 - ($266))|0; | |
$268 = $262 << $265; | |
$269 = $268 >>> 15; | |
$270 = (($267) + ($269))|0; | |
$271 = $270 << 1; | |
$272 = (($270) + 7)|0; | |
$273 = $247 >>> $272; | |
$274 = $273 & 1; | |
$275 = $274 | $271; | |
$idx$0$i = $275; | |
} | |
} | |
$276 = ((24 + ($idx$0$i<<2)|0) + 304|0); | |
$277 = HEAP32[$276>>2]|0; | |
$278 = ($277|0)==(0|0); | |
L126: do { | |
if ($278) { | |
$rsize$2$i = $250;$t$1$i = 0;$v$2$i = 0; | |
} else { | |
$279 = ($idx$0$i|0)==(31); | |
if ($279) { | |
$283 = 0; | |
} else { | |
$280 = $idx$0$i >>> 1; | |
$281 = (25 - ($280))|0; | |
$283 = $281; | |
} | |
$282 = $247 << $283; | |
$rsize$0$i15 = $250;$rst$0$i = 0;$sizebits$0$i = $282;$t$0$i14 = $277;$v$0$i16 = 0; | |
while(1) { | |
$284 = (($t$0$i14) + 4|0); | |
$285 = HEAP32[$284>>2]|0; | |
$286 = $285 & -8; | |
$287 = (($286) - ($247))|0; | |
$288 = ($287>>>0)<($rsize$0$i15>>>0); | |
if ($288) { | |
$289 = ($286|0)==($247|0); | |
if ($289) { | |
$rsize$2$i = $287;$t$1$i = $t$0$i14;$v$2$i = $t$0$i14; | |
break L126; | |
} else { | |
$rsize$1$i = $287;$v$1$i = $t$0$i14; | |
} | |
} else { | |
$rsize$1$i = $rsize$0$i15;$v$1$i = $v$0$i16; | |
} | |
$290 = (($t$0$i14) + 20|0); | |
$291 = HEAP32[$290>>2]|0; | |
$292 = $sizebits$0$i >>> 31; | |
$293 = ((($t$0$i14) + ($292<<2)|0) + 16|0); | |
$294 = HEAP32[$293>>2]|0; | |
$295 = ($291|0)==(0|0); | |
$296 = ($291|0)==($294|0); | |
$or$cond$i = $295 | $296; | |
$rst$1$i = $or$cond$i ? $rst$0$i : $291; | |
$297 = ($294|0)==(0|0); | |
$298 = $sizebits$0$i << 1; | |
if ($297) { | |
$rsize$2$i = $rsize$1$i;$t$1$i = $rst$1$i;$v$2$i = $v$1$i; | |
break; | |
} else { | |
$rsize$0$i15 = $rsize$1$i;$rst$0$i = $rst$1$i;$sizebits$0$i = $298;$t$0$i14 = $294;$v$0$i16 = $v$1$i; | |
} | |
} | |
} | |
} while(0); | |
$299 = ($t$1$i|0)==(0|0); | |
$300 = ($v$2$i|0)==(0|0); | |
$or$cond19$i = $299 & $300; | |
if ($or$cond19$i) { | |
$301 = 2 << $idx$0$i; | |
$302 = (0 - ($301))|0; | |
$303 = $301 | $302; | |
$304 = $248 & $303; | |
$305 = ($304|0)==(0); | |
if ($305) { | |
$nb$0 = $247; | |
break; | |
} | |
$306 = (0 - ($304))|0; | |
$307 = $304 & $306; | |
$308 = (($307) + -1)|0; | |
$309 = $308 >>> 12; | |
$310 = $309 & 16; | |
$311 = $308 >>> $310; | |
$312 = $311 >>> 5; | |
$313 = $312 & 8; | |
$314 = $313 | $310; | |
$315 = $311 >>> $313; | |
$316 = $315 >>> 2; | |
$317 = $316 & 4; | |
$318 = $314 | $317; | |
$319 = $315 >>> $317; | |
$320 = $319 >>> 1; | |
$321 = $320 & 2; | |
$322 = $318 | $321; | |
$323 = $319 >>> $321; | |
$324 = $323 >>> 1; | |
$325 = $324 & 1; | |
$326 = $322 | $325; | |
$327 = $323 >>> $325; | |
$328 = (($326) + ($327))|0; | |
$329 = ((24 + ($328<<2)|0) + 304|0); | |
$330 = HEAP32[$329>>2]|0; | |
$t$2$ph$i = $330; | |
} else { | |
$t$2$ph$i = $t$1$i; | |
} | |
$331 = ($t$2$ph$i|0)==(0|0); | |
if ($331) { | |
$rsize$3$lcssa$i = $rsize$2$i;$v$3$lcssa$i = $v$2$i; | |
} else { | |
$rsize$329$i = $rsize$2$i;$t$228$i = $t$2$ph$i;$v$330$i = $v$2$i; | |
while(1) { | |
$332 = (($t$228$i) + 4|0); | |
$333 = HEAP32[$332>>2]|0; | |
$334 = $333 & -8; | |
$335 = (($334) - ($247))|0; | |
$336 = ($335>>>0)<($rsize$329$i>>>0); | |
$$rsize$3$i = $336 ? $335 : $rsize$329$i; | |
$t$2$v$3$i = $336 ? $t$228$i : $v$330$i; | |
$337 = (($t$228$i) + 16|0); | |
$338 = HEAP32[$337>>2]|0; | |
$339 = ($338|0)==(0|0); | |
if (!($339)) { | |
$rsize$329$i = $$rsize$3$i;$t$228$i = $338;$v$330$i = $t$2$v$3$i; | |
continue; | |
} | |
$340 = (($t$228$i) + 20|0); | |
$341 = HEAP32[$340>>2]|0; | |
$342 = ($341|0)==(0|0); | |
if ($342) { | |
$rsize$3$lcssa$i = $$rsize$3$i;$v$3$lcssa$i = $t$2$v$3$i; | |
break; | |
} else { | |
$rsize$329$i = $$rsize$3$i;$t$228$i = $341;$v$330$i = $t$2$v$3$i; | |
} | |
} | |
} | |
$343 = ($v$3$lcssa$i|0)==(0|0); | |
if ($343) { | |
$nb$0 = $247; | |
} else { | |
$344 = HEAP32[((24 + 8|0))>>2]|0; | |
$345 = (($344) - ($247))|0; | |
$346 = ($rsize$3$lcssa$i>>>0)<($345>>>0); | |
if ($346) { | |
$347 = HEAP32[((24 + 16|0))>>2]|0; | |
$348 = ($v$3$lcssa$i>>>0)<($347>>>0); | |
if ($348) { | |
_abort(); | |
// unreachable; | |
} | |
$349 = (($v$3$lcssa$i) + ($247)|0); | |
$350 = ($v$3$lcssa$i>>>0)<($349>>>0); | |
if (!($350)) { | |
_abort(); | |
// unreachable; | |
} | |
$351 = (($v$3$lcssa$i) + 24|0); | |
$352 = HEAP32[$351>>2]|0; | |
$353 = (($v$3$lcssa$i) + 12|0); | |
$354 = HEAP32[$353>>2]|0; | |
$355 = ($354|0)==($v$3$lcssa$i|0); | |
do { | |
if ($355) { | |
$365 = (($v$3$lcssa$i) + 20|0); | |
$366 = HEAP32[$365>>2]|0; | |
$367 = ($366|0)==(0|0); | |
if ($367) { | |
$368 = (($v$3$lcssa$i) + 16|0); | |
$369 = HEAP32[$368>>2]|0; | |
$370 = ($369|0)==(0|0); | |
if ($370) { | |
$R$1$i20 = 0; | |
break; | |
} else { | |
$R$0$i18 = $369;$RP$0$i17 = $368; | |
} | |
} else { | |
$R$0$i18 = $366;$RP$0$i17 = $365; | |
} | |
while(1) { | |
$371 = (($R$0$i18) + 20|0); | |
$372 = HEAP32[$371>>2]|0; | |
$373 = ($372|0)==(0|0); | |
if (!($373)) { | |
$R$0$i18 = $372;$RP$0$i17 = $371; | |
continue; | |
} | |
$374 = (($R$0$i18) + 16|0); | |
$375 = HEAP32[$374>>2]|0; | |
$376 = ($375|0)==(0|0); | |
if ($376) { | |
break; | |
} else { | |
$R$0$i18 = $375;$RP$0$i17 = $374; | |
} | |
} | |
$377 = ($RP$0$i17>>>0)<($347>>>0); | |
if ($377) { | |
_abort(); | |
// unreachable; | |
} else { | |
HEAP32[$RP$0$i17>>2] = 0; | |
$R$1$i20 = $R$0$i18; | |
break; | |
} | |
} else { | |
$356 = (($v$3$lcssa$i) + 8|0); | |
$357 = HEAP32[$356>>2]|0; | |
$358 = ($357>>>0)<($347>>>0); | |
if ($358) { | |
_abort(); | |
// unreachable; | |
} | |
$359 = (($357) + 12|0); | |
$360 = HEAP32[$359>>2]|0; | |
$361 = ($360|0)==($v$3$lcssa$i|0); | |
if (!($361)) { | |
_abort(); | |
// unreachable; | |
} | |
$362 = (($354) + 8|0); | |
$363 = HEAP32[$362>>2]|0; | |
$364 = ($363|0)==($v$3$lcssa$i|0); | |
if ($364) { | |
HEAP32[$359>>2] = $354; | |
HEAP32[$362>>2] = $357; | |
$R$1$i20 = $354; | |
break; | |
} else { | |
_abort(); | |
// unreachable; | |
} | |
} | |
} while(0); | |
$378 = ($352|0)==(0|0); | |
do { | |
if (!($378)) { | |
$379 = (($v$3$lcssa$i) + 28|0); | |
$380 = HEAP32[$379>>2]|0; | |
$381 = ((24 + ($380<<2)|0) + 304|0); | |
$382 = HEAP32[$381>>2]|0; | |
$383 = ($v$3$lcssa$i|0)==($382|0); | |
if ($383) { | |
HEAP32[$381>>2] = $R$1$i20; | |
$cond$i21 = ($R$1$i20|0)==(0|0); | |
if ($cond$i21) { | |
$384 = 1 << $380; | |
$385 = $384 ^ -1; | |
$386 = HEAP32[((24 + 4|0))>>2]|0; | |
$387 = $386 & $385; | |
HEAP32[((24 + 4|0))>>2] = $387; | |
break; | |
} | |
} else { | |
$388 = HEAP32[((24 + 16|0))>>2]|0; | |
$389 = ($352>>>0)<($388>>>0); | |
if ($389) { | |
_abort(); | |
// unreachable; | |
} | |
$390 = (($352) + 16|0); | |
$391 = HEAP32[$390>>2]|0; | |
$392 = ($391|0)==($v$3$lcssa$i|0); | |
if ($392) { | |
HEAP32[$390>>2] = $R$1$i20; | |
} else { | |
$393 = (($352) + 20|0); | |
HEAP32[$393>>2] = $R$1$i20; | |
} | |
$394 = ($R$1$i20|0)==(0|0); | |
if ($394) { | |
break; | |
} | |
} | |
$395 = HEAP32[((24 + 16|0))>>2]|0; | |
$396 = ($R$1$i20>>>0)<($395>>>0); | |
if ($396) { | |
_abort(); | |
// unreachable; | |
} | |
$397 = (($R$1$i20) + 24|0); | |
HEAP32[$397>>2] = $352; | |
$398 = (($v$3$lcssa$i) + 16|0); | |
$399 = HEAP32[$398>>2]|0; | |
$400 = ($399|0)==(0|0); | |
do { | |
if (!($400)) { | |
$401 = HEAP32[((24 + 16|0))>>2]|0; | |
$402 = ($399>>>0)<($401>>>0); | |
if ($402) { | |
_abort(); | |
// unreachable; | |
} else { | |
$403 = (($R$1$i20) + 16|0); | |
HEAP32[$403>>2] = $399; | |
$404 = (($399) + 24|0); | |
HEAP32[$404>>2] = $R$1$i20; | |
break; | |
} | |
} | |
} while(0); | |
$405 = (($v$3$lcssa$i) + 20|0); | |
$406 = HEAP32[$405>>2]|0; | |
$407 = ($406|0)==(0|0); | |
if (!($407)) { | |
$408 = HEAP32[((24 + 16|0))>>2]|0; | |
$409 = ($406>>>0)<($408>>>0); | |
if ($409) { | |
_abort(); | |
// unreachable; | |
} else { | |
$410 = (($R$1$i20) + 20|0); | |
HEAP32[$410>>2] = $406; | |
$411 = (($406) + 24|0); | |
HEAP32[$411>>2] = $R$1$i20; | |
break; | |
} | |
} | |
} | |
} while(0); | |
$412 = ($rsize$3$lcssa$i>>>0)<(16); | |
L204: do { | |
if ($412) { | |
$413 = (($rsize$3$lcssa$i) + ($247))|0; | |
$414 = $413 | 3; | |
$415 = (($v$3$lcssa$i) + 4|0); | |
HEAP32[$415>>2] = $414; | |
$$sum18$i = (($413) + 4)|0; | |
$416 = (($v$3$lcssa$i) + ($$sum18$i)|0); | |
$417 = HEAP32[$416>>2]|0; | |
$418 = $417 | 1; | |
HEAP32[$416>>2] = $418; | |
} else { | |
$419 = $247 | 3; | |
$420 = (($v$3$lcssa$i) + 4|0); | |
HEAP32[$420>>2] = $419; | |
$421 = $rsize$3$lcssa$i | 1; | |
$$sum$i2334 = $247 | 4; | |
$422 = (($v$3$lcssa$i) + ($$sum$i2334)|0); | |
HEAP32[$422>>2] = $421; | |
$$sum1$i24 = (($rsize$3$lcssa$i) + ($247))|0; | |
$423 = (($v$3$lcssa$i) + ($$sum1$i24)|0); | |
HEAP32[$423>>2] = $rsize$3$lcssa$i; | |
$424 = $rsize$3$lcssa$i >>> 3; | |
$425 = ($rsize$3$lcssa$i>>>0)<(256); | |
if ($425) { | |
$426 = $424 << 1; | |
$427 = ((24 + ($426<<2)|0) + 40|0); | |
$428 = HEAP32[24>>2]|0; | |
$429 = 1 << $424; | |
$430 = $428 & $429; | |
$431 = ($430|0)==(0); | |
do { | |
if ($431) { | |
$432 = $428 | $429; | |
HEAP32[24>>2] = $432; | |
$$sum14$pre$i = (($426) + 2)|0; | |
$$pre$i25 = ((24 + ($$sum14$pre$i<<2)|0) + 40|0); | |
$$pre$phi$i26Z2D = $$pre$i25;$F5$0$i = $427; | |
} else { | |
$$sum17$i = (($426) + 2)|0; | |
$433 = ((24 + ($$sum17$i<<2)|0) + 40|0); | |
$434 = HEAP32[$433>>2]|0; | |
$435 = HEAP32[((24 + 16|0))>>2]|0; | |
$436 = ($434>>>0)<($435>>>0); | |
if (!($436)) { | |
$$pre$phi$i26Z2D = $433;$F5$0$i = $434; | |
break; | |
} | |
_abort(); | |
// unreachable; | |
} | |
} while(0); | |
HEAP32[$$pre$phi$i26Z2D>>2] = $349; | |
$437 = (($F5$0$i) + 12|0); | |
HEAP32[$437>>2] = $349; | |
$$sum15$i = (($247) + 8)|0; | |
$438 = (($v$3$lcssa$i) + ($$sum15$i)|0); | |
HEAP32[$438>>2] = $F5$0$i; | |
$$sum16$i = (($247) + 12)|0; | |
$439 = (($v$3$lcssa$i) + ($$sum16$i)|0); | |
HEAP32[$439>>2] = $427; | |
break; | |
} | |
$440 = $rsize$3$lcssa$i >>> 8; | |
$441 = ($440|0)==(0); | |
if ($441) { | |
$I7$0$i = 0; | |
} else { | |
$442 = ($rsize$3$lcssa$i>>>0)>(16777215); | |
if ($442) { | |
$I7$0$i = 31; | |
} else { | |
$443 = (($440) + 1048320)|0; | |
$444 = $443 >>> 16; | |
$445 = $444 & 8; | |
$446 = $440 << $445; | |
$447 = (($446) + 520192)|0; | |
$448 = $447 >>> 16; | |
$449 = $448 & 4; | |
$450 = $449 | $445; | |
$451 = $446 << $449; | |
$452 = (($451) + 245760)|0; | |
$453 = $452 >>> 16; | |
$454 = $453 & 2; | |
$455 = $450 | $454; | |
$456 = (14 - ($455))|0; | |
$457 = $451 << $454; | |
$458 = $457 >>> 15; | |
$459 = (($456) + ($458))|0; | |
$460 = $459 << 1; | |
$461 = (($459) + 7)|0; | |
$462 = $rsize$3$lcssa$i >>> $461; | |
$463 = $462 & 1; | |
$464 = $463 | $460; | |
$I7$0$i = $464; | |
} | |
} | |
$465 = ((24 + ($I7$0$i<<2)|0) + 304|0); | |
$$sum2$i = (($247) + 28)|0; | |
$466 = (($v$3$lcssa$i) + ($$sum2$i)|0); | |
HEAP32[$466>>2] = $I7$0$i; | |
$$sum3$i27 = (($247) + 16)|0; | |
$467 = (($v$3$lcssa$i) + ($$sum3$i27)|0); | |
$$sum4$i28 = (($247) + 20)|0; | |
$468 = (($v$3$lcssa$i) + ($$sum4$i28)|0); | |
HEAP32[$468>>2] = 0; | |
HEAP32[$467>>2] = 0; | |
$469 = HEAP32[((24 + 4|0))>>2]|0; | |
$470 = 1 << $I7$0$i; | |
$471 = $469 & $470; | |
$472 = ($471|0)==(0); | |
if ($472) { | |
$473 = $469 | $470; | |
HEAP32[((24 + 4|0))>>2] = $473; | |
HEAP32[$465>>2] = $349; | |
$$sum5$i = (($247) + 24)|0; | |
$474 = (($v$3$lcssa$i) + ($$sum5$i)|0); | |
HEAP32[$474>>2] = $465; | |
$$sum6$i = (($247) + 12)|0; | |
$475 = (($v$3$lcssa$i) + ($$sum6$i)|0); | |
HEAP32[$475>>2] = $349; | |
$$sum7$i = (($247) + 8)|0; | |
$476 = (($v$3$lcssa$i) + ($$sum7$i)|0); | |
HEAP32[$476>>2] = $349; | |
break; | |
} | |
$477 = HEAP32[$465>>2]|0; | |
$478 = ($I7$0$i|0)==(31); | |
if ($478) { | |
$486 = 0; | |
} else { | |
$479 = $I7$0$i >>> 1; | |
$480 = (25 - ($479))|0; | |
$486 = $480; | |
} | |
$481 = (($477) + 4|0); | |
$482 = HEAP32[$481>>2]|0; | |
$483 = $482 & -8; | |
$484 = ($483|0)==($rsize$3$lcssa$i|0); | |
L225: do { | |
if ($484) { | |
$T$0$lcssa$i = $477; | |
} else { | |
$485 = $rsize$3$lcssa$i << $486; | |
$K12$025$i = $485;$T$024$i = $477; | |
while(1) { | |
$493 = $K12$025$i >>> 31; | |
$494 = ((($T$024$i) + ($493<<2)|0) + 16|0); | |
$489 = HEAP32[$494>>2]|0; | |
$495 = ($489|0)==(0|0); | |
if ($495) { | |
break; | |
} | |
$487 = $K12$025$i << 1; | |
$488 = (($489) + 4|0); | |
$490 = HEAP32[$488>>2]|0; | |
$491 = $490 & -8; | |
$492 = ($491|0)==($rsize$3$lcssa$i|0); | |
if ($492) { | |
$T$0$lcssa$i = $489; | |
break L225; | |
} else { | |
$K12$025$i = $487;$T$024$i = $489; | |
} | |
} | |
$496 = HEAP32[((24 + 16|0))>>2]|0; | |
$497 = ($494>>>0)<($496>>>0); | |
if ($497) { | |
_abort(); | |
// unreachable; | |
} else { | |
HEAP32[$494>>2] = $349; | |
$$sum11$i = (($247) + 24)|0; | |
$498 = (($v$3$lcssa$i) + ($$sum11$i)|0); | |
HEAP32[$498>>2] = $T$024$i; | |
$$sum12$i = (($247) + 12)|0; | |
$499 = (($v$3$lcssa$i) + ($$sum12$i)|0); | |
HEAP32[$499>>2] = $349; | |
$$sum13$i = (($247) + 8)|0; | |
$500 = (($v$3$lcssa$i) + ($$sum13$i)|0); | |
HEAP32[$500>>2] = $349; | |
break L204; | |
} | |
} | |
} while(0); | |
$501 = (($T$0$lcssa$i) + 8|0); | |
$502 = HEAP32[$501>>2]|0; | |
$503 = HEAP32[((24 + 16|0))>>2]|0; | |
$504 = ($T$0$lcssa$i>>>0)<($503>>>0); | |
if ($504) { | |
_abort(); | |
// unreachable; | |
} | |
$505 = ($502>>>0)<($503>>>0); | |
if ($505) { | |
_abort(); | |
// unreachable; | |
} else { | |
$506 = (($502) + 12|0); | |
HEAP32[$506>>2] = $349; | |
HEAP32[$501>>2] = $349; | |
$$sum8$i = (($247) + 8)|0; | |
$507 = (($v$3$lcssa$i) + ($$sum8$i)|0); | |
HEAP32[$507>>2] = $502; | |
$$sum9$i = (($247) + 12)|0; | |
$508 = (($v$3$lcssa$i) + ($$sum9$i)|0); | |
HEAP32[$508>>2] = $T$0$lcssa$i; | |
$$sum10$i = (($247) + 24)|0; | |
$509 = (($v$3$lcssa$i) + ($$sum10$i)|0); | |
HEAP32[$509>>2] = 0; | |
break; | |
} | |
} | |
} while(0); | |
$510 = (($v$3$lcssa$i) + 8|0); | |
$mem$0 = $510; | |
STACKTOP = sp;return ($mem$0|0); | |
} else { | |
$nb$0 = $247; | |
} | |
} | |
} | |
} | |
} | |
} while(0); | |
$511 = HEAP32[((24 + 8|0))>>2]|0; | |
$512 = ($nb$0>>>0)>($511>>>0); | |
if (!($512)) { | |
$513 = (($511) - ($nb$0))|0; | |
$514 = HEAP32[((24 + 20|0))>>2]|0; | |
$515 = ($513>>>0)>(15); | |
if ($515) { | |
$516 = (($514) + ($nb$0)|0); | |
HEAP32[((24 + 20|0))>>2] = $516; | |
HEAP32[((24 + 8|0))>>2] = $513; | |
$517 = $513 | 1; | |
$$sum2 = (($nb$0) + 4)|0; | |
$518 = (($514) + ($$sum2)|0); | |
HEAP32[$518>>2] = $517; | |
$519 = (($514) + ($511)|0); | |
HEAP32[$519>>2] = $513; | |
$520 = $nb$0 | 3; | |
$521 = (($514) + 4|0); | |
HEAP32[$521>>2] = $520; | |
} else { | |
HEAP32[((24 + 8|0))>>2] = 0; | |
HEAP32[((24 + 20|0))>>2] = 0; | |
$522 = $511 | 3; | |
$523 = (($514) + 4|0); | |
HEAP32[$523>>2] = $522; | |
$$sum1 = (($511) + 4)|0; | |
$524 = (($514) + ($$sum1)|0); | |
$525 = HEAP32[$524>>2]|0; | |
$526 = $525 | 1; | |
HEAP32[$524>>2] = $526; | |
} | |
$527 = (($514) + 8|0); | |
$mem$0 = $527; | |
STACKTOP = sp;return ($mem$0|0); | |
} | |
$528 = HEAP32[((24 + 12|0))>>2]|0; | |
$529 = ($nb$0>>>0)<($528>>>0); | |
if ($529) { | |
$530 = (($528) - ($nb$0))|0; | |
HEAP32[((24 + 12|0))>>2] = $530; | |
$531 = HEAP32[((24 + 24|0))>>2]|0; | |
$532 = (($531) + ($nb$0)|0); | |
HEAP32[((24 + 24|0))>>2] = $532; | |
$533 = $530 | 1; | |
$$sum = (($nb$0) + 4)|0; | |
$534 = (($531) + ($$sum)|0); | |
HEAP32[$534>>2] = $533; | |
$535 = $nb$0 | 3; | |
$536 = (($531) + 4|0); | |
HEAP32[$536>>2] = $535; | |
$537 = (($531) + 8|0); | |
$mem$0 = $537; | |
STACKTOP = sp;return ($mem$0|0); | |
} | |
$538 = HEAP32[496>>2]|0; | |
$539 = ($538|0)==(0); | |
do { | |
if ($539) { | |
$540 = (_sysconf(30)|0); | |
$541 = (($540) + -1)|0; | |
$542 = $541 & $540; | |
$543 = ($542|0)==(0); | |
if ($543) { | |
HEAP32[((496 + 8|0))>>2] = $540; | |
HEAP32[((496 + 4|0))>>2] = $540; | |
HEAP32[((496 + 12|0))>>2] = -1; | |
HEAP32[((496 + 16|0))>>2] = -1; | |
HEAP32[((496 + 20|0))>>2] = 0; | |
HEAP32[((24 + 444|0))>>2] = 0; | |
$544 = (_time((0|0))|0); | |
$545 = $544 & -16; | |
$546 = $545 ^ 1431655768; | |
HEAP32[496>>2] = $546; | |
break; | |
} else { | |
_abort(); | |
// unreachable; | |
} | |
} | |
} while(0); | |
$547 = (($nb$0) + 48)|0; | |
$548 = HEAP32[((496 + 8|0))>>2]|0; | |
$549 = (($nb$0) + 47)|0; | |
$550 = (($548) + ($549))|0; | |
$551 = (0 - ($548))|0; | |
$552 = $550 & $551; | |
$553 = ($552>>>0)>($nb$0>>>0); | |
if (!($553)) { | |
$mem$0 = 0; | |
STACKTOP = sp;return ($mem$0|0); | |
} | |
$554 = HEAP32[((24 + 440|0))>>2]|0; | |
$555 = ($554|0)==(0); | |
if (!($555)) { | |
$556 = HEAP32[((24 + 432|0))>>2]|0; | |
$557 = (($556) + ($552))|0; | |
$558 = ($557>>>0)<=($556>>>0); | |
$559 = ($557>>>0)>($554>>>0); | |
$or$cond1$i = $558 | $559; | |
if ($or$cond1$i) { | |
$mem$0 = 0; | |
STACKTOP = sp;return ($mem$0|0); | |
} | |
} | |
$560 = HEAP32[((24 + 444|0))>>2]|0; | |
$561 = $560 & 4; | |
$562 = ($561|0)==(0); | |
L269: do { | |
if ($562) { | |
$563 = HEAP32[((24 + 24|0))>>2]|0; | |
$564 = ($563|0)==(0|0); | |
L271: do { | |
if ($564) { | |
label = 182; | |
} else { | |
$sp$0$i$i = ((24 + 448|0)); | |
while(1) { | |
$565 = HEAP32[$sp$0$i$i>>2]|0; | |
$566 = ($565>>>0)>($563>>>0); | |
if (!($566)) { | |
$567 = (($sp$0$i$i) + 4|0); | |
$568 = HEAP32[$567>>2]|0; | |
$569 = (($565) + ($568)|0); | |
$570 = ($569>>>0)>($563>>>0); | |
if ($570) { | |
break; | |
} | |
} | |
$571 = (($sp$0$i$i) + 8|0); | |
$572 = HEAP32[$571>>2]|0; | |
$573 = ($572|0)==(0|0); | |
if ($573) { | |
label = 182; | |
break L271; | |
} else { | |
$sp$0$i$i = $572; | |
} | |
} | |
$574 = ($sp$0$i$i|0)==(0|0); | |
if ($574) { | |
label = 182; | |
} else { | |
$597 = HEAP32[((24 + 12|0))>>2]|0; | |
$598 = (($550) - ($597))|0; | |
$599 = $598 & $551; | |
$600 = ($599>>>0)<(2147483647); | |
if ($600) { | |
$601 = (_sbrk(($599|0))|0); | |
$602 = HEAP32[$sp$0$i$i>>2]|0; | |
$603 = HEAP32[$567>>2]|0; | |
$604 = (($602) + ($603)|0); | |
$605 = ($601|0)==($604|0); | |
$$3$i = $605 ? $599 : 0; | |
$$4$i = $605 ? $601 : (-1); | |
$br$0$i = $601;$ssize$1$i = $599;$tbase$0$i = $$4$i;$tsize$0$i = $$3$i; | |
label = 191; | |
} else { | |
$tsize$0323841$i = 0; | |
} | |
} | |
} | |
} while(0); | |
do { | |
if ((label|0) == 182) { | |
$575 = (_sbrk(0)|0); | |
$576 = ($575|0)==((-1)|0); | |
if ($576) { | |
$tsize$0323841$i = 0; | |
} else { | |
$577 = $575; | |
$578 = HEAP32[((496 + 4|0))>>2]|0; | |
$579 = (($578) + -1)|0; | |
$580 = $579 & $577; | |
$581 = ($580|0)==(0); | |
if ($581) { | |
$ssize$0$i = $552; | |
} else { | |
$582 = (($579) + ($577))|0; | |
$583 = (0 - ($578))|0; | |
$584 = $582 & $583; | |
$585 = (($552) - ($577))|0; | |
$586 = (($585) + ($584))|0; | |
$ssize$0$i = $586; | |
} | |
$587 = HEAP32[((24 + 432|0))>>2]|0; | |
$588 = (($587) + ($ssize$0$i))|0; | |
$589 = ($ssize$0$i>>>0)>($nb$0>>>0); | |
$590 = ($ssize$0$i>>>0)<(2147483647); | |
$or$cond$i29 = $589 & $590; | |
if ($or$cond$i29) { | |
$591 = HEAP32[((24 + 440|0))>>2]|0; | |
$592 = ($591|0)==(0); | |
if (!($592)) { | |
$593 = ($588>>>0)<=($587>>>0); | |
$594 = ($588>>>0)>($591>>>0); | |
$or$cond2$i = $593 | $594; | |
if ($or$cond2$i) { | |
$tsize$0323841$i = 0; | |
break; | |
} | |
} | |
$595 = (_sbrk(($ssize$0$i|0))|0); | |
$596 = ($595|0)==($575|0); | |
$ssize$0$$i = $596 ? $ssize$0$i : 0; | |
$$$i = $596 ? $575 : (-1); | |
$br$0$i = $595;$ssize$1$i = $ssize$0$i;$tbase$0$i = $$$i;$tsize$0$i = $ssize$0$$i; | |
label = 191; | |
} else { | |
$tsize$0323841$i = 0; | |
} | |
} | |
} | |
} while(0); | |
L291: do { | |
if ((label|0) == 191) { | |
$606 = (0 - ($ssize$1$i))|0; | |
$607 = ($tbase$0$i|0)==((-1)|0); | |
if (!($607)) { | |
$tbase$247$i = $tbase$0$i;$tsize$246$i = $tsize$0$i; | |
label = 202; | |
break L269; | |
} | |
$608 = ($br$0$i|0)!=((-1)|0); | |
$609 = ($ssize$1$i>>>0)<(2147483647); | |
$or$cond5$i = $608 & $609; | |
$610 = ($ssize$1$i>>>0)<($547>>>0); | |
$or$cond6$i = $or$cond5$i & $610; | |
do { | |
if ($or$cond6$i) { | |
$611 = HEAP32[((496 + 8|0))>>2]|0; | |
$612 = (($549) - ($ssize$1$i))|0; | |
$613 = (($612) + ($611))|0; | |
$614 = (0 - ($611))|0; | |
$615 = $613 & $614; | |
$616 = ($615>>>0)<(2147483647); | |
if ($616) { | |
$617 = (_sbrk(($615|0))|0); | |
$618 = ($617|0)==((-1)|0); | |
if ($618) { | |
(_sbrk(($606|0))|0); | |
$tsize$0323841$i = $tsize$0$i; | |
break L291; | |
} else { | |
$619 = (($615) + ($ssize$1$i))|0; | |
$ssize$2$i = $619; | |
break; | |
} | |
} else { | |
$ssize$2$i = $ssize$1$i; | |
} | |
} else { | |
$ssize$2$i = $ssize$1$i; | |
} | |
} while(0); | |
$620 = ($br$0$i|0)==((-1)|0); | |
if ($620) { | |
$tsize$0323841$i = $tsize$0$i; | |
} else { | |
$tbase$247$i = $br$0$i;$tsize$246$i = $ssize$2$i; | |
label = 202; | |
break L269; | |
} | |
} | |
} while(0); | |
$621 = HEAP32[((24 + 444|0))>>2]|0; | |
$622 = $621 | 4; | |
HEAP32[((24 + 444|0))>>2] = $622; | |
$tsize$1$i = $tsize$0323841$i; | |
label = 199; | |
} else { | |
$tsize$1$i = 0; | |
label = 199; | |
} | |
} while(0); | |
if ((label|0) == 199) { | |
$623 = ($552>>>0)<(2147483647); | |
if ($623) { | |
$624 = (_sbrk(($552|0))|0); | |
$625 = (_sbrk(0)|0); | |
$notlhs$i = ($624|0)!=((-1)|0); | |
$notrhs$i = ($625|0)!=((-1)|0); | |
$or$cond8$not$i = $notrhs$i & $notlhs$i; | |
$626 = ($624>>>0)<($625>>>0); | |
$or$cond9$i = $or$cond8$not$i & $626; | |
if ($or$cond9$i) { | |
$627 = $625; | |
$628 = $624; | |
$629 = (($627) - ($628))|0; | |
$630 = (($nb$0) + 40)|0; | |
$631 = ($629>>>0)>($630>>>0); | |
$$tsize$1$i = $631 ? $629 : $tsize$1$i; | |
if ($631) { | |
$tbase$247$i = $624;$tsize$246$i = $$tsize$1$i; | |
label = 202; | |
} | |
} | |
} | |
} | |
if ((label|0) == 202) { | |
$632 = HEAP32[((24 + 432|0))>>2]|0; | |
$633 = (($632) + ($tsize$246$i))|0; | |
HEAP32[((24 + 432|0))>>2] = $633; | |
$634 = HEAP32[((24 + 436|0))>>2]|0; | |
$635 = ($633>>>0)>($634>>>0); | |
if ($635) { | |
HEAP32[((24 + 436|0))>>2] = $633; | |
} | |
$636 = HEAP32[((24 + 24|0))>>2]|0; | |
$637 = ($636|0)==(0|0); | |
L311: do { | |
if ($637) { | |
$638 = HEAP32[((24 + 16|0))>>2]|0; | |
$639 = ($638|0)==(0|0); | |
$640 = ($tbase$247$i>>>0)<($638>>>0); | |
$or$cond10$i = $639 | $640; | |
if ($or$cond10$i) { | |
HEAP32[((24 + 16|0))>>2] = $tbase$247$i; | |
} | |
HEAP32[((24 + 448|0))>>2] = $tbase$247$i; | |
HEAP32[((24 + 452|0))>>2] = $tsize$246$i; | |
HEAP32[((24 + 460|0))>>2] = 0; | |
$641 = HEAP32[496>>2]|0; | |
HEAP32[((24 + 36|0))>>2] = $641; | |
HEAP32[((24 + 32|0))>>2] = -1; | |
$i$02$i$i = 0; | |
while(1) { | |
$642 = $i$02$i$i << 1; | |
$643 = ((24 + ($642<<2)|0) + 40|0); | |
$$sum$i$i = (($642) + 3)|0; | |
$644 = ((24 + ($$sum$i$i<<2)|0) + 40|0); | |
HEAP32[$644>>2] = $643; | |
$$sum1$i$i = (($642) + 2)|0; | |
$645 = ((24 + ($$sum1$i$i<<2)|0) + 40|0); | |
HEAP32[$645>>2] = $643; | |
$646 = (($i$02$i$i) + 1)|0; | |
$exitcond$i$i = ($646|0)==(32); | |
if ($exitcond$i$i) { | |
break; | |
} else { | |
$i$02$i$i = $646; | |
} | |
} | |
$647 = (($tsize$246$i) + -40)|0; | |
$648 = (($tbase$247$i) + 8|0); | |
$649 = $648; | |
$650 = $649 & 7; | |
$651 = ($650|0)==(0); | |
if ($651) { | |
$655 = 0; | |
} else { | |
$652 = (0 - ($649))|0; | |
$653 = $652 & 7; | |
$655 = $653; | |
} | |
$654 = (($tbase$247$i) + ($655)|0); | |
$656 = (($647) - ($655))|0; | |
HEAP32[((24 + 24|0))>>2] = $654; | |
HEAP32[((24 + 12|0))>>2] = $656; | |
$657 = $656 | 1; | |
$$sum$i14$i = (($655) + 4)|0; | |
$658 = (($tbase$247$i) + ($$sum$i14$i)|0); | |
HEAP32[$658>>2] = $657; | |
$$sum2$i$i = (($tsize$246$i) + -36)|0; | |
$659 = (($tbase$247$i) + ($$sum2$i$i)|0); | |
HEAP32[$659>>2] = 40; | |
$660 = HEAP32[((496 + 16|0))>>2]|0; | |
HEAP32[((24 + 28|0))>>2] = $660; | |
} else { | |
$sp$075$i = ((24 + 448|0)); | |
while(1) { | |
$661 = HEAP32[$sp$075$i>>2]|0; | |
$662 = (($sp$075$i) + 4|0); | |
$663 = HEAP32[$662>>2]|0; | |
$664 = (($661) + ($663)|0); | |
$665 = ($tbase$247$i|0)==($664|0); | |
if ($665) { | |
label = 214; | |
break; | |
} | |
$666 = (($sp$075$i) + 8|0); | |
$667 = HEAP32[$666>>2]|0; | |
$668 = ($667|0)==(0|0); | |
if ($668) { | |
break; | |
} else { | |
$sp$075$i = $667; | |
} | |
} | |
if ((label|0) == 214) { | |
$669 = (($sp$075$i) + 12|0); | |
$670 = HEAP32[$669>>2]|0; | |
$671 = $670 & 8; | |
$672 = ($671|0)==(0); | |
if ($672) { | |
$673 = ($636>>>0)>=($661>>>0); | |
$674 = ($636>>>0)<($tbase$247$i>>>0); | |
$or$cond49$i = $673 & $674; | |
if ($or$cond49$i) { | |
$675 = (($663) + ($tsize$246$i))|0; | |
HEAP32[$662>>2] = $675; | |
$676 = HEAP32[((24 + 12|0))>>2]|0; | |
$677 = (($676) + ($tsize$246$i))|0; | |
$678 = (($636) + 8|0); | |
$679 = $678; | |
$680 = $679 & 7; | |
$681 = ($680|0)==(0); | |
if ($681) { | |
$685 = 0; | |
} else { | |
$682 = (0 - ($679))|0; | |
$683 = $682 & 7; | |
$685 = $683; | |
} | |
$684 = (($636) + ($685)|0); | |
$686 = (($677) - ($685))|0; | |
HEAP32[((24 + 24|0))>>2] = $684; | |
HEAP32[((24 + 12|0))>>2] = $686; | |
$687 = $686 | 1; | |
$$sum$i18$i = (($685) + 4)|0; | |
$688 = (($636) + ($$sum$i18$i)|0); | |
HEAP32[$688>>2] = $687; | |
$$sum2$i19$i = (($677) + 4)|0; | |
$689 = (($636) + ($$sum2$i19$i)|0); | |
HEAP32[$689>>2] = 40; | |
$690 = HEAP32[((496 + 16|0))>>2]|0; | |
HEAP32[((24 + 28|0))>>2] = $690; | |
break; | |
} | |
} | |
} | |
$691 = HEAP32[((24 + 16|0))>>2]|0; | |
$692 = ($tbase$247$i>>>0)<($691>>>0); | |
if ($692) { | |
HEAP32[((24 + 16|0))>>2] = $tbase$247$i; | |
} | |
$693 = (($tbase$247$i) + ($tsize$246$i)|0); | |
$sp$168$i = ((24 + 448|0)); | |
while(1) { | |
$694 = HEAP32[$sp$168$i>>2]|0; | |
$695 = ($694|0)==($693|0); | |
if ($695) { | |
label = 224; | |
break; | |
} | |
$696 = (($sp$168$i) + 8|0); | |
$697 = HEAP32[$696>>2]|0; | |
$698 = ($697|0)==(0|0); | |
if ($698) { | |
break; | |
} else { | |
$sp$168$i = $697; | |
} | |
} | |
if ((label|0) == 224) { | |
$699 = (($sp$168$i) + 12|0); | |
$700 = HEAP32[$699>>2]|0; | |
$701 = $700 & 8; | |
$702 = ($701|0)==(0); | |
if ($702) { | |
HEAP32[$sp$168$i>>2] = $tbase$247$i; | |
$703 = (($sp$168$i) + 4|0); | |
$704 = HEAP32[$703>>2]|0; | |
$705 = (($704) + ($tsize$246$i))|0; | |
HEAP32[$703>>2] = $705; | |
$706 = (($tbase$247$i) + 8|0); | |
$707 = $706; | |
$708 = $707 & 7; | |
$709 = ($708|0)==(0); | |
if ($709) { | |
$713 = 0; | |
} else { | |
$710 = (0 - ($707))|0; | |
$711 = $710 & 7; | |
$713 = $711; | |
} | |
$712 = (($tbase$247$i) + ($713)|0); | |
$$sum107$i = (($tsize$246$i) + 8)|0; | |
$714 = (($tbase$247$i) + ($$sum107$i)|0); | |
$715 = $714; | |
$716 = $715 & 7; | |
$717 = ($716|0)==(0); | |
if ($717) { | |
$720 = 0; | |
} else { | |
$718 = (0 - ($715))|0; | |
$719 = $718 & 7; | |
$720 = $719; | |
} | |
$$sum108$i = (($720) + ($tsize$246$i))|0; | |
$721 = (($tbase$247$i) + ($$sum108$i)|0); | |
$722 = $721; | |
$723 = $712; | |
$724 = (($722) - ($723))|0; | |
$$sum$i21$i = (($713) + ($nb$0))|0; | |
$725 = (($tbase$247$i) + ($$sum$i21$i)|0); | |
$726 = (($724) - ($nb$0))|0; | |
$727 = $nb$0 | 3; | |
$$sum1$i22$i = (($713) + 4)|0; | |
$728 = (($tbase$247$i) + ($$sum1$i22$i)|0); | |
HEAP32[$728>>2] = $727; | |
$729 = HEAP32[((24 + 24|0))>>2]|0; | |
$730 = ($721|0)==($729|0); | |
L348: do { | |
if ($730) { | |
$731 = HEAP32[((24 + 12|0))>>2]|0; | |
$732 = (($731) + ($726))|0; | |
HEAP32[((24 + 12|0))>>2] = $732; | |
HEAP32[((24 + 24|0))>>2] = $725; | |
$733 = $732 | 1; | |
$$sum42$i$i = (($$sum$i21$i) + 4)|0; | |
$734 = (($tbase$247$i) + ($$sum42$i$i)|0); | |
HEAP32[$734>>2] = $733; | |
} else { | |
$735 = HEAP32[((24 + 20|0))>>2]|0; | |
$736 = ($721|0)==($735|0); | |
if ($736) { | |
$737 = HEAP32[((24 + 8|0))>>2]|0; | |
$738 = (($737) + ($726))|0; | |
HEAP32[((24 + 8|0))>>2] = $738; | |
HEAP32[((24 + 20|0))>>2] = $725; | |
$739 = $738 | 1; | |
$$sum40$i$i = (($$sum$i21$i) + 4)|0; | |
$740 = (($tbase$247$i) + ($$sum40$i$i)|0); | |
HEAP32[$740>>2] = $739; | |
$$sum41$i$i = (($738) + ($$sum$i21$i))|0; | |
$741 = (($tbase$247$i) + ($$sum41$i$i)|0); | |
HEAP32[$741>>2] = $738; | |
break; | |
} | |
$$sum2$i23$i = (($tsize$246$i) + 4)|0; | |
$$sum109$i = (($$sum2$i23$i) + ($720))|0; | |
$742 = (($tbase$247$i) + ($$sum109$i)|0); | |
$743 = HEAP32[$742>>2]|0; | |
$744 = $743 & 3; | |
$745 = ($744|0)==(1); | |
if ($745) { | |
$746 = $743 & -8; | |
$747 = $743 >>> 3; | |
$748 = ($743>>>0)<(256); | |
L355: do { | |
if ($748) { | |
$$sum3738$i$i = $720 | 8; | |
$$sum119$i = (($$sum3738$i$i) + ($tsize$246$i))|0; | |
$749 = (($tbase$247$i) + ($$sum119$i)|0); | |
$750 = HEAP32[$749>>2]|0; | |
$$sum39$i$i = (($tsize$246$i) + 12)|0; | |
$$sum120$i = (($$sum39$i$i) + ($720))|0; | |
$751 = (($tbase$247$i) + ($$sum120$i)|0); | |
$752 = HEAP32[$751>>2]|0; | |
$753 = $747 << 1; | |
$754 = ((24 + ($753<<2)|0) + 40|0); | |
$755 = ($750|0)==($754|0); | |
do { | |
if (!($755)) { | |
$756 = HEAP32[((24 + 16|0))>>2]|0; | |
$757 = ($750>>>0)<($756>>>0); | |
if ($757) { | |
_abort(); | |
// unreachable; | |
} | |
$758 = (($750) + 12|0); | |
$759 = HEAP32[$758>>2]|0; | |
$760 = ($759|0)==($721|0); | |
if ($760) { | |
break; | |
} | |
_abort(); | |
// unreachable; | |
} | |
} while(0); | |
$761 = ($752|0)==($750|0); | |
if ($761) { | |
$762 = 1 << $747; | |
$763 = $762 ^ -1; | |
$764 = HEAP32[24>>2]|0; | |
$765 = $764 & $763; | |
HEAP32[24>>2] = $765; | |
break; | |
} | |
$766 = ($752|0)==($754|0); | |
do { | |
if ($766) { | |
$$pre57$i$i = (($752) + 8|0); | |
$$pre$phi58$i$iZ2D = $$pre57$i$i; | |
} else { | |
$767 = HEAP32[((24 + 16|0))>>2]|0; | |
$768 = ($752>>>0)<($767>>>0); | |
if ($768) { | |
_abort(); | |
// unreachable; | |
} | |
$769 = (($752) + 8|0); | |
$770 = HEAP32[$769>>2]|0; | |
$771 = ($770|0)==($721|0); | |
if ($771) { | |
$$pre$phi58$i$iZ2D = $769; | |
break; | |
} | |
_abort(); | |
// unreachable; | |
} | |
} while(0); | |
$772 = (($750) + 12|0); | |
HEAP32[$772>>2] = $752; | |
HEAP32[$$pre$phi58$i$iZ2D>>2] = $750; | |
} else { | |
$$sum34$i$i = $720 | 24; | |
$$sum110$i = (($$sum34$i$i) + ($tsize$246$i))|0; | |
$773 = (($tbase$247$i) + ($$sum110$i)|0); | |
$774 = HEAP32[$773>>2]|0; | |
$$sum5$i$i = (($tsize$246$i) + 12)|0; | |
$$sum111$i = (($$sum5$i$i) + ($720))|0; | |
$775 = (($tbase$247$i) + ($$sum111$i)|0); | |
$776 = HEAP32[$775>>2]|0; | |
$777 = ($776|0)==($721|0); | |
do { | |
if ($777) { | |
$$sum67$i$i = $720 | 16; | |
$$sum117$i = (($$sum2$i23$i) + ($$sum67$i$i))|0; | |
$788 = (($tbase$247$i) + ($$sum117$i)|0); | |
$789 = HEAP32[$788>>2]|0; | |
$790 = ($789|0)==(0|0); | |
if ($790) { | |
$$sum118$i = (($$sum67$i$i) + ($tsize$246$i))|0; | |
$791 = (($tbase$247$i) + ($$sum118$i)|0); | |
$792 = HEAP32[$791>>2]|0; | |
$793 = ($792|0)==(0|0); | |
if ($793) { | |
$R$1$i$i = 0; | |
break; | |
} else { | |
$R$0$i$i = $792;$RP$0$i$i = $791; | |
} | |
} else { | |
$R$0$i$i = $789;$RP$0$i$i = $788; | |
} | |
while(1) { | |
$794 = (($R$0$i$i) + 20|0); | |
$795 = HEAP32[$794>>2]|0; | |
$796 = ($795|0)==(0|0); | |
if (!($796)) { | |
$R$0$i$i = $795;$RP$0$i$i = $794; | |
continue; | |
} | |
$797 = (($R$0$i$i) + 16|0); | |
$798 = HEAP32[$797>>2]|0; | |
$799 = ($798|0)==(0|0); | |
if ($799) { | |
break; | |
} else { | |
$R$0$i$i = $798;$RP$0$i$i = $797; | |
} | |
} | |
$800 = HEAP32[((24 + 16|0))>>2]|0; | |
$801 = ($RP$0$i$i>>>0)<($800>>>0); | |
if ($801) { | |
_abort(); | |
// unreachable; | |
} else { | |
HEAP32[$RP$0$i$i>>2] = 0; | |
$R$1$i$i = $R$0$i$i; | |
break; | |
} | |
} else { | |
$$sum3536$i$i = $720 | 8; | |
$$sum112$i = (($$sum3536$i$i) + ($tsize$246$i))|0; | |
$778 = (($tbase$247$i) + ($$sum112$i)|0); | |
$779 = HEAP32[$778>>2]|0; | |
$780 = HEAP32[((24 + 16|0))>>2]|0; | |
$781 = ($779>>>0)<($780>>>0); | |
if ($781) { | |
_abort(); | |
// unreachable; | |
} | |
$782 = (($779) + 12|0); | |
$783 = HEAP32[$782>>2]|0; | |
$784 = ($783|0)==($721|0); | |
if (!($784)) { | |
_abort(); | |
// unreachable; | |
} | |
$785 = (($776) + 8|0); | |
$786 = HEAP32[$785>>2]|0; | |
$787 = ($786|0)==($721|0); | |
if ($787) { | |
HEAP32[$782>>2] = $776; | |
HEAP32[$785>>2] = $779; | |
$R$1$i$i = $776; | |
break; | |
} else { | |
_abort(); | |
// unreachable; | |
} | |
} | |
} while(0); | |
$802 = ($774|0)==(0|0); | |
if ($802) { | |
break; | |
} | |
$$sum30$i$i = (($tsize$246$i) + 28)|0; | |
$$sum113$i = (($$sum30$i$i) + ($720))|0; | |
$803 = (($tbase$247$i) + ($$sum113$i)|0); | |
$804 = HEAP32[$803>>2]|0; | |
$805 = ((24 + ($804<<2)|0) + 304|0); | |
$806 = HEAP32[$805>>2]|0; | |
$807 = ($721|0)==($806|0); | |
do { | |
if ($807) { | |
HEAP32[$805>>2] = $R$1$i$i; | |
$cond$i$i = ($R$1$i$i|0)==(0|0); | |
if (!($cond$i$i)) { | |
break; | |
} | |
$808 = 1 << $804; | |
$809 = $808 ^ -1; | |
$810 = HEAP32[((24 + 4|0))>>2]|0; | |
$811 = $810 & $809; | |
HEAP32[((24 + 4|0))>>2] = $811; | |
break L355; | |
} else { | |
$812 = HEAP32[((24 + 16|0))>>2]|0; | |
$813 = ($774>>>0)<($812>>>0); | |
if ($813) { | |
_abort(); | |
// unreachable; | |
} | |
$814 = (($774) + 16|0); | |
$815 = HEAP32[$814>>2]|0; | |
$816 = ($815|0)==($721|0); | |
if ($816) { | |
HEAP32[$814>>2] = $R$1$i$i; | |
} else { | |
$817 = (($774) + 20|0); | |
HEAP32[$817>>2] = $R$1$i$i; | |
} | |
$818 = ($R$1$i$i|0)==(0|0); | |
if ($818) { | |
break L355; | |
} | |
} | |
} while(0); | |
$819 = HEAP32[((24 + 16|0))>>2]|0; | |
$820 = ($R$1$i$i>>>0)<($819>>>0); | |
if ($820) { | |
_abort(); | |
// unreachable; | |
} | |
$821 = (($R$1$i$i) + 24|0); | |
HEAP32[$821>>2] = $774; | |
$$sum3132$i$i = $720 | 16; | |
$$sum114$i = (($$sum3132$i$i) + ($tsize$246$i))|0; | |
$822 = (($tbase$247$i) + ($$sum114$i)|0); | |
$823 = HEAP32[$822>>2]|0; | |
$824 = ($823|0)==(0|0); | |
do { | |
if (!($824)) { | |
$825 = HEAP32[((24 + 16|0))>>2]|0; | |
$826 = ($823>>>0)<($825>>>0); | |
if ($826) { | |
_abort(); | |
// unreachable; | |
} else { | |
$827 = (($R$1$i$i) + 16|0); | |
HEAP32[$827>>2] = $823; | |
$828 = (($823) + 24|0); | |
HEAP32[$828>>2] = $R$1$i$i; | |
break; | |
} | |
} | |
} while(0); | |
$$sum115$i = (($$sum2$i23$i) + ($$sum3132$i$i))|0; | |
$829 = (($tbase$247$i) + ($$sum115$i)|0); | |
$830 = HEAP32[$829>>2]|0; | |
$831 = ($830|0)==(0|0); | |
if ($831) { | |
break; | |
} | |
$832 = HEAP32[((24 + 16|0))>>2]|0; | |
$833 = ($830>>>0)<($832>>>0); | |
if ($833) { | |
_abort(); | |
// unreachable; | |
} else { | |
$834 = (($R$1$i$i) + 20|0); | |
HEAP32[$834>>2] = $830; | |
$835 = (($830) + 24|0); | |
HEAP32[$835>>2] = $R$1$i$i; | |
break; | |
} | |
} | |
} while(0); | |
$$sum9$i$i = $746 | $720; | |
$$sum116$i = (($$sum9$i$i) + ($tsize$246$i))|0; | |
$836 = (($tbase$247$i) + ($$sum116$i)|0); | |
$837 = (($746) + ($726))|0; | |
$oldfirst$0$i$i = $836;$qsize$0$i$i = $837; | |
} else { | |
$oldfirst$0$i$i = $721;$qsize$0$i$i = $726; | |
} | |
$838 = (($oldfirst$0$i$i) + 4|0); | |
$839 = HEAP32[$838>>2]|0; | |
$840 = $839 & -2; | |
HEAP32[$838>>2] = $840; | |
$841 = $qsize$0$i$i | 1; | |
$$sum10$i$i = (($$sum$i21$i) + 4)|0; | |
$842 = (($tbase$247$i) + ($$sum10$i$i)|0); | |
HEAP32[$842>>2] = $841; | |
$$sum11$i24$i = (($qsize$0$i$i) + ($$sum$i21$i))|0; | |
$843 = (($tbase$247$i) + ($$sum11$i24$i)|0); | |
HEAP32[$843>>2] = $qsize$0$i$i; | |
$844 = $qsize$0$i$i >>> 3; | |
$845 = ($qsize$0$i$i>>>0)<(256); | |
if ($845) { | |
$846 = $844 << 1; | |
$847 = ((24 + ($846<<2)|0) + 40|0); | |
$848 = HEAP32[24>>2]|0; | |
$849 = 1 << $844; | |
$850 = $848 & $849; | |
$851 = ($850|0)==(0); | |
do { | |
if ($851) { | |
$852 = $848 | $849; | |
HEAP32[24>>2] = $852; | |
$$sum26$pre$i$i = (($846) + 2)|0; | |
$$pre$i25$i = ((24 + ($$sum26$pre$i$i<<2)|0) + 40|0); | |
$$pre$phi$i26$iZ2D = $$pre$i25$i;$F4$0$i$i = $847; | |
} else { | |
$$sum29$i$i = (($846) + 2)|0; | |
$853 = ((24 + ($$sum29$i$i<<2)|0) + 40|0); | |
$854 = HEAP32[$853>>2]|0; | |
$855 = HEAP32[((24 + 16|0))>>2]|0; | |
$856 = ($854>>>0)<($855>>>0); | |
if (!($856)) { | |
$$pre$phi$i26$iZ2D = $853;$F4$0$i$i = $854; | |
break; | |
} | |
_abort(); | |
// unreachable; | |
} | |
} while(0); | |
HEAP32[$$pre$phi$i26$iZ2D>>2] = $725; | |
$857 = (($F4$0$i$i) + 12|0); | |
HEAP32[$857>>2] = $725; | |
$$sum27$i$i = (($$sum$i21$i) + 8)|0; | |
$858 = (($tbase$247$i) + ($$sum27$i$i)|0); | |
HEAP32[$858>>2] = $F4$0$i$i; | |
$$sum28$i$i = (($$sum$i21$i) + 12)|0; | |
$859 = (($tbase$247$i) + ($$sum28$i$i)|0); | |
HEAP32[$859>>2] = $847; | |
break; | |
} | |
$860 = $qsize$0$i$i >>> 8; | |
$861 = ($860|0)==(0); | |
do { | |
if ($861) { | |
$I7$0$i$i = 0; | |
} else { | |
$862 = ($qsize$0$i$i>>>0)>(16777215); | |
if ($862) { | |
$I7$0$i$i = 31; | |
break; | |
} | |
$863 = (($860) + 1048320)|0; | |
$864 = $863 >>> 16; | |
$865 = $864 & 8; | |
$866 = $860 << $865; | |
$867 = (($866) + 520192)|0; | |
$868 = $867 >>> 16; | |
$869 = $868 & 4; | |
$870 = $869 | $865; | |
$871 = $866 << $869; | |
$872 = (($871) + 245760)|0; | |
$873 = $872 >>> 16; | |
$874 = $873 & 2; | |
$875 = $870 | $874; | |
$876 = (14 - ($875))|0; | |
$877 = $871 << $874; | |
$878 = $877 >>> 15; | |
$879 = (($876) + ($878))|0; | |
$880 = $879 << 1; | |
$881 = (($879) + 7)|0; | |
$882 = $qsize$0$i$i >>> $881; | |
$883 = $882 & 1; | |
$884 = $883 | $880; | |
$I7$0$i$i = $884; | |
} | |
} while(0); | |
$885 = ((24 + ($I7$0$i$i<<2)|0) + 304|0); | |
$$sum12$i$i = (($$sum$i21$i) + 28)|0; | |
$886 = (($tbase$247$i) + ($$sum12$i$i)|0); | |
HEAP32[$886>>2] = $I7$0$i$i; | |
$$sum13$i$i = (($$sum$i21$i) + 16)|0; | |
$887 = (($tbase$247$i) + ($$sum13$i$i)|0); | |
$$sum14$i$i = (($$sum$i21$i) + 20)|0; | |
$888 = (($tbase$247$i) + ($$sum14$i$i)|0); | |
HEAP32[$888>>2] = 0; | |
HEAP32[$887>>2] = 0; | |
$889 = HEAP32[((24 + 4|0))>>2]|0; | |
$890 = 1 << $I7$0$i$i; | |
$891 = $889 & $890; | |
$892 = ($891|0)==(0); | |
if ($892) { | |
$893 = $889 | $890; | |
HEAP32[((24 + 4|0))>>2] = $893; | |
HEAP32[$885>>2] = $725; | |
$$sum15$i$i = (($$sum$i21$i) + 24)|0; | |
$894 = (($tbase$247$i) + ($$sum15$i$i)|0); | |
HEAP32[$894>>2] = $885; | |
$$sum16$i$i = (($$sum$i21$i) + 12)|0; | |
$895 = (($tbase$247$i) + ($$sum16$i$i)|0); | |
HEAP32[$895>>2] = $725; | |
$$sum17$i$i = (($$sum$i21$i) + 8)|0; | |
$896 = (($tbase$247$i) + ($$sum17$i$i)|0); | |
HEAP32[$896>>2] = $725; | |
break; | |
} | |
$897 = HEAP32[$885>>2]|0; | |
$898 = ($I7$0$i$i|0)==(31); | |
if ($898) { | |
$906 = 0; | |
} else { | |
$899 = $I7$0$i$i >>> 1; | |
$900 = (25 - ($899))|0; | |
$906 = $900; | |
} | |
$901 = (($897) + 4|0); | |
$902 = HEAP32[$901>>2]|0; | |
$903 = $902 & -8; | |
$904 = ($903|0)==($qsize$0$i$i|0); | |
L444: do { | |
if ($904) { | |
$T$0$lcssa$i28$i = $897; | |
} else { | |
$905 = $qsize$0$i$i << $906; | |
$K8$052$i$i = $905;$T$051$i$i = $897; | |
while(1) { | |
$913 = $K8$052$i$i >>> 31; | |
$914 = ((($T$051$i$i) + ($913<<2)|0) + 16|0); | |
$909 = HEAP32[$914>>2]|0; | |
$915 = ($909|0)==(0|0); | |
if ($915) { | |
break; | |
} | |
$907 = $K8$052$i$i << 1; | |
$908 = (($909) + 4|0); | |
$910 = HEAP32[$908>>2]|0; | |
$911 = $910 & -8; | |
$912 = ($911|0)==($qsize$0$i$i|0); | |
if ($912) { | |
$T$0$lcssa$i28$i = $909; | |
break L444; | |
} else { | |
$K8$052$i$i = $907;$T$051$i$i = $909; | |
} | |
} | |
$916 = HEAP32[((24 + 16|0))>>2]|0; | |
$917 = ($914>>>0)<($916>>>0); | |
if ($917) { | |
_abort(); | |
// unreachable; | |
} else { | |
HEAP32[$914>>2] = $725; | |
$$sum23$i$i = (($$sum$i21$i) + 24)|0; | |
$918 = (($tbase$247$i) + ($$sum23$i$i)|0); | |
HEAP32[$918>>2] = $T$051$i$i; | |
$$sum24$i$i = (($$sum$i21$i) + 12)|0; | |
$919 = (($tbase$247$i) + ($$sum24$i$i)|0); | |
HEAP32[$919>>2] = $725; | |
$$sum25$i$i = (($$sum$i21$i) + 8)|0; | |
$920 = (($tbase$247$i) + ($$sum25$i$i)|0); | |
HEAP32[$920>>2] = $725; | |
break L348; | |
} | |
} | |
} while(0); | |
$921 = (($T$0$lcssa$i28$i) + 8|0); | |
$922 = HEAP32[$921>>2]|0; | |
$923 = HEAP32[((24 + 16|0))>>2]|0; | |
$924 = ($T$0$lcssa$i28$i>>>0)<($923>>>0); | |
if ($924) { | |
_abort(); | |
// unreachable; | |
} | |
$925 = ($922>>>0)<($923>>>0); | |
if ($925) { | |
_abort(); | |
// unreachable; | |
} else { | |
$926 = (($922) + 12|0); | |
HEAP32[$926>>2] = $725; | |
HEAP32[$921>>2] = $725; | |
$$sum20$i$i = (($$sum$i21$i) + 8)|0; | |
$927 = (($tbase$247$i) + ($$sum20$i$i)|0); | |
HEAP32[$927>>2] = $922; | |
$$sum21$i$i = (($$sum$i21$i) + 12)|0; | |
$928 = (($tbase$247$i) + ($$sum21$i$i)|0); | |
HEAP32[$928>>2] = $T$0$lcssa$i28$i; | |
$$sum22$i$i = (($$sum$i21$i) + 24)|0; | |
$929 = (($tbase$247$i) + ($$sum22$i$i)|0); | |
HEAP32[$929>>2] = 0; | |
break; | |
} | |
} | |
} while(0); | |
$$sum1819$i$i = $713 | 8; | |
$930 = (($tbase$247$i) + ($$sum1819$i$i)|0); | |
$mem$0 = $930; | |
STACKTOP = sp;return ($mem$0|0); | |
} | |
} | |
$sp$0$i$i$i = ((24 + 448|0)); | |
while(1) { | |
$931 = HEAP32[$sp$0$i$i$i>>2]|0; | |
$932 = ($931>>>0)>($636>>>0); | |
if (!($932)) { | |
$933 = (($sp$0$i$i$i) + 4|0); | |
$934 = HEAP32[$933>>2]|0; | |
$935 = (($931) + ($934)|0); | |
$936 = ($935>>>0)>($636>>>0); | |
if ($936) { | |
break; | |
} | |
} | |
$937 = (($sp$0$i$i$i) + 8|0); | |
$938 = HEAP32[$937>>2]|0; | |
$sp$0$i$i$i = $938; | |
} | |
$$sum$i15$i = (($934) + -47)|0; | |
$$sum1$i16$i = (($934) + -39)|0; | |
$939 = (($931) + ($$sum1$i16$i)|0); | |
$940 = $939; | |
$941 = $940 & 7; | |
$942 = ($941|0)==(0); | |
if ($942) { | |
$945 = 0; | |
} else { | |
$943 = (0 - ($940))|0; | |
$944 = $943 & 7; | |
$945 = $944; | |
} | |
$$sum2$i17$i = (($$sum$i15$i) + ($945))|0; | |
$946 = (($931) + ($$sum2$i17$i)|0); | |
$947 = (($636) + 16|0); | |
$948 = ($946>>>0)<($947>>>0); | |
$949 = $948 ? $636 : $946; | |
$950 = (($949) + 8|0); | |
$951 = (($tsize$246$i) + -40)|0; | |
$952 = (($tbase$247$i) + 8|0); | |
$953 = $952; | |
$954 = $953 & 7; | |
$955 = ($954|0)==(0); | |
if ($955) { | |
$959 = 0; | |
} else { | |
$956 = (0 - ($953))|0; | |
$957 = $956 & 7; | |
$959 = $957; | |
} | |
$958 = (($tbase$247$i) + ($959)|0); | |
$960 = (($951) - ($959))|0; | |
HEAP32[((24 + 24|0))>>2] = $958; | |
HEAP32[((24 + 12|0))>>2] = $960; | |
$961 = $960 | 1; | |
$$sum$i$i$i = (($959) + 4)|0; | |
$962 = (($tbase$247$i) + ($$sum$i$i$i)|0); | |
HEAP32[$962>>2] = $961; | |
$$sum2$i$i$i = (($tsize$246$i) + -36)|0; | |
$963 = (($tbase$247$i) + ($$sum2$i$i$i)|0); | |
HEAP32[$963>>2] = 40; | |
$964 = HEAP32[((496 + 16|0))>>2]|0; | |
HEAP32[((24 + 28|0))>>2] = $964; | |
$965 = (($949) + 4|0); | |
HEAP32[$965>>2] = 27; | |
;HEAP32[$950+0>>2]=HEAP32[((24 + 448|0))+0>>2]|0;HEAP32[$950+4>>2]=HEAP32[((24 + 448|0))+4>>2]|0;HEAP32[$950+8>>2]=HEAP32[((24 + 448|0))+8>>2]|0;HEAP32[$950+12>>2]=HEAP32[((24 + 448|0))+12>>2]|0; | |
HEAP32[((24 + 448|0))>>2] = $tbase$247$i; | |
HEAP32[((24 + 452|0))>>2] = $tsize$246$i; | |
HEAP32[((24 + 460|0))>>2] = 0; | |
HEAP32[((24 + 456|0))>>2] = $950; | |
$966 = (($949) + 28|0); | |
HEAP32[$966>>2] = 7; | |
$967 = (($949) + 32|0); | |
$968 = ($967>>>0)<($935>>>0); | |
if ($968) { | |
$970 = $966; | |
while(1) { | |
$969 = (($970) + 4|0); | |
HEAP32[$969>>2] = 7; | |
$971 = (($970) + 8|0); | |
$972 = ($971>>>0)<($935>>>0); | |
if ($972) { | |
$970 = $969; | |
} else { | |
break; | |
} | |
} | |
} | |
$973 = ($949|0)==($636|0); | |
if (!($973)) { | |
$974 = $949; | |
$975 = $636; | |
$976 = (($974) - ($975))|0; | |
$977 = (($636) + ($976)|0); | |
$$sum3$i$i = (($976) + 4)|0; | |
$978 = (($636) + ($$sum3$i$i)|0); | |
$979 = HEAP32[$978>>2]|0; | |
$980 = $979 & -2; | |
HEAP32[$978>>2] = $980; | |
$981 = $976 | 1; | |
$982 = (($636) + 4|0); | |
HEAP32[$982>>2] = $981; | |
HEAP32[$977>>2] = $976; | |
$983 = $976 >>> 3; | |
$984 = ($976>>>0)<(256); | |
if ($984) { | |
$985 = $983 << 1; | |
$986 = ((24 + ($985<<2)|0) + 40|0); | |
$987 = HEAP32[24>>2]|0; | |
$988 = 1 << $983; | |
$989 = $987 & $988; | |
$990 = ($989|0)==(0); | |
do { | |
if ($990) { | |
$991 = $987 | $988; | |
HEAP32[24>>2] = $991; | |
$$sum10$pre$i$i = (($985) + 2)|0; | |
$$pre$i$i = ((24 + ($$sum10$pre$i$i<<2)|0) + 40|0); | |
$$pre$phi$i$iZ2D = $$pre$i$i;$F$0$i$i = $986; | |
} else { | |
$$sum11$i$i = (($985) + 2)|0; | |
$992 = ((24 + ($$sum11$i$i<<2)|0) + 40|0); | |
$993 = HEAP32[$992>>2]|0; | |
$994 = HEAP32[((24 + 16|0))>>2]|0; | |
$995 = ($993>>>0)<($994>>>0); | |
if (!($995)) { | |
$$pre$phi$i$iZ2D = $992;$F$0$i$i = $993; | |
break; | |
} | |
_abort(); | |
// unreachable; | |
} | |
} while(0); | |
HEAP32[$$pre$phi$i$iZ2D>>2] = $636; | |
$996 = (($F$0$i$i) + 12|0); | |
HEAP32[$996>>2] = $636; | |
$997 = (($636) + 8|0); | |
HEAP32[$997>>2] = $F$0$i$i; | |
$998 = (($636) + 12|0); | |
HEAP32[$998>>2] = $986; | |
break; | |
} | |
$999 = $976 >>> 8; | |
$1000 = ($999|0)==(0); | |
if ($1000) { | |
$I1$0$i$i = 0; | |
} else { | |
$1001 = ($976>>>0)>(16777215); | |
if ($1001) { | |
$I1$0$i$i = 31; | |
} else { | |
$1002 = (($999) + 1048320)|0; | |
$1003 = $1002 >>> 16; | |
$1004 = $1003 & 8; | |
$1005 = $999 << $1004; | |
$1006 = (($1005) + 520192)|0; | |
$1007 = $1006 >>> 16; | |
$1008 = $1007 & 4; | |
$1009 = $1008 | $1004; | |
$1010 = $1005 << $1008; | |
$1011 = (($1010) + 245760)|0; | |
$1012 = $1011 >>> 16; | |
$1013 = $1012 & 2; | |
$1014 = $1009 | $1013; | |
$1015 = (14 - ($1014))|0; | |
$1016 = $1010 << $1013; | |
$1017 = $1016 >>> 15; | |
$1018 = (($1015) + ($1017))|0; | |
$1019 = $1018 << 1; | |
$1020 = (($1018) + 7)|0; | |
$1021 = $976 >>> $1020; | |
$1022 = $1021 & 1; | |
$1023 = $1022 | $1019; | |
$I1$0$i$i = $1023; | |
} | |
} | |
$1024 = ((24 + ($I1$0$i$i<<2)|0) + 304|0); | |
$1025 = (($636) + 28|0); | |
$I1$0$c$i$i = $I1$0$i$i; | |
HEAP32[$1025>>2] = $I1$0$c$i$i; | |
$1026 = (($636) + 20|0); | |
HEAP32[$1026>>2] = 0; | |
$1027 = (($636) + 16|0); | |
HEAP32[$1027>>2] = 0; | |
$1028 = HEAP32[((24 + 4|0))>>2]|0; | |
$1029 = 1 << $I1$0$i$i; | |
$1030 = $1028 & $1029; | |
$1031 = ($1030|0)==(0); | |
if ($1031) { | |
$1032 = $1028 | $1029; | |
HEAP32[((24 + 4|0))>>2] = $1032; | |
HEAP32[$1024>>2] = $636; | |
$1033 = (($636) + 24|0); | |
HEAP32[$1033>>2] = $1024; | |
$1034 = (($636) + 12|0); | |
HEAP32[$1034>>2] = $636; | |
$1035 = (($636) + 8|0); | |
HEAP32[$1035>>2] = $636; | |
break; | |
} | |
$1036 = HEAP32[$1024>>2]|0; | |
$1037 = ($I1$0$i$i|0)==(31); | |
if ($1037) { | |
$1045 = 0; | |
} else { | |
$1038 = $I1$0$i$i >>> 1; | |
$1039 = (25 - ($1038))|0; | |
$1045 = $1039; | |
} | |
$1040 = (($1036) + 4|0); | |
$1041 = HEAP32[$1040>>2]|0; | |
$1042 = $1041 & -8; | |
$1043 = ($1042|0)==($976|0); | |
L499: do { | |
if ($1043) { | |
$T$0$lcssa$i$i = $1036; | |
} else { | |
$1044 = $976 << $1045; | |
$K2$014$i$i = $1044;$T$013$i$i = $1036; | |
while(1) { | |
$1052 = $K2$014$i$i >>> 31; | |
$1053 = ((($T$013$i$i) + ($1052<<2)|0) + 16|0); | |
$1048 = HEAP32[$1053>>2]|0; | |
$1054 = ($1048|0)==(0|0); | |
if ($1054) { | |
break; | |
} | |
$1046 = $K2$014$i$i << 1; | |
$1047 = (($1048) + 4|0); | |
$1049 = HEAP32[$1047>>2]|0; | |
$1050 = $1049 & -8; | |
$1051 = ($1050|0)==($976|0); | |
if ($1051) { | |
$T$0$lcssa$i$i = $1048; | |
break L499; | |
} else { | |
$K2$014$i$i = $1046;$T$013$i$i = $1048; | |
} | |
} | |
$1055 = HEAP32[((24 + 16|0))>>2]|0; | |
$1056 = ($1053>>>0)<($1055>>>0); | |
if ($1056) { | |
_abort(); | |
// unreachable; | |
} else { | |
HEAP32[$1053>>2] = $636; | |
$1057 = (($636) + 24|0); | |
HEAP32[$1057>>2] = $T$013$i$i; | |
$1058 = (($636) + 12|0); | |
HEAP32[$1058>>2] = $636; | |
$1059 = (($636) + 8|0); | |
HEAP32[$1059>>2] = $636; | |
break L311; | |
} | |
} | |
} while(0); | |
$1060 = (($T$0$lcssa$i$i) + 8|0); | |
$1061 = HEAP32[$1060>>2]|0; | |
$1062 = HEAP32[((24 + 16|0))>>2]|0; | |
$1063 = ($T$0$lcssa$i$i>>>0)<($1062>>>0); | |
if ($1063) { | |
_abort(); | |
// unreachable; | |
} | |
$1064 = ($1061>>>0)<($1062>>>0); | |
if ($1064) { | |
_abort(); | |
// unreachable; | |
} else { | |
$1065 = (($1061) + 12|0); | |
HEAP32[$1065>>2] = $636; | |
HEAP32[$1060>>2] = $636; | |
$1066 = (($636) + 8|0); | |
HEAP32[$1066>>2] = $1061; | |
$1067 = (($636) + 12|0); | |
HEAP32[$1067>>2] = $T$0$lcssa$i$i; | |
$1068 = (($636) + 24|0); | |
HEAP32[$1068>>2] = 0; | |
break; | |
} | |
} | |
} | |
} while(0); | |
$1069 = HEAP32[((24 + 12|0))>>2]|0; | |
$1070 = ($1069>>>0)>($nb$0>>>0); | |
if ($1070) { | |
$1071 = (($1069) - ($nb$0))|0; | |
HEAP32[((24 + 12|0))>>2] = $1071; | |
$1072 = HEAP32[((24 + 24|0))>>2]|0; | |
$1073 = (($1072) + ($nb$0)|0); | |
HEAP32[((24 + 24|0))>>2] = $1073; | |
$1074 = $1071 | 1; | |
$$sum$i32 = (($nb$0) + 4)|0; | |
$1075 = (($1072) + ($$sum$i32)|0); | |
HEAP32[$1075>>2] = $1074; | |
$1076 = $nb$0 | 3; | |
$1077 = (($1072) + 4|0); | |
HEAP32[$1077>>2] = $1076; | |
$1078 = (($1072) + 8|0); | |
$mem$0 = $1078; | |
STACKTOP = sp;return ($mem$0|0); | |
} | |
} | |
$1079 = (___errno_location()|0); | |
HEAP32[$1079>>2] = 12; | |
$mem$0 = 0; | |
STACKTOP = sp;return ($mem$0|0); | |
} | |
function _free($mem) { | |
$mem = $mem|0; | |
var $$pre = 0, $$pre$phi68Z2D = 0, $$pre$phi70Z2D = 0, $$pre$phiZ2D = 0, $$pre67 = 0, $$pre69 = 0, $$sum = 0, $$sum16$pre = 0, $$sum17 = 0, $$sum18 = 0, $$sum19 = 0, $$sum2 = 0, $$sum20 = 0, $$sum2324 = 0, $$sum25 = 0, $$sum26 = 0, $$sum28 = 0, $$sum29 = 0, $$sum3 = 0, $$sum30 = 0; | |
var $$sum31 = 0, $$sum32 = 0, $$sum33 = 0, $$sum34 = 0, $$sum35 = 0, $$sum36 = 0, $$sum37 = 0, $$sum5 = 0, $$sum67 = 0, $$sum8 = 0, $$sum9 = 0, $0 = 0, $1 = 0, $10 = 0, $100 = 0, $101 = 0, $102 = 0, $103 = 0, $104 = 0, $105 = 0; | |
var $106 = 0, $107 = 0, $108 = 0, $109 = 0, $11 = 0, $110 = 0, $111 = 0, $112 = 0, $113 = 0, $114 = 0, $115 = 0, $116 = 0, $117 = 0, $118 = 0, $119 = 0, $12 = 0, $120 = 0, $121 = 0, $122 = 0, $123 = 0; | |
var $124 = 0, $125 = 0, $126 = 0, $127 = 0, $128 = 0, $129 = 0, $13 = 0, $130 = 0, $131 = 0, $132 = 0, $133 = 0, $134 = 0, $135 = 0, $136 = 0, $137 = 0, $138 = 0, $139 = 0, $14 = 0, $140 = 0, $141 = 0; | |
var $142 = 0, $143 = 0, $144 = 0, $145 = 0, $146 = 0, $147 = 0, $148 = 0, $149 = 0, $15 = 0, $150 = 0, $151 = 0, $152 = 0, $153 = 0, $154 = 0, $155 = 0, $156 = 0, $157 = 0, $158 = 0, $159 = 0, $16 = 0; | |
var $160 = 0, $161 = 0, $162 = 0, $163 = 0, $164 = 0, $165 = 0, $166 = 0, $167 = 0, $168 = 0, $169 = 0, $17 = 0, $170 = 0, $171 = 0, $172 = 0, $173 = 0, $174 = 0, $175 = 0, $176 = 0, $177 = 0, $178 = 0; | |
var $179 = 0, $18 = 0, $180 = 0, $181 = 0, $182 = 0, $183 = 0, $184 = 0, $185 = 0, $186 = 0, $187 = 0, $188 = 0, $189 = 0, $19 = 0, $190 = 0, $191 = 0, $192 = 0, $193 = 0, $194 = 0, $195 = 0, $196 = 0; | |
var $197 = 0, $198 = 0, $199 = 0, $2 = 0, $20 = 0, $200 = 0, $201 = 0, $202 = 0, $203 = 0, $204 = 0, $205 = 0, $206 = 0, $207 = 0, $208 = 0, $209 = 0, $21 = 0, $210 = 0, $211 = 0, $212 = 0, $213 = 0; | |
var $214 = 0, $215 = 0, $216 = 0, $217 = 0, $218 = 0, $219 = 0, $22 = 0, $220 = 0, $221 = 0, $222 = 0, $223 = 0, $224 = 0, $225 = 0, $226 = 0, $227 = 0, $228 = 0, $229 = 0, $23 = 0, $230 = 0, $231 = 0; | |
var $232 = 0, $233 = 0, $234 = 0, $235 = 0, $236 = 0, $237 = 0, $238 = 0, $239 = 0, $24 = 0, $240 = 0, $241 = 0, $242 = 0, $243 = 0, $244 = 0, $245 = 0, $246 = 0, $247 = 0, $248 = 0, $249 = 0, $25 = 0; | |
var $250 = 0, $251 = 0, $252 = 0, $253 = 0, $254 = 0, $255 = 0, $256 = 0, $257 = 0, $258 = 0, $259 = 0, $26 = 0, $260 = 0, $261 = 0, $262 = 0, $263 = 0, $264 = 0, $265 = 0, $266 = 0, $267 = 0, $268 = 0; | |
var $269 = 0, $27 = 0, $270 = 0, $271 = 0, $272 = 0, $273 = 0, $274 = 0, $275 = 0, $276 = 0, $277 = 0, $278 = 0, $279 = 0, $28 = 0, $280 = 0, $281 = 0, $282 = 0, $283 = 0, $284 = 0, $285 = 0, $286 = 0; | |
var $287 = 0, $288 = 0, $289 = 0, $29 = 0, $290 = 0, $291 = 0, $292 = 0, $293 = 0, $294 = 0, $295 = 0, $296 = 0, $297 = 0, $298 = 0, $299 = 0, $3 = 0, $30 = 0, $300 = 0, $301 = 0, $302 = 0, $303 = 0; | |
var $304 = 0, $305 = 0, $306 = 0, $307 = 0, $308 = 0, $309 = 0, $31 = 0, $310 = 0, $311 = 0, $312 = 0, $313 = 0, $314 = 0, $315 = 0, $316 = 0, $317 = 0, $318 = 0, $319 = 0, $32 = 0, $320 = 0, $321 = 0; | |
var $322 = 0, $323 = 0, $324 = 0, $33 = 0, $34 = 0, $35 = 0, $36 = 0, $37 = 0, $38 = 0, $39 = 0, $4 = 0, $40 = 0, $41 = 0, $42 = 0, $43 = 0, $44 = 0, $45 = 0, $46 = 0, $47 = 0, $48 = 0; | |
var $49 = 0, $5 = 0, $50 = 0, $51 = 0, $52 = 0, $53 = 0, $54 = 0, $55 = 0, $56 = 0, $57 = 0, $58 = 0, $59 = 0, $6 = 0, $60 = 0, $61 = 0, $62 = 0, $63 = 0, $64 = 0, $65 = 0, $66 = 0; | |
var $67 = 0, $68 = 0, $69 = 0, $7 = 0, $70 = 0, $71 = 0, $72 = 0, $73 = 0, $74 = 0, $75 = 0, $76 = 0, $77 = 0, $78 = 0, $79 = 0, $8 = 0, $80 = 0, $81 = 0, $82 = 0, $83 = 0, $84 = 0; | |
var $85 = 0, $86 = 0, $87 = 0, $88 = 0, $89 = 0, $9 = 0, $90 = 0, $91 = 0, $92 = 0, $93 = 0, $94 = 0, $95 = 0, $96 = 0, $97 = 0, $98 = 0, $99 = 0, $F16$0 = 0, $I18$0 = 0, $I18$0$c = 0, $K19$057 = 0; | |
var $R$0 = 0, $R$1 = 0, $R7$0 = 0, $R7$1 = 0, $RP$0 = 0, $RP9$0 = 0, $T$0$lcssa = 0, $T$056 = 0, $cond = 0, $cond54 = 0, $p$0 = 0, $psize$0 = 0, $psize$1 = 0, $sp$0$i = 0, $sp$0$in$i = 0, label = 0, sp = 0; | |
sp = STACKTOP; | |
$0 = ($mem|0)==(0|0); | |
if ($0) { | |
STACKTOP = sp;return; | |
} | |
$1 = (($mem) + -8|0); | |
$2 = HEAP32[((24 + 16|0))>>2]|0; | |
$3 = ($1>>>0)<($2>>>0); | |
if ($3) { | |
_abort(); | |
// unreachable; | |
} | |
$4 = (($mem) + -4|0); | |
$5 = HEAP32[$4>>2]|0; | |
$6 = $5 & 3; | |
$7 = ($6|0)==(1); | |
if ($7) { | |
_abort(); | |
// unreachable; | |
} | |
$8 = $5 & -8; | |
$$sum = (($8) + -8)|0; | |
$9 = (($mem) + ($$sum)|0); | |
$10 = $5 & 1; | |
$11 = ($10|0)==(0); | |
do { | |
if ($11) { | |
$12 = HEAP32[$1>>2]|0; | |
$13 = ($6|0)==(0); | |
if ($13) { | |
STACKTOP = sp;return; | |
} | |
$$sum2 = (-8 - ($12))|0; | |
$14 = (($mem) + ($$sum2)|0); | |
$15 = (($12) + ($8))|0; | |
$16 = ($14>>>0)<($2>>>0); | |
if ($16) { | |
_abort(); | |
// unreachable; | |
} | |
$17 = HEAP32[((24 + 20|0))>>2]|0; | |
$18 = ($14|0)==($17|0); | |
if ($18) { | |
$$sum3 = (($8) + -4)|0; | |
$104 = (($mem) + ($$sum3)|0); | |
$105 = HEAP32[$104>>2]|0; | |
$106 = $105 & 3; | |
$107 = ($106|0)==(3); | |
if (!($107)) { | |
$p$0 = $14;$psize$0 = $15; | |
break; | |
} | |
HEAP32[((24 + 8|0))>>2] = $15; | |
$108 = HEAP32[$104>>2]|0; | |
$109 = $108 & -2; | |
HEAP32[$104>>2] = $109; | |
$110 = $15 | 1; | |
$$sum26 = (($$sum2) + 4)|0; | |
$111 = (($mem) + ($$sum26)|0); | |
HEAP32[$111>>2] = $110; | |
HEAP32[$9>>2] = $15; | |
STACKTOP = sp;return; | |
} | |
$19 = $12 >>> 3; | |
$20 = ($12>>>0)<(256); | |
if ($20) { | |
$$sum36 = (($$sum2) + 8)|0; | |
$21 = (($mem) + ($$sum36)|0); | |
$22 = HEAP32[$21>>2]|0; | |
$$sum37 = (($$sum2) + 12)|0; | |
$23 = (($mem) + ($$sum37)|0); | |
$24 = HEAP32[$23>>2]|0; | |
$25 = $19 << 1; | |
$26 = ((24 + ($25<<2)|0) + 40|0); | |
$27 = ($22|0)==($26|0); | |
if (!($27)) { | |
$28 = ($22>>>0)<($2>>>0); | |
if ($28) { | |
_abort(); | |
// unreachable; | |
} | |
$29 = (($22) + 12|0); | |
$30 = HEAP32[$29>>2]|0; | |
$31 = ($30|0)==($14|0); | |
if (!($31)) { | |
_abort(); | |
// unreachable; | |
} | |
} | |
$32 = ($24|0)==($22|0); | |
if ($32) { | |
$33 = 1 << $19; | |
$34 = $33 ^ -1; | |
$35 = HEAP32[24>>2]|0; | |
$36 = $35 & $34; | |
HEAP32[24>>2] = $36; | |
$p$0 = $14;$psize$0 = $15; | |
break; | |
} | |
$37 = ($24|0)==($26|0); | |
if ($37) { | |
$$pre69 = (($24) + 8|0); | |
$$pre$phi70Z2D = $$pre69; | |
} else { | |
$38 = ($24>>>0)<($2>>>0); | |
if ($38) { | |
_abort(); | |
// unreachable; | |
} | |
$39 = (($24) + 8|0); | |
$40 = HEAP32[$39>>2]|0; | |
$41 = ($40|0)==($14|0); | |
if ($41) { | |
$$pre$phi70Z2D = $39; | |
} else { | |
_abort(); | |
// unreachable; | |
} | |
} | |
$42 = (($22) + 12|0); | |
HEAP32[$42>>2] = $24; | |
HEAP32[$$pre$phi70Z2D>>2] = $22; | |
$p$0 = $14;$psize$0 = $15; | |
break; | |
} | |
$$sum28 = (($$sum2) + 24)|0; | |
$43 = (($mem) + ($$sum28)|0); | |
$44 = HEAP32[$43>>2]|0; | |
$$sum29 = (($$sum2) + 12)|0; | |
$45 = (($mem) + ($$sum29)|0); | |
$46 = HEAP32[$45>>2]|0; | |
$47 = ($46|0)==($14|0); | |
do { | |
if ($47) { | |
$$sum31 = (($$sum2) + 20)|0; | |
$57 = (($mem) + ($$sum31)|0); | |
$58 = HEAP32[$57>>2]|0; | |
$59 = ($58|0)==(0|0); | |
if ($59) { | |
$$sum30 = (($$sum2) + 16)|0; | |
$60 = (($mem) + ($$sum30)|0); | |
$61 = HEAP32[$60>>2]|0; | |
$62 = ($61|0)==(0|0); | |
if ($62) { | |
$R$1 = 0; | |
break; | |
} else { | |
$R$0 = $61;$RP$0 = $60; | |
} | |
} else { | |
$R$0 = $58;$RP$0 = $57; | |
} | |
while(1) { | |
$63 = (($R$0) + 20|0); | |
$64 = HEAP32[$63>>2]|0; | |
$65 = ($64|0)==(0|0); | |
if (!($65)) { | |
$R$0 = $64;$RP$0 = $63; | |
continue; | |
} | |
$66 = (($R$0) + 16|0); | |
$67 = HEAP32[$66>>2]|0; | |
$68 = ($67|0)==(0|0); | |
if ($68) { | |
break; | |
} else { | |
$R$0 = $67;$RP$0 = $66; | |
} | |
} | |
$69 = ($RP$0>>>0)<($2>>>0); | |
if ($69) { | |
_abort(); | |
// unreachable; | |
} else { | |
HEAP32[$RP$0>>2] = 0; | |
$R$1 = $R$0; | |
break; | |
} | |
} else { | |
$$sum35 = (($$sum2) + 8)|0; | |
$48 = (($mem) + ($$sum35)|0); | |
$49 = HEAP32[$48>>2]|0; | |
$50 = ($49>>>0)<($2>>>0); | |
if ($50) { | |
_abort(); | |
// unreachable; | |
} | |
$51 = (($49) + 12|0); | |
$52 = HEAP32[$51>>2]|0; | |
$53 = ($52|0)==($14|0); | |
if (!($53)) { | |
_abort(); | |
// unreachable; | |
} | |
$54 = (($46) + 8|0); | |
$55 = HEAP32[$54>>2]|0; | |
$56 = ($55|0)==($14|0); | |
if ($56) { | |
HEAP32[$51>>2] = $46; | |
HEAP32[$54>>2] = $49; | |
$R$1 = $46; | |
break; | |
} else { | |
_abort(); | |
// unreachable; | |
} | |
} | |
} while(0); | |
$70 = ($44|0)==(0|0); | |
if ($70) { | |
$p$0 = $14;$psize$0 = $15; | |
} else { | |
$$sum32 = (($$sum2) + 28)|0; | |
$71 = (($mem) + ($$sum32)|0); | |
$72 = HEAP32[$71>>2]|0; | |
$73 = ((24 + ($72<<2)|0) + 304|0); | |
$74 = HEAP32[$73>>2]|0; | |
$75 = ($14|0)==($74|0); | |
if ($75) { | |
HEAP32[$73>>2] = $R$1; | |
$cond = ($R$1|0)==(0|0); | |
if ($cond) { | |
$76 = 1 << $72; | |
$77 = $76 ^ -1; | |
$78 = HEAP32[((24 + 4|0))>>2]|0; | |
$79 = $78 & $77; | |
HEAP32[((24 + 4|0))>>2] = $79; | |
$p$0 = $14;$psize$0 = $15; | |
break; | |
} | |
} else { | |
$80 = HEAP32[((24 + 16|0))>>2]|0; | |
$81 = ($44>>>0)<($80>>>0); | |
if ($81) { | |
_abort(); | |
// unreachable; | |
} | |
$82 = (($44) + 16|0); | |
$83 = HEAP32[$82>>2]|0; | |
$84 = ($83|0)==($14|0); | |
if ($84) { | |
HEAP32[$82>>2] = $R$1; | |
} else { | |
$85 = (($44) + 20|0); | |
HEAP32[$85>>2] = $R$1; | |
} | |
$86 = ($R$1|0)==(0|0); | |
if ($86) { | |
$p$0 = $14;$psize$0 = $15; | |
break; | |
} | |
} | |
$87 = HEAP32[((24 + 16|0))>>2]|0; | |
$88 = ($R$1>>>0)<($87>>>0); | |
if ($88) { | |
_abort(); | |
// unreachable; | |
} | |
$89 = (($R$1) + 24|0); | |
HEAP32[$89>>2] = $44; | |
$$sum33 = (($$sum2) + 16)|0; | |
$90 = (($mem) + ($$sum33)|0); | |
$91 = HEAP32[$90>>2]|0; | |
$92 = ($91|0)==(0|0); | |
do { | |
if (!($92)) { | |
$93 = HEAP32[((24 + 16|0))>>2]|0; | |
$94 = ($91>>>0)<($93>>>0); | |
if ($94) { | |
_abort(); | |
// unreachable; | |
} else { | |
$95 = (($R$1) + 16|0); | |
HEAP32[$95>>2] = $91; | |
$96 = (($91) + 24|0); | |
HEAP32[$96>>2] = $R$1; | |
break; | |
} | |
} | |
} while(0); | |
$$sum34 = (($$sum2) + 20)|0; | |
$97 = (($mem) + ($$sum34)|0); | |
$98 = HEAP32[$97>>2]|0; | |
$99 = ($98|0)==(0|0); | |
if ($99) { | |
$p$0 = $14;$psize$0 = $15; | |
} else { | |
$100 = HEAP32[((24 + 16|0))>>2]|0; | |
$101 = ($98>>>0)<($100>>>0); | |
if ($101) { | |
_abort(); | |
// unreachable; | |
} else { | |
$102 = (($R$1) + 20|0); | |
HEAP32[$102>>2] = $98; | |
$103 = (($98) + 24|0); | |
HEAP32[$103>>2] = $R$1; | |
$p$0 = $14;$psize$0 = $15; | |
break; | |
} | |
} | |
} | |
} else { | |
$p$0 = $1;$psize$0 = $8; | |
} | |
} while(0); | |
$112 = ($p$0>>>0)<($9>>>0); | |
if (!($112)) { | |
_abort(); | |
// unreachable; | |
} | |
$$sum25 = (($8) + -4)|0; | |
$113 = (($mem) + ($$sum25)|0); | |
$114 = HEAP32[$113>>2]|0; | |
$115 = $114 & 1; | |
$116 = ($115|0)==(0); | |
if ($116) { | |
_abort(); | |
// unreachable; | |
} | |
$117 = $114 & 2; | |
$118 = ($117|0)==(0); | |
if ($118) { | |
$119 = HEAP32[((24 + 24|0))>>2]|0; | |
$120 = ($9|0)==($119|0); | |
if ($120) { | |
$121 = HEAP32[((24 + 12|0))>>2]|0; | |
$122 = (($121) + ($psize$0))|0; | |
HEAP32[((24 + 12|0))>>2] = $122; | |
HEAP32[((24 + 24|0))>>2] = $p$0; | |
$123 = $122 | 1; | |
$124 = (($p$0) + 4|0); | |
HEAP32[$124>>2] = $123; | |
$125 = HEAP32[((24 + 20|0))>>2]|0; | |
$126 = ($p$0|0)==($125|0); | |
if (!($126)) { | |
STACKTOP = sp;return; | |
} | |
HEAP32[((24 + 20|0))>>2] = 0; | |
HEAP32[((24 + 8|0))>>2] = 0; | |
STACKTOP = sp;return; | |
} | |
$127 = HEAP32[((24 + 20|0))>>2]|0; | |
$128 = ($9|0)==($127|0); | |
if ($128) { | |
$129 = HEAP32[((24 + 8|0))>>2]|0; | |
$130 = (($129) + ($psize$0))|0; | |
HEAP32[((24 + 8|0))>>2] = $130; | |
HEAP32[((24 + 20|0))>>2] = $p$0; | |
$131 = $130 | 1; | |
$132 = (($p$0) + 4|0); | |
HEAP32[$132>>2] = $131; | |
$133 = (($p$0) + ($130)|0); | |
HEAP32[$133>>2] = $130; | |
STACKTOP = sp;return; | |
} | |
$134 = $114 & -8; | |
$135 = (($134) + ($psize$0))|0; | |
$136 = $114 >>> 3; | |
$137 = ($114>>>0)<(256); | |
do { | |
if ($137) { | |
$138 = (($mem) + ($8)|0); | |
$139 = HEAP32[$138>>2]|0; | |
$$sum2324 = $8 | 4; | |
$140 = (($mem) + ($$sum2324)|0); | |
$141 = HEAP32[$140>>2]|0; | |
$142 = $136 << 1; | |
$143 = ((24 + ($142<<2)|0) + 40|0); | |
$144 = ($139|0)==($143|0); | |
if (!($144)) { | |
$145 = HEAP32[((24 + 16|0))>>2]|0; | |
$146 = ($139>>>0)<($145>>>0); | |
if ($146) { | |
_abort(); | |
// unreachable; | |
} | |
$147 = (($139) + 12|0); | |
$148 = HEAP32[$147>>2]|0; | |
$149 = ($148|0)==($9|0); | |
if (!($149)) { | |
_abort(); | |
// unreachable; | |
} | |
} | |
$150 = ($141|0)==($139|0); | |
if ($150) { | |
$151 = 1 << $136; | |
$152 = $151 ^ -1; | |
$153 = HEAP32[24>>2]|0; | |
$154 = $153 & $152; | |
HEAP32[24>>2] = $154; | |
break; | |
} | |
$155 = ($141|0)==($143|0); | |
if ($155) { | |
$$pre67 = (($141) + 8|0); | |
$$pre$phi68Z2D = $$pre67; | |
} else { | |
$156 = HEAP32[((24 + 16|0))>>2]|0; | |
$157 = ($141>>>0)<($156>>>0); | |
if ($157) { | |
_abort(); | |
// unreachable; | |
} | |
$158 = (($141) + 8|0); | |
$159 = HEAP32[$158>>2]|0; | |
$160 = ($159|0)==($9|0); | |
if ($160) { | |
$$pre$phi68Z2D = $158; | |
} else { | |
_abort(); | |
// unreachable; | |
} | |
} | |
$161 = (($139) + 12|0); | |
HEAP32[$161>>2] = $141; | |
HEAP32[$$pre$phi68Z2D>>2] = $139; | |
} else { | |
$$sum5 = (($8) + 16)|0; | |
$162 = (($mem) + ($$sum5)|0); | |
$163 = HEAP32[$162>>2]|0; | |
$$sum67 = $8 | 4; | |
$164 = (($mem) + ($$sum67)|0); | |
$165 = HEAP32[$164>>2]|0; | |
$166 = ($165|0)==($9|0); | |
do { | |
if ($166) { | |
$$sum9 = (($8) + 12)|0; | |
$177 = (($mem) + ($$sum9)|0); | |
$178 = HEAP32[$177>>2]|0; | |
$179 = ($178|0)==(0|0); | |
if ($179) { | |
$$sum8 = (($8) + 8)|0; | |
$180 = (($mem) + ($$sum8)|0); | |
$181 = HEAP32[$180>>2]|0; | |
$182 = ($181|0)==(0|0); | |
if ($182) { | |
$R7$1 = 0; | |
break; | |
} else { | |
$R7$0 = $181;$RP9$0 = $180; | |
} | |
} else { | |
$R7$0 = $178;$RP9$0 = $177; | |
} | |
while(1) { | |
$183 = (($R7$0) + 20|0); | |
$184 = HEAP32[$183>>2]|0; | |
$185 = ($184|0)==(0|0); | |
if (!($185)) { | |
$R7$0 = $184;$RP9$0 = $183; | |
continue; | |
} | |
$186 = (($R7$0) + 16|0); | |
$187 = HEAP32[$186>>2]|0; | |
$188 = ($187|0)==(0|0); | |
if ($188) { | |
break; | |
} else { | |
$R7$0 = $187;$RP9$0 = $186; | |
} | |
} | |
$189 = HEAP32[((24 + 16|0))>>2]|0; | |
$190 = ($RP9$0>>>0)<($189>>>0); | |
if ($190) { | |
_abort(); | |
// unreachable; | |
} else { | |
HEAP32[$RP9$0>>2] = 0; | |
$R7$1 = $R7$0; | |
break; | |
} | |
} else { | |
$167 = (($mem) + ($8)|0); | |
$168 = HEAP32[$167>>2]|0; | |
$169 = HEAP32[((24 + 16|0))>>2]|0; | |
$170 = ($168>>>0)<($169>>>0); | |
if ($170) { | |
_abort(); | |
// unreachable; | |
} | |
$171 = (($168) + 12|0); | |
$172 = HEAP32[$171>>2]|0; | |
$173 = ($172|0)==($9|0); | |
if (!($173)) { | |
_abort(); | |
// unreachable; | |
} | |
$174 = (($165) + 8|0); | |
$175 = HEAP32[$174>>2]|0; | |
$176 = ($175|0)==($9|0); | |
if ($176) { | |
HEAP32[$171>>2] = $165; | |
HEAP32[$174>>2] = $168; | |
$R7$1 = $165; | |
break; | |
} else { | |
_abort(); | |
// unreachable; | |
} | |
} | |
} while(0); | |
$191 = ($163|0)==(0|0); | |
if (!($191)) { | |
$$sum18 = (($8) + 20)|0; | |
$192 = (($mem) + ($$sum18)|0); | |
$193 = HEAP32[$192>>2]|0; | |
$194 = ((24 + ($193<<2)|0) + 304|0); | |
$195 = HEAP32[$194>>2]|0; | |
$196 = ($9|0)==($195|0); | |
if ($196) { | |
HEAP32[$194>>2] = $R7$1; | |
$cond54 = ($R7$1|0)==(0|0); | |
if ($cond54) { | |
$197 = 1 << $193; | |
$198 = $197 ^ -1; | |
$199 = HEAP32[((24 + 4|0))>>2]|0; | |
$200 = $199 & $198; | |
HEAP32[((24 + 4|0))>>2] = $200; | |
break; | |
} | |
} else { | |
$201 = HEAP32[((24 + 16|0))>>2]|0; | |
$202 = ($163>>>0)<($201>>>0); | |
if ($202) { | |
_abort(); | |
// unreachable; | |
} | |
$203 = (($163) + 16|0); | |
$204 = HEAP32[$203>>2]|0; | |
$205 = ($204|0)==($9|0); | |
if ($205) { | |
HEAP32[$203>>2] = $R7$1; | |
} else { | |
$206 = (($163) + 20|0); | |
HEAP32[$206>>2] = $R7$1; | |
} | |
$207 = ($R7$1|0)==(0|0); | |
if ($207) { | |
break; | |
} | |
} | |
$208 = HEAP32[((24 + 16|0))>>2]|0; | |
$209 = ($R7$1>>>0)<($208>>>0); | |
if ($209) { | |
_abort(); | |
// unreachable; | |
} | |
$210 = (($R7$1) + 24|0); | |
HEAP32[$210>>2] = $163; | |
$$sum19 = (($8) + 8)|0; | |
$211 = (($mem) + ($$sum19)|0); | |
$212 = HEAP32[$211>>2]|0; | |
$213 = ($212|0)==(0|0); | |
do { | |
if (!($213)) { | |
$214 = HEAP32[((24 + 16|0))>>2]|0; | |
$215 = ($212>>>0)<($214>>>0); | |
if ($215) { | |
_abort(); | |
// unreachable; | |
} else { | |
$216 = (($R7$1) + 16|0); | |
HEAP32[$216>>2] = $212; | |
$217 = (($212) + 24|0); | |
HEAP32[$217>>2] = $R7$1; | |
break; | |
} | |
} | |
} while(0); | |
$$sum20 = (($8) + 12)|0; | |
$218 = (($mem) + ($$sum20)|0); | |
$219 = HEAP32[$218>>2]|0; | |
$220 = ($219|0)==(0|0); | |
if (!($220)) { | |
$221 = HEAP32[((24 + 16|0))>>2]|0; | |
$222 = ($219>>>0)<($221>>>0); | |
if ($222) { | |
_abort(); | |
// unreachable; | |
} else { | |
$223 = (($R7$1) + 20|0); | |
HEAP32[$223>>2] = $219; | |
$224 = (($219) + 24|0); | |
HEAP32[$224>>2] = $R7$1; | |
break; | |
} | |
} | |
} | |
} | |
} while(0); | |
$225 = $135 | 1; | |
$226 = (($p$0) + 4|0); | |
HEAP32[$226>>2] = $225; | |
$227 = (($p$0) + ($135)|0); | |
HEAP32[$227>>2] = $135; | |
$228 = HEAP32[((24 + 20|0))>>2]|0; | |
$229 = ($p$0|0)==($228|0); | |
if ($229) { | |
HEAP32[((24 + 8|0))>>2] = $135; | |
STACKTOP = sp;return; | |
} else { | |
$psize$1 = $135; | |
} | |
} else { | |
$230 = $114 & -2; | |
HEAP32[$113>>2] = $230; | |
$231 = $psize$0 | 1; | |
$232 = (($p$0) + 4|0); | |
HEAP32[$232>>2] = $231; | |
$233 = (($p$0) + ($psize$0)|0); | |
HEAP32[$233>>2] = $psize$0; | |
$psize$1 = $psize$0; | |
} | |
$234 = $psize$1 >>> 3; | |
$235 = ($psize$1>>>0)<(256); | |
if ($235) { | |
$236 = $234 << 1; | |
$237 = ((24 + ($236<<2)|0) + 40|0); | |
$238 = HEAP32[24>>2]|0; | |
$239 = 1 << $234; | |
$240 = $238 & $239; | |
$241 = ($240|0)==(0); | |
if ($241) { | |
$242 = $238 | $239; | |
HEAP32[24>>2] = $242; | |
$$sum16$pre = (($236) + 2)|0; | |
$$pre = ((24 + ($$sum16$pre<<2)|0) + 40|0); | |
$$pre$phiZ2D = $$pre;$F16$0 = $237; | |
} else { | |
$$sum17 = (($236) + 2)|0; | |
$243 = ((24 + ($$sum17<<2)|0) + 40|0); | |
$244 = HEAP32[$243>>2]|0; | |
$245 = HEAP32[((24 + 16|0))>>2]|0; | |
$246 = ($244>>>0)<($245>>>0); | |
if ($246) { | |
_abort(); | |
// unreachable; | |
} else { | |
$$pre$phiZ2D = $243;$F16$0 = $244; | |
} | |
} | |
HEAP32[$$pre$phiZ2D>>2] = $p$0; | |
$247 = (($F16$0) + 12|0); | |
HEAP32[$247>>2] = $p$0; | |
$248 = (($p$0) + 8|0); | |
HEAP32[$248>>2] = $F16$0; | |
$249 = (($p$0) + 12|0); | |
HEAP32[$249>>2] = $237; | |
STACKTOP = sp;return; | |
} | |
$250 = $psize$1 >>> 8; | |
$251 = ($250|0)==(0); | |
if ($251) { | |
$I18$0 = 0; | |
} else { | |
$252 = ($psize$1>>>0)>(16777215); | |
if ($252) { | |
$I18$0 = 31; | |
} else { | |
$253 = (($250) + 1048320)|0; | |
$254 = $253 >>> 16; | |
$255 = $254 & 8; | |
$256 = $250 << $255; | |
$257 = (($256) + 520192)|0; | |
$258 = $257 >>> 16; | |
$259 = $258 & 4; | |
$260 = $259 | $255; | |
$261 = $256 << $259; | |
$262 = (($261) + 245760)|0; | |
$263 = $262 >>> 16; | |
$264 = $263 & 2; | |
$265 = $260 | $264; | |
$266 = (14 - ($265))|0; | |
$267 = $261 << $264; | |
$268 = $267 >>> 15; | |
$269 = (($266) + ($268))|0; | |
$270 = $269 << 1; | |
$271 = (($269) + 7)|0; | |
$272 = $psize$1 >>> $271; | |
$273 = $272 & 1; | |
$274 = $273 | $270; | |
$I18$0 = $274; | |
} | |
} | |
$275 = ((24 + ($I18$0<<2)|0) + 304|0); | |
$276 = (($p$0) + 28|0); | |
$I18$0$c = $I18$0; | |
HEAP32[$276>>2] = $I18$0$c; | |
$277 = (($p$0) + 20|0); | |
HEAP32[$277>>2] = 0; | |
$278 = (($p$0) + 16|0); | |
HEAP32[$278>>2] = 0; | |
$279 = HEAP32[((24 + 4|0))>>2]|0; | |
$280 = 1 << $I18$0; | |
$281 = $279 & $280; | |
$282 = ($281|0)==(0); | |
L199: do { | |
if ($282) { | |
$283 = $279 | $280; | |
HEAP32[((24 + 4|0))>>2] = $283; | |
HEAP32[$275>>2] = $p$0; | |
$284 = (($p$0) + 24|0); | |
HEAP32[$284>>2] = $275; | |
$285 = (($p$0) + 12|0); | |
HEAP32[$285>>2] = $p$0; | |
$286 = (($p$0) + 8|0); | |
HEAP32[$286>>2] = $p$0; | |
} else { | |
$287 = HEAP32[$275>>2]|0; | |
$288 = ($I18$0|0)==(31); | |
if ($288) { | |
$296 = 0; | |
} else { | |
$289 = $I18$0 >>> 1; | |
$290 = (25 - ($289))|0; | |
$296 = $290; | |
} | |
$291 = (($287) + 4|0); | |
$292 = HEAP32[$291>>2]|0; | |
$293 = $292 & -8; | |
$294 = ($293|0)==($psize$1|0); | |
L205: do { | |
if ($294) { | |
$T$0$lcssa = $287; | |
} else { | |
$295 = $psize$1 << $296; | |
$K19$057 = $295;$T$056 = $287; | |
while(1) { | |
$303 = $K19$057 >>> 31; | |
$304 = ((($T$056) + ($303<<2)|0) + 16|0); | |
$299 = HEAP32[$304>>2]|0; | |
$305 = ($299|0)==(0|0); | |
if ($305) { | |
break; | |
} | |
$297 = $K19$057 << 1; | |
$298 = (($299) + 4|0); | |
$300 = HEAP32[$298>>2]|0; | |
$301 = $300 & -8; | |
$302 = ($301|0)==($psize$1|0); | |
if ($302) { | |
$T$0$lcssa = $299; | |
break L205; | |
} else { | |
$K19$057 = $297;$T$056 = $299; | |
} | |
} | |
$306 = HEAP32[((24 + 16|0))>>2]|0; | |
$307 = ($304>>>0)<($306>>>0); | |
if ($307) { | |
_abort(); | |
// unreachable; | |
} else { | |
HEAP32[$304>>2] = $p$0; | |
$308 = (($p$0) + 24|0); | |
HEAP32[$308>>2] = $T$056; | |
$309 = (($p$0) + 12|0); | |
HEAP32[$309>>2] = $p$0; | |
$310 = (($p$0) + 8|0); | |
HEAP32[$310>>2] = $p$0; | |
break L199; | |
} | |
} | |
} while(0); | |
$311 = (($T$0$lcssa) + 8|0); | |
$312 = HEAP32[$311>>2]|0; | |
$313 = HEAP32[((24 + 16|0))>>2]|0; | |
$314 = ($T$0$lcssa>>>0)<($313>>>0); | |
if ($314) { | |
_abort(); | |
// unreachable; | |
} | |
$315 = ($312>>>0)<($313>>>0); | |
if ($315) { | |
_abort(); | |
// unreachable; | |
} else { | |
$316 = (($312) + 12|0); | |
HEAP32[$316>>2] = $p$0; | |
HEAP32[$311>>2] = $p$0; | |
$317 = (($p$0) + 8|0); | |
HEAP32[$317>>2] = $312; | |
$318 = (($p$0) + 12|0); | |
HEAP32[$318>>2] = $T$0$lcssa; | |
$319 = (($p$0) + 24|0); | |
HEAP32[$319>>2] = 0; | |
break; | |
} | |
} | |
} while(0); | |
$320 = HEAP32[((24 + 32|0))>>2]|0; | |
$321 = (($320) + -1)|0; | |
HEAP32[((24 + 32|0))>>2] = $321; | |
$322 = ($321|0)==(0); | |
if ($322) { | |
$sp$0$in$i = ((24 + 456|0)); | |
} else { | |
STACKTOP = sp;return; | |
} | |
while(1) { | |
$sp$0$i = HEAP32[$sp$0$in$i>>2]|0; | |
$323 = ($sp$0$i|0)==(0|0); | |
$324 = (($sp$0$i) + 8|0); | |
if ($323) { | |
break; | |
} else { | |
$sp$0$in$i = $324; | |
} | |
} | |
HEAP32[((24 + 32|0))>>2] = -1; | |
STACKTOP = sp;return; | |
} | |
function runPostSets() { | |
} | |
function _memset(ptr, value, num) { | |
ptr = ptr|0; value = value|0; num = num|0; | |
var stop = 0, value4 = 0, stop4 = 0, unaligned = 0; | |
stop = (ptr + num)|0; | |
if ((num|0) >= 20) { | |
// This is unaligned, but quite large, so work hard to get to aligned settings | |
value = value & 0xff; | |
unaligned = ptr & 3; | |
value4 = value | (value << 8) | (value << 16) | (value << 24); | |
stop4 = stop & ~3; | |
if (unaligned) { | |
unaligned = (ptr + 4 - unaligned)|0; | |
while ((ptr|0) < (unaligned|0)) { // no need to check for stop, since we have large num | |
HEAP8[((ptr)>>0)]=value; | |
ptr = (ptr+1)|0; | |
} | |
} | |
while ((ptr|0) < (stop4|0)) { | |
HEAP32[((ptr)>>2)]=value4; | |
ptr = (ptr+4)|0; | |
} | |
} | |
while ((ptr|0) < (stop|0)) { | |
HEAP8[((ptr)>>0)]=value; | |
ptr = (ptr+1)|0; | |
} | |
return (ptr-num)|0; | |
} | |
function _strlen(ptr) { | |
ptr = ptr|0; | |
var curr = 0; | |
curr = ptr; | |
while (((HEAP8[((curr)>>0)])|0)) { | |
curr = (curr + 1)|0; | |
} | |
return (curr - ptr)|0; | |
} | |
function _memcpy(dest, src, num) { | |
dest = dest|0; src = src|0; num = num|0; | |
var ret = 0; | |
if ((num|0) >= 4096) return _emscripten_memcpy_big(dest|0, src|0, num|0)|0; | |
ret = dest|0; | |
if ((dest&3) == (src&3)) { | |
while (dest & 3) { | |
if ((num|0) == 0) return ret|0; | |
HEAP8[((dest)>>0)]=((HEAP8[((src)>>0)])|0); | |
dest = (dest+1)|0; | |
src = (src+1)|0; | |
num = (num-1)|0; | |
} | |
while ((num|0) >= 4) { | |
HEAP32[((dest)>>2)]=((HEAP32[((src)>>2)])|0); | |
dest = (dest+4)|0; | |
src = (src+4)|0; | |
num = (num-4)|0; | |
} | |
} | |
while ((num|0) > 0) { | |
HEAP8[((dest)>>0)]=((HEAP8[((src)>>0)])|0); | |
dest = (dest+1)|0; | |
src = (src+1)|0; | |
num = (num-1)|0; | |
} | |
return ret|0; | |
} | |
// EMSCRIPTEN_END_FUNCS | |
// EMSCRIPTEN_END_FUNCS | |
return { _strlen: _strlen, _free: _free, _main: _main, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, getTempRet0: getTempRet0 }; | |
}) | |
// EMSCRIPTEN_END_ASM | |
(Module.asmGlobalArg, Module.asmLibraryArg, buffer); | |
var real__strlen = asm["_strlen"]; asm["_strlen"] = function() { | |
assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); | |
assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); | |
return real__strlen.apply(null, arguments); | |
}; | |
var real__main = asm["_main"]; asm["_main"] = function() { | |
assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); | |
assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); | |
return real__main.apply(null, arguments); | |
}; | |
var real_runPostSets = asm["runPostSets"]; asm["runPostSets"] = function() { | |
assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); | |
assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); | |
return real_runPostSets.apply(null, arguments); | |
}; | |
var _strlen = Module["_strlen"] = asm["_strlen"]; | |
var _free = Module["_free"] = asm["_free"]; | |
var _main = Module["_main"] = asm["_main"]; | |
var _memset = Module["_memset"] = asm["_memset"]; | |
var _malloc = Module["_malloc"] = asm["_malloc"]; | |
var _memcpy = Module["_memcpy"] = asm["_memcpy"]; | |
var runPostSets = Module["runPostSets"] = asm["runPostSets"]; | |
Runtime.stackAlloc = asm['stackAlloc']; | |
Runtime.stackSave = asm['stackSave']; | |
Runtime.stackRestore = asm['stackRestore']; | |
Runtime.setTempRet0 = asm['setTempRet0']; | |
Runtime.getTempRet0 = asm['getTempRet0']; | |
// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included | |
var i64Math = null; | |
// === Auto-generated postamble setup entry stuff === | |
if (memoryInitializer) { | |
if (typeof Module['locateFile'] === 'function') { | |
memoryInitializer = Module['locateFile'](memoryInitializer); | |
} else if (Module['memoryInitializerPrefixURL']) { | |
memoryInitializer = Module['memoryInitializerPrefixURL'] + memoryInitializer; | |
} | |
if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) { | |
var data = Module['readBinary'](memoryInitializer); | |
HEAPU8.set(data, STATIC_BASE); | |
} else { | |
addRunDependency('memory initializer'); | |
Browser.asyncLoad(memoryInitializer, function(data) { | |
for (var i = 0; i < data.length; i++) { | |
assert(HEAPU8[STATIC_BASE + i] === 0, "area for memory initializer should not have been touched before it's loaded"); | |
} | |
HEAPU8.set(data, STATIC_BASE); | |
removeRunDependency('memory initializer'); | |
}, function(data) { | |
throw 'could not load memory initializer ' + memoryInitializer; | |
}); | |
} | |
} | |
function ExitStatus(status) { | |
this.name = "ExitStatus"; | |
this.message = "Program terminated with exit(" + status + ")"; | |
this.status = status; | |
}; | |
ExitStatus.prototype = new Error(); | |
ExitStatus.prototype.constructor = ExitStatus; | |
var initialStackTop; | |
var preloadStartTime = null; | |
var calledMain = false; | |
dependenciesFulfilled = function runCaller() { | |
// If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false) | |
if (!Module['calledRun'] && shouldRunNow) run(); | |
if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled | |
} | |
Module['callMain'] = Module.callMain = function callMain(args) { | |
assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)'); | |
assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called'); | |
args = args || []; | |
ensureInitRuntime(); | |
var argc = args.length+1; | |
function pad() { | |
for (var i = 0; i < 4-1; i++) { | |
argv.push(0); | |
} | |
} | |
var argv = [allocate(intArrayFromString(Module['thisProgram']), 'i8', ALLOC_NORMAL) ]; | |
pad(); | |
for (var i = 0; i < argc-1; i = i + 1) { | |
argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL)); | |
pad(); | |
} | |
argv.push(0); | |
argv = allocate(argv, 'i32', ALLOC_NORMAL); | |
initialStackTop = STACKTOP; | |
try { | |
var ret = Module['_main'](argc, argv, 0); | |
// if we're not running an evented main loop, it's time to exit | |
exit(ret); | |
} | |
catch(e) { | |
if (e instanceof ExitStatus) { | |
// exit() throws this once it's done to make sure execution | |
// has been stopped completely | |
return; | |
} else if (e == 'SimulateInfiniteLoop') { | |
// running an evented main loop, don't immediately exit | |
Module['noExitRuntime'] = true; | |
return; | |
} else { | |
if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]); | |
throw e; | |
} | |
} finally { | |
calledMain = true; | |
} | |
} | |
function run(args) { | |
args = args || Module['arguments']; | |
if (preloadStartTime === null) preloadStartTime = Date.now(); | |
if (runDependencies > 0) { | |
Module.printErr('run() called, but dependencies remain, so not running'); | |
return; | |
} | |
preRun(); | |
if (runDependencies > 0) return; // a preRun added a dependency, run will be called later | |
if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame | |
function doRun() { | |
if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening | |
Module['calledRun'] = true; | |
if (ABORT) return; | |
ensureInitRuntime(); | |
preMain(); | |
if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) { | |
Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms'); | |
} | |
if (Module['_main'] && shouldRunNow) { | |
Module['callMain'](args); | |
} | |
postRun(); | |
} | |
if (Module['setStatus']) { | |
Module['setStatus']('Running...'); | |
setTimeout(function() { | |
setTimeout(function() { | |
Module['setStatus'](''); | |
}, 1); | |
doRun(); | |
}, 1); | |
} else { | |
doRun(); | |
} | |
} | |
Module['run'] = Module.run = run; | |
function exit(status) { | |
if (Module['noExitRuntime']) { | |
Module.printErr('exit(' + status + ') called, but noExitRuntime, so not exiting'); | |
return; | |
} | |
ABORT = true; | |
EXITSTATUS = status; | |
STACKTOP = initialStackTop; | |
// exit the runtime | |
exitRuntime(); | |
if (ENVIRONMENT_IS_NODE) { | |
// Work around a node.js bug where stdout buffer is not flushed at process exit: | |
// Instead of process.exit() directly, wait for stdout flush event. | |
// See https://github.com/joyent/node/issues/1669 and https://github.com/kripken/emscripten/issues/2582 | |
// Workaround is based on https://github.com/RReverser/acorn/commit/50ab143cecc9ed71a2d66f78b4aec3bb2e9844f6 | |
process['stdout']['once']('drain', function () { | |
process['exit'](status); | |
}); | |
console.log(' '); // Make sure to print something to force the drain event to occur, in case the stdout buffer was empty. | |
// Work around another node bug where sometimes 'drain' is never fired - make another effort | |
// to emit the exit status, after a significant delay (if node hasn't fired drain by then, give up) | |
setTimeout(function() { | |
process['exit'](status); | |
}, 500); | |
} else | |
if (ENVIRONMENT_IS_SHELL && typeof quit === 'function') { | |
quit(status); | |
} | |
// if we reach here, we must throw an exception to halt the current execution | |
throw new ExitStatus(status); | |
} | |
Module['exit'] = Module.exit = exit; | |
function abort(text) { | |
if (text) { | |
Module.print(text); | |
Module.printErr(text); | |
} | |
ABORT = true; | |
EXITSTATUS = 1; | |
var extra = ''; | |
throw 'abort() at ' + stackTrace() + extra; | |
} | |
Module['abort'] = Module.abort = abort; | |
// {{PRE_RUN_ADDITIONS}} | |
if (Module['preInit']) { | |
if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; | |
while (Module['preInit'].length > 0) { | |
Module['preInit'].pop()(); | |
} | |
} | |
// shouldRunNow refers to calling main(), not run(). | |
var shouldRunNow = true; | |
if (Module['noInitialRun']) { | |
shouldRunNow = false; | |
} | |
run(); | |
// {{POST_RUN_ADDITIONS}} | |
// {{MODULE_ADDITIONS}} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function WebGL2DScreen(canvas) { | |
var gl = null; | |
var oldGetContext = (function(func) { | |
return function(type) { | |
gl = null; | |
return func.call(canvas, type); | |
}; | |
})(canvas.getContext); | |
canvas.getContext = function(type) { | |
if (type !== '2d') return oldGetContext(type); | |
gl = oldGetContext("webgl") || oldGetContext("experimental-webgl"); | |
if (!gl) return oldGetContext('2d'); | |
var vertexShaderString = | |
'attribute vec2 vertexPosition; \n\ | |
varying vec2 texCoord; \n\ | |
void main(void) { \n\ | |
texCoord = vec2(vertexPosition.x, 1.0 - vertexPosition.y); \n\ | |
gl_Position = vec4(2.0 * vertexPosition - 1.0, 0.0, 1.0); \n\ | |
} \n'; | |
var fragmentShaderString = | |
'precision mediump float; \n\ | |
uniform sampler2D texSampler; \n\ | |
varying vec2 texCoord; \n\ | |
void main(void) { \n\ | |
/* the rasterizer writes out data in bgra format */ \n\ | |
gl_FragColor = texture2D(texSampler, texCoord).bgra; \n\ | |
} \n'; | |
var texarray, program; | |
var texUnit = 0; // we will use texture unit 0 only | |
var vertexShader = gl.createShader(gl.VERTEX_SHADER); | |
gl.shaderSource(vertexShader, vertexShaderString); | |
gl.compileShader(vertexShader); | |
if (gl.getError() !== gl.NO_ERROR) return oldGetContext('2d'); | |
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); | |
gl.shaderSource(fragmentShader, fragmentShaderString); | |
gl.compileShader(fragmentShader); | |
if (gl.getError() !== gl.NO_ERROR) return oldGetContext('2d'); | |
program = gl.createProgram(); | |
gl.attachShader(program, vertexShader); | |
gl.attachShader(program, fragmentShader); | |
gl.linkProgram(program); | |
gl.useProgram(program); | |
if (gl.getError() !== gl.NO_ERROR) return oldGetContext('2d'); | |
var vertexPositionAttrLoc = gl.getAttribLocation(program, "vertexPosition"); | |
gl.enableVertexAttribArray(vertexPositionAttrLoc); | |
var texSamplerLoc = gl.getUniformLocation(program, "texSampler"); | |
gl.uniform1i(texSamplerLoc, texUnit); | |
var vertexPositionBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer); | |
var vertices = [ 0.0, 0.0, | |
0.0, 1.0, | |
1.0, 0.0, | |
1.0, 1.0 ]; | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); | |
gl.vertexAttribPointer(vertexPositionAttrLoc, 2, gl.FLOAT, false, 0, 0); | |
texarray = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 255, 128, 0, 255, 0, 0, 0, 0, 255, 128, 0, 255, 0, 0, 0, 0, | |
255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, | |
0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, | |
0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255]); | |
texture = gl.createTexture(); | |
gl.bindTexture(gl.TEXTURE_2D, texture); | |
//gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); // so we can have the above array upright. Otherwise, it helps performance NOT to flip. | |
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4); // 4 is the default. added for explicitness. common pitfall. | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); // so it works with this non-power-of-two texture | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); | |
gl.bindTexture(gl.TEXTURE_2D, null); | |
var image = null; | |
return { | |
createImageData: function(w, h) { | |
if (w !== canvas.width || h !== canvas.height) { | |
throw 'bad inputs to createImageData'; | |
} | |
if (image && image.width === canvas.width && image.height == canvas.height) return image; | |
return image = { | |
width: w, | |
height: h, | |
data: new Uint8Array(w*h*4) | |
}; | |
}, | |
getImageData: function(x, y, w, h) { | |
if (x !== 0 || y !== 0 || w !== canvas.width || h !== canvas.height) { | |
throw 'bad inputs to getImageData'; | |
} | |
return this.createImageData(w, h); | |
}, | |
putImageData: function(image, x, y) { | |
if (x !== 0 || y !== 0) { | |
throw 'bad inputs to putImageData'; | |
} | |
gl.activeTexture(gl.TEXTURE0); // so we're being explicit with texture units. But here, texUnit is set to 0 so this is just pedantic. | |
gl.bindTexture(gl.TEXTURE_2D, texture); | |
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, canvas.width, canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, image.data); | |
gl.clearColor(0.0, 0.0, 0.0, 1.0); | |
gl.clear(gl.COLOR_BUFFER_BIT); | |
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); | |
} | |
}; | |
}; | |
return canvas; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment