summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS4
-rw-r--r--ChangeLog23
-rw-r--r--README.md2
-rwxr-xr-xemcc35
-rw-r--r--emscripten-version.txt2
-rw-r--r--media/powered_by_logo.pngbin0 -> 24795 bytes
-rw-r--r--media/powered_by_logo.svg1547
-rw-r--r--media/switch_logo.epsbin1114650 -> 0 bytes
-rw-r--r--media/switch_logo.jpegbin35951 -> 0 bytes
-rw-r--r--media/switch_logo.pngbin0 -> 19222 bytes
-rwxr-xr-xscons-tools/emscripten.py58
-rw-r--r--src/closure-externs.js60
-rw-r--r--src/library.js22
-rw-r--r--src/library_browser.js55
-rw-r--r--src/library_egl.js6
-rw-r--r--src/library_glfw.js2
-rw-r--r--src/library_html5.js61
-rw-r--r--src/library_openal.js27
-rw-r--r--src/library_sdl.js13
-rw-r--r--src/postamble.js8
-rw-r--r--src/preamble.js17
-rw-r--r--src/relooper/Relooper.cpp53
-rw-r--r--src/relooper/Relooper.h8
-rw-r--r--src/relooper/test.cpp92
-rw-r--r--src/relooper/test.txt47
-rw-r--r--src/runtime.js5
-rw-r--r--src/settings.js1
-rw-r--r--src/shell.js4
-rw-r--r--system/include/emscripten/emscripten.h42
-rw-r--r--system/include/emscripten/html5.h18
-rw-r--r--tests/cases/aliases_fastcomp.ll41
-rw-r--r--tests/cases/aliases_fastcomp.txt5
-rw-r--r--tests/emscripten_log/emscripten_log.cpp11
-rwxr-xr-xtests/fuzz/csmith_driver.py4
-rw-r--r--tests/mem_init.cpp24
-rw-r--r--tests/openal_playback.cpp2
-rwxr-xr-xtests/runner.py5
-rw-r--r--tests/sdl_wm_togglefullscreen.c78
-rw-r--r--tests/test_browser.py111
-rw-r--r--tests/test_core.py2
-rw-r--r--tests/test_html5_fullscreen.c23
-rw-r--r--tests/test_html5_mouse.c159
-rw-r--r--tests/test_interactive.py94
-rw-r--r--tests/test_other.py16
-rw-r--r--tools/file_packager.py16
-rw-r--r--tools/js-optimizer.js51
-rw-r--r--tools/profile_stripper.py43
-rw-r--r--tools/profile_used.py17
-rw-r--r--tools/shared.py9
-rw-r--r--tools/system_libs.py17
-rw-r--r--tools/test-js-optimizer-asm-outline1-output.js39
51 files changed, 2706 insertions, 273 deletions
diff --git a/AUTHORS b/AUTHORS
index 076ce1cb..03abe143 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -10,7 +10,7 @@ a license to everyone to use it as detailed in LICENSE.)
* Sigmund Vik <sigmund_vik@yahoo.com>
* Jeff Terrace <jterrace@gmail.com>
* Benoit Tremblay <benoit.tremblay@frimastudio.com>
-* Andreas Bergmeier <andreas.bergmeier@gmx.net>
+* Andreas Bergmeier <abergmeier@gmx.net>
* Ben Schwartz <bens@alum.mit.edu>
* David Claughton <dave@eclecticdave.com>
* David Yip <yipdw@member.fsf.org>
@@ -130,4 +130,6 @@ a license to everyone to use it as detailed in LICENSE.)
* Nicolas Peri <nicox@shivaengine.com> (copyright owned by ShiVa Technologies, SAS)
* Bernhard Fey <e-male@web.de>
* Dave Nicponski <dave.nicponski@gmail.com>
+* Jonathan Jarri <noxalus@gmail.com>
+* Daniele Di Proietto <daniele.di.proietto@gmail.com>
diff --git a/ChangeLog b/ChangeLog
index fea67ddd..328e3cac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,7 +10,28 @@ Not all changes are documented here. In particular, new features, user-oriented
Current trunk code
------------------
- To see a list of commits in the active development branch 'incoming', which have not yet been packaged in a release, see
- https://github.com/kripken/emscripten/compare/1.12.3...incoming
+ https://github.com/kripken/emscripten/compare/1.13.1...incoming
+
+v1.13.1: 3/10/2014
+------------------
+ - Disallow C implicit function declarations by making it an error instead of a warning by default. These will not work with Emscripten, due to strict Emscripten signature requirements when calling function pointers (#2175).
+ - Allow transitioning to full screen from SDL as a response to mouse press events.
+ - Fixed a bug in previous 1.13.0 release that broke fullscreen transitioning from working.
+ - Fixed emscripten/html5.h to be used in C source files.
+ - Fix an issue where extraneous system libraries would get included in the generated output (#2191).
+ - Added a new function emscripten_async_wget2_data() that allows reading from an XMLHTTPRequest directly into memory while supporting advanced features.
+ - Fixed esc key code in GLFW.
+ - Full list of changes: https://github.com/kripken/emscripten/compare/1.13.0...1.13.1
+
+v1.13.0: 3/3/2014
+------------------
+ - Fixed the deprecated source mapping syntax warning.
+ - Fixed a buffer overflow issue in emscripten_get_callstack (#2171).
+ - Added support for -Os (optimize for size) and -Oz (aggressively optimize for size) arguments to emcc.
+ - Fixed a typo that broko the call signature of glCompressedTexSubImage2D() function (#2173).
+ - Added new browser fullscreen resize logic that always retains aspect ratio and adds support for IE11.
+ - Improve debug messaging with bad function pointer calls when -s ASSERTIONS=2 is set.
+ - Full list of changes: https://github.com/kripken/emscripten/compare/1.12.3...1.13.0
v1.12.3: 2/27/2014
------------------
diff --git a/README.md b/README.md
index 6b4778bf..8f0d244e 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-![emscripten logo](media/switch_logo.jpeg)
+![emscripten logo](media/switch_logo.png)
Emscripten is an LLVM-to-JavaScript compiler. It takes LLVM bitcode - which can be generated
from C/C++, using `llvm-gcc` (DragonEgg) or `clang`, or any other language that can be
diff --git a/emcc b/emcc
index f7d1a939..1c57d991 100755
--- a/emcc
+++ b/emcc
@@ -235,6 +235,13 @@ Options that are modified or new in %s include:
slower because JS optimization will be
limited to 1 core. (default in -O0)
+ -profiling Use reasonable defaults when emitting JS to
+ make the build useful for profiling. This
+ sets -g2 (preserve function names) and may
+ also enable optimizations that affect
+ performance and otherwise might not be
+ performed in -g2.
+
--typed-arrays <mode> 0: No typed arrays
1: Parallel typed arrays
2: Shared (C-like) typed arrays (default)
@@ -470,7 +477,16 @@ Options that are modified or new in %s include:
1: Emit a separate memory initialization file
in binary format. This is more efficient than
storing it as text inside JavaScript, but does
- mean you have another file to publish.
+ mean you have another file to publish. The
+ binary file will also be loaded asynchronously,
+ which means main() will not be called until
+ the file is downloaded and applied; you cannot
+ call any C functions until it arrives. (Call
+ yourself from main() to know when all async
+ stuff has happened and it is safe to call
+ library functions, as main() will only be
+ called at that time. You can also call
+ addOnPreMain from a preRun.)
-Wno-warn-absolute-paths If not specified, the compiler will warn about any
uses of absolute paths in -I and -L command line
@@ -761,6 +777,7 @@ try:
opt_level = 0
debug_level = 0
+ profiling = False
js_opts = None
llvm_opts = None
llvm_lto = None
@@ -881,6 +898,10 @@ try:
requested_level = newargs[i][2:] or '3'
debug_level = validate_arg_level(requested_level, 4, 'Invalid debug level: ' + newargs[i])
newargs[i] = '-g' # we'll need this to get LLVM debug info
+ elif newargs[i] == '-profiling':
+ debug_level = 2
+ profiling = True
+ newargs[i] = ''
elif newargs[i] == '--bind':
bind = True
newargs[i] = ''
@@ -1025,9 +1046,6 @@ try:
if DEBUG: start_time = time.time() # done after parsing arguments, which might affect debug state
- if closure:
- assert os.path.exists(shared.CLOSURE_COMPILER), logging.error('fatal: Closure compiler (%s) does not exist', shared.CLOSURE_COMPILER)
-
for i in range(len(newargs)):
if newargs[i] == '-s':
if is_minus_s_for_emcc(newargs, i):
@@ -1181,7 +1199,7 @@ try:
shared.Settings.ASM_JS = 1 if opt_level > 0 else 2
try:
assert shared.Settings.UNALIGNED_MEMORY == 0, 'forced unaligned memory not supported in fastcomp'
- assert shared.Settings.CHECK_HEAP_ALIGN == 0, 'check heap align not supported in fastcomp yet'
+ assert shared.Settings.CHECK_HEAP_ALIGN == 0, 'check heap align not supported in fastcomp - use SAFE_HEAP instead'
assert shared.Settings.SAFE_DYNCALLS == 0, 'safe dyncalls not supported in fastcomp'
assert shared.Settings.ASM_HEAP_LOG == 0, 'asm heap log not supported in fastcomp'
assert shared.Settings.LABEL_DEBUG == 0, 'label debug not supported in fastcomp'
@@ -1243,6 +1261,10 @@ try:
logging.warning('disabling closure because debug info was requested')
closure = False
+ if closure:
+ shared.Settings.CLOSURE_COMPILER = 1
+ assert os.path.exists(shared.CLOSURE_COMPILER), logging.error('fatal: Closure compiler (%s) does not exist', shared.CLOSURE_COMPILER)
+
assert shared.LLVM_TARGET in shared.COMPILER_OPTS
if shared.LLVM_TARGET == 'i386-pc-linux-gnu':
shared.Settings.TARGET_X86 = 1
@@ -1369,6 +1391,7 @@ try:
if file_ending.endswith(SOURCE_ENDINGS):
temp_file = temp_files[i]
logging.debug('optimizing %s', input_file)
+ #if DEBUG: shutil.copyfile(temp_file, os.path.join(TEMP_DIR, 'to_opt.bc') # useful when LLVM opt aborts
shared.Building.llvm_opt(temp_file, llvm_opts)
# If we were just asked to generate bitcode, stop there
@@ -1487,7 +1510,7 @@ try:
# Prepare .ll for Emscripten
if not LEAVE_INPUTS_RAW:
- if save_bc:
+ if save_bc and not fastcomp:
final = shared.Building.llvm_dis(final, final + '.ll')
else:
assert len(input_files) == 1
diff --git a/emscripten-version.txt b/emscripten-version.txt
index bf2b5ccf..2e46fa6f 100644
--- a/emscripten-version.txt
+++ b/emscripten-version.txt
@@ -1,2 +1,2 @@
-1.13.0
+1.13.2
diff --git a/media/powered_by_logo.png b/media/powered_by_logo.png
new file mode 100644
index 00000000..69e90c77
--- /dev/null
+++ b/media/powered_by_logo.png
Binary files differ
diff --git a/media/powered_by_logo.svg b/media/powered_by_logo.svg
new file mode 100644
index 00000000..f39123c1
--- /dev/null
+++ b/media/powered_by_logo.svg
@@ -0,0 +1,1547 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ width="900px"
+ height="400px"
+ viewBox="0 0 900 400"
+ 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> \ No newline at end of file
diff --git a/media/switch_logo.eps b/media/switch_logo.eps
deleted file mode 100644
index 741970c1..00000000
--- a/media/switch_logo.eps
+++ /dev/null
Binary files differ
diff --git a/media/switch_logo.jpeg b/media/switch_logo.jpeg
deleted file mode 100644
index 7c05cd94..00000000
--- a/media/switch_logo.jpeg
+++ /dev/null
Binary files differ
diff --git a/media/switch_logo.png b/media/switch_logo.png
new file mode 100644
index 00000000..1e072247
--- /dev/null
+++ b/media/switch_logo.png
Binary files differ
diff --git a/scons-tools/emscripten.py b/scons-tools/emscripten.py
index af85f106..94153adb 100755
--- a/scons-tools/emscripten.py
+++ b/scons-tools/emscripten.py
@@ -9,11 +9,6 @@ from SCons.Scanner import Scanner
def exists(env):
return True
-def _expand_settings_flags(settings, env):
- return [
- ('-s%s=%s' % (KEY, json.dumps(VALUE).replace('"', '\\"')))
- for KEY, VALUE in settings.items() ]
-
emscripten_version_files = {}
def build_version_file(env):
@@ -86,10 +81,6 @@ def emscripten(env, target_js, source_bc):
buildName('raw.js'),
[opt_ll])
- [optimized_js] = env.JSOptimizer(
- buildName('opt.js'),
- raw_emscripten_js)
-
prejs = [
env['EMSCRIPTEN_PREJS'],
'${EMSCRIPTEN_HOME}/src/embind/emval.js',
@@ -98,7 +89,7 @@ def emscripten(env, target_js, source_bc):
[concatenated_js] = env.Concatenate(
buildName('concat.js'),
[ prejs,
- optimized_js,
+ raw_emscripten_js,
env['EMSCRIPTEN_POSTJS'] ])
DISABLE_EMSCRIPTEN_WARNINGS = [
@@ -139,11 +130,6 @@ def emscripten(env, target_js, source_bc):
concatenated_js,
CLOSURE_FLAGS=['--language_in', 'ECMASCRIPT5']+DISABLE_EMSCRIPTEN_WARNINGS+['--formatting', 'PRETTY_PRINT', '--compilation_level', 'ADVANCED_OPTIMIZATIONS'])
- [global_emscripten_min_js] = env.JSOptimizer(
- buildName('global.min.js'),
- closure_js,
- JS_OPTIMIZER_PASSES=['simplifyExpressionsPost', 'minifyWhitespace', 'last'])
-
[emscripten_iteration_js] = env.WrapInModule(
buildName('iteration.js'),
iter_global_emscripten_js)
@@ -154,12 +140,27 @@ def emscripten(env, target_js, source_bc):
[emscripten_min_js] = env.WrapInModule(
buildName('min.js'),
- global_emscripten_min_js)
+ closure_js)
return [emscripten_iteration_js, emscripten_js, emscripten_min_js]
LIBC_SOURCES = [
'system/lib/dlmalloc.c',
+ 'system/lib/libc/musl/src/internal/floatscan.c',
+ 'system/lib/libc/musl/src/internal/shgetc.c',
+ 'system/lib/libc/musl/src/math/scalbn.c',
+ 'system/lib/libc/musl/src/math/scalbnl.c',
+ 'system/lib/libc/musl/src/stdio/__overflow.c',
+ 'system/lib/libc/musl/src/stdio/__toread.c',
+ 'system/lib/libc/musl/src/stdio/__towrite.c',
+ 'system/lib/libc/musl/src/stdio/__uflow.c',
+ 'system/lib/libc/musl/src/stdlib/atof.c',
+ 'system/lib/libc/musl/src/stdlib/strtod.c',
+ 'system/lib/libc/musl/src/string/memcmp.c',
+ 'system/lib/libc/musl/src/string/strcasecmp.c',
+ 'system/lib/libc/musl/src/string/strcmp.c',
+ 'system/lib/libc/musl/src/string/strncasecmp.c',
+ 'system/lib/libc/musl/src/string/strncmp.c',
'system/lib/libc/musl/src/string/wmemset.c',
'system/lib/libc/musl/src/string/wmemcpy.c',
]
@@ -185,13 +186,14 @@ LIBCXX_SOURCES = [os.path.join('system/lib/libcxx', x) for x in [
'strstream.cpp',
'system_error.cpp',
#'thread.cpp',
- 'typeinfo.cpp',
+ #'typeinfo.cpp',
'utility.cpp',
'valarray.cpp',
]]
LIBCXXABI_SOURCES = [os.path.join('system/lib/libcxxabi/src', x) for x in [
- 'private_typeinfo.cpp'
+ 'private_typeinfo.cpp',
+ 'typeinfo.cpp'
]]
# MAJOR HACK ALERT
@@ -233,6 +235,7 @@ def build_libcxx(env):
env = env.Clone()
env['CXXFLAGS'] = filter(lambda e: e not in ('-Werror', '-Wall'), env['CXXFLAGS'])
env['CCFLAGS'] = filter(lambda e: e not in ('-Werror', '-Wall'), env['CCFLAGS'])
+ env['CCFLAGS'] = env['CCFLAGS'] + ['-isystem${EMSCRIPTEN_HOME}/system/lib/libc/musl/src/internal/']
objs = [
env.Object(
@@ -248,16 +251,10 @@ def build_libcxx(env):
def generate(env):
env.SetDefault(
PYTHON=sys.executable,
- NODEJS='node',
- JS_ENGINE='$NODEJS',
- EMSCRIPTEN_FLAGS=['-v', '-j', '--suppressUsageWarning'],
+ EMSCRIPTEN_FLAGS=[],
EMSCRIPTEN_TEMP_DIR=env.Dir('#/emscripten.tmp'),
- _expand_settings_flags=_expand_settings_flags,
EMSCRIPTEN_PREJS=[],
EMSCRIPTEN_POSTJS=[],
- EMSCRIPTEN_SETTINGS={},
- _EMSCRIPTEN_SETTINGS_FLAGS='${_expand_settings_flags(EMSCRIPTEN_SETTINGS, __env__)}',
- JS_OPTIMIZER_PASSES=[],
LLVM_OPT_PASSES=['-std-compile-opts', '-std-link-opts'],
EMSCRIPTEN_HOME=env.Dir(os.path.join(os.path.dirname(__file__), '..')),
@@ -274,7 +271,7 @@ def generate(env):
RANLIBCOM='',
CCFLAGS=[
'-U__STRICT_ANSI__',
- '-target', 'asmjs-unknown-emscripten',
+ '-target', 'le32-unknown-nacl',
'-nostdinc',
'-Wno-#warnings',
'-Wno-error=unused-variable',
@@ -286,10 +283,9 @@ def generate(env):
'-Xclang', '-nostdinc++',
'-Xclang', '-nobuiltininc',
'-Xclang', '-nostdsysteminc',
- '-Xclang', '-isystem$EMSCRIPTEN_HOME/system/include',
+ '-Xclang', '-isystem$EMSCRIPTEN_HOME/system/include/compat',
'-Xclang', '-isystem$EMSCRIPTEN_HOME/system/include/libc',
'-Xclang', '-isystem$EMSCRIPTEN_HOME/system/include/libcxx',
- '-Xclang', '-isystem$EMSCRIPTEN_HOME/system/include/bsd',
'-emit-llvm'],
CXXFLAGS=['-std=c++11', '-fno-exceptions'],
)
@@ -307,11 +303,7 @@ def generate(env):
)
env['BUILDERS']['Emscripten'] = Builder(
- action='$PYTHON ${EMSCRIPTEN_HOME}/emscripten.py $EMSCRIPTEN_FLAGS $_EMSCRIPTEN_SETTINGS_FLAGS --temp-dir=$EMSCRIPTEN_TEMP_DIR --compiler $JS_ENGINE --relooper=third-party/relooper.js $SOURCE > $TARGET',
- target_scanner=EmscriptenScanner)
-
- env['BUILDERS']['JSOptimizer'] = Builder(
- action='$JS_ENGINE ${EMSCRIPTEN_HOME}/tools/js-optimizer.js $SOURCE $JS_OPTIMIZER_PASSES > $TARGET',
+ action='$PYTHON ${EMSCRIPTEN_HOME}/emcc ${EMSCRIPTEN_FLAGS} $SOURCE -o $TARGET',
target_scanner=EmscriptenScanner)
def depend_on_embedder(target, source, env):
diff --git a/src/closure-externs.js b/src/closure-externs.js
index a82aa669..fe6d84aa 100644
--- a/src/closure-externs.js
+++ b/src/closure-externs.js
@@ -108,3 +108,63 @@ var flags = {};
flags.binary;
+/**
+ * @fileoverview Definitions for W3C's Gamepad specification.
+ * @see http://www.w3.org/TR/gamepad/
+ * @externs
+ */
+
+/**
+ * @typedef {{id: string, index: number, timestamp: number, axes: Array.<number>, buttons: Array.<number>}}
+ */
+var Gamepad;
+
+/**
+* @type {Array.<number>}
+*/
+Gamepad.buttons;
+
+/**
+* @type {Array.<number>}
+*/
+Gamepad.axes;
+
+/**
+* @type {number}
+*/
+Gamepad.index;
+
+/**
+* @type {string}
+*/
+Gamepad.id;
+
+/**
+* @type {number}
+*/
+Gamepad.timestamp;
+
+/**
+ * @return {Array.<Gamepad>}
+ */
+navigator.getGamepads = function() {};
+
+/**
+ * @return {Array.<Gamepad>}
+ */
+navigator.webkitGetGamepads = function() {};
+
+/**
+ * @return {Array.<Gamepad>}
+ */
+navigator.webkitGamepads = function() {};
+
+/**
+ * @return {Array.<Gamepad>}
+ */
+navigator.mozGamepads = function() {};
+
+/**
+ * @return {Array.<Gamepad>}
+ */
+navigator.gamepads = function() {};
diff --git a/src/library.js b/src/library.js
index 2c3d5e03..e711ee98 100644
--- a/src/library.js
+++ b/src/library.js
@@ -6402,6 +6402,13 @@ LibraryManager.library = {
siginterrupt: function() { throw 'siginterrupt not implemented' },
+ raise__deps: ['$ERRNO_CODES', '__setErrNo'],
+ raise: function(sig) {
+ // TODO:
+ ___setErrNo(ERRNO_CODES.ENOSYS);
+ return -1;
+ },
+
// ==========================================================================
// sys/wait.h
// ==========================================================================
@@ -8915,10 +8922,19 @@ LibraryManager.library = {
emscripten_get_callstack_js: function(flags) {
var err = new Error();
if (!err.stack) {
- Runtime.warnOnce('emscripten_get_callstack_js is not supported on this browser!');
- return '';
+ // 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) {
+ Runtime.warnOnce('emscripten_get_callstack_js is not supported on this browser!');
+ return '';
+ }
}
- var callstack = new Error().stack.toString();
+ var callstack = err.stack.toString();
// Find the symbols in the callstack that corresponds to the functions that report callstack information, and remove everyhing up to these from the output.
var iThisFunc = callstack.lastIndexOf('_emscripten_log');
diff --git a/src/library_browser.js b/src/library_browser.js
index a280d1b2..0808b9f0 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -723,8 +723,59 @@ mergeInto(LibraryManager.library, {
// PROGRESS
http.onprogress = function http_onprogress(e) {
- var percentComplete = (e.position / e.totalSize)*100;
- if (onprogress) Runtime.dynCall('vii', onprogress, [arg, percentComplete]);
+ if (e.lengthComputable || (e.lengthComputable === undefined && e.totalSize != 0)) {
+ var percentComplete = (e.position / e.totalSize)*100;
+ if (onprogress) Runtime.dynCall('vii', onprogress, [arg, percentComplete]);
+ }
+ };
+
+ // Useful because the browser can limit the number of redirection
+ try {
+ if (http.channel instanceof Ci.nsIHttpChannel)
+ http.channel.redirectionLimit = 0;
+ } catch (ex) { /* whatever */ }
+
+ if (_request == "POST") {
+ //Send the proper header information along with the request
+ http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ http.setRequestHeader("Content-length", _param.length);
+ http.setRequestHeader("Connection", "close");
+ http.send(_param);
+ } else {
+ http.send(null);
+ }
+ },
+
+ emscripten_async_wget2_data: function(url, request, param, arg, free, onload, onerror, onprogress) {
+ var _url = Pointer_stringify(url);
+ var _request = Pointer_stringify(request);
+ var _param = Pointer_stringify(param);
+
+ var http = new XMLHttpRequest();
+ http.open(_request, _url, true);
+ http.responseType = 'arraybuffer';
+
+ // LOAD
+ http.onload = function http_onload(e) {
+ if (http.status == 200 || _url.substr(0,4).toLowerCase() != "http") {
+ var byteArray = new Uint8Array(http.response);
+ var buffer = _malloc(byteArray.length);
+ HEAPU8.set(byteArray, buffer);
+ if (onload) Runtime.dynCall('viii', onload, [arg, buffer, byteArray.length]);
+ if (free) _free(buffer);
+ } else {
+ if (onerror) Runtime.dynCall('viii', onerror, [arg, http.status, http.statusText]);
+ }
+ };
+
+ // ERROR
+ http.onerror = function http_onerror(e) {
+ if (onerror) Runtime.dynCall('viii', onerror, [arg, http.status, http.statusText]);
+ };
+
+ // PROGRESS
+ http.onprogress = function http_onprogress(e) {
+ if (onprogress) Runtime.dynCall('viii', onprogress, [arg, e.loaded, e.lengthComputable || e.lengthComputable === undefined ? e.total : 0]);
};
// Useful because the browser can limit the number of redirection
diff --git a/src/library_egl.js b/src/library_egl.js
index e2d1df43..46ec939e 100644
--- a/src/library_egl.js
+++ b/src/library_egl.js
@@ -492,7 +492,11 @@ var LibraryEGL = {
EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
return 1;
},
-
+
+
+ // EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
+ eglWaitGL: 'eglWaitClient',
+
// EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
eglSwapInterval: function(display, interval) {
if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
diff --git a/src/library_glfw.js b/src/library_glfw.js
index b54205ad..e5782900 100644
--- a/src/library_glfw.js
+++ b/src/library_glfw.js
@@ -51,7 +51,7 @@ var LibraryGLFW = {
DOMToGLFWKeyCode: function(keycode) {
switch (keycode) {
case 0x09: return 295 ; //DOM_VK_TAB -> GLFW_KEY_TAB
- case 0x1B: return 255 ; //DOM_VK_ESCAPE -> GLFW_KEY_ESC
+ case 0x1B: return 257 ; //DOM_VK_ESCAPE -> GLFW_KEY_ESC
case 0x6A: return 313 ; //DOM_VK_MULTIPLY -> GLFW_KEY_KP_MULTIPLY
case 0x6B: return 315 ; //DOM_VK_ADD -> GLFW_KEY_KP_ADD
case 0x6D: return 314 ; //DOM_VK_SUBTRACT -> GLFW_KEY_KP_SUBTRACT
diff --git a/src/library_html5.js b/src/library_html5.js
index b17a0d4d..d9376c2a 100644
--- a/src/library_html5.js
+++ b/src/library_html5.js
@@ -17,6 +17,11 @@ var LibraryJSEvents = {
// so that we can report information about that element in the event message.
previousFullscreenElement: null,
+ // Remember the current mouse coordinates in case we need to emulate movementXY generation for browsers that don't support it.
+ // Some browsers (e.g. Safari 6.0.5) only give movementXY when Pointerlock is active.
+ previousScreenX: null,
+ previousScreenY: null,
+
// When the C runtime exits via exit(), we unregister all event handlers added by this library to be nice and clean.
// Track in this field whether we have yet registered that __ATEXIT__ handler.
removeEventListenersRegistered: false,
@@ -118,8 +123,11 @@ var LibraryJSEvents = {
// Stores objects representing each currently registered JS event handler.
eventHandlers: [],
+ isInternetExplorer: function() { return navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0; },
+
_removeHandler: function(i) {
- JSEvents.eventHandlers[i].target.removeEventListener(JSEvents.eventHandlers[i].eventTypeString, JSEvents.eventHandlers[i].handlerFunc, true);
+ var h = JSEvents.eventHandlers[i];
+ h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture);
JSEvents.eventHandlers.splice(i, 1);
},
@@ -139,6 +147,7 @@ var LibraryJSEvents = {
}
if (eventHandler.callbackfunc) {
+ eventHandler.eventListenerFunc = jsEventHandler;
eventHandler.target.addEventListener(eventHandler.eventTypeString, jsEventHandler, eventHandler.useCapture);
JSEvents.eventHandlers.push(eventHandler);
JSEvents.registerRemoveEventListeners();
@@ -177,11 +186,9 @@ var LibraryJSEvents = {
}
};
- var isInternetExplorer = (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0);
-
var eventHandler = {
target: JSEvents.findEventTarget(target),
- allowsDeferredCalls: isInternetExplorer ? false : true, // MSIE doesn't allow fullscreen and pointerlock requests from key handlers, others do.
+ allowsDeferredCalls: JSEvents.isInternetExplorer() ? false : true, // MSIE doesn't allow fullscreen and pointerlock requests from key handlers, others do.
eventTypeString: eventTypeString,
callbackfunc: callbackfunc,
handlerFunc: handlerFunc,
@@ -203,10 +210,12 @@ var LibraryJSEvents = {
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.metaKey, 'e.metaKey', 'i32') }}};
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.button, 'e.button', 'i16') }}};
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.buttons, 'e.buttons', 'i16') }}};
- {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.movementX, 'e.movementX || e.mozMovementX || e.webkitMovementX', 'i32') }}};
- {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.movementY, 'e.movementY || e.mozMovementY || e.webkitMovementY', 'i32') }}};
+ {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.movementX, 'e["movementX"] || e["mozMovementX"] || e["webkitMovementX"] || (e.screenX-JSEvents.previousScreenX)', 'i32') }}};
+ {{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.movementY, 'e["movementY"] || e["mozMovementY"] || e["webkitMovementY"] || (e.screenY-JSEvents.previousScreenY)', 'i32') }}};
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.canvasX, 'e.clientX - rect.left', 'i32') }}};
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.canvasY, 'e.clientY - rect.top', 'i32') }}};
+ JSEvents.previousScreenX = e.screenX;
+ JSEvents.previousScreenY = e.screenY;
},
registerMouseEventCallback: function(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString) {
@@ -230,6 +239,8 @@ var LibraryJSEvents = {
handlerFunc: handlerFunc,
useCapture: useCapture
};
+ // In IE, mousedown events don't either allow deferred calls to be run!
+ if (JSEvents.isInternetExplorer() && eventTypeString == 'mousedown') eventHandler.allowsDeferredCalls = false;
JSEvents.registerOrRemoveHandler(eventHandler);
},
@@ -237,13 +248,27 @@ var LibraryJSEvents = {
if (!JSEvents.wheelEvent) {
JSEvents.wheelEvent = _malloc( {{{ C_STRUCTS.EmscriptenWheelEvent.__size__ }}} );
}
- var handlerFunc = function(event) {
+ // The DOM Level 3 events spec event 'wheel'
+ var wheelHandlerFunc = function(event) {
var e = event || window.event;
JSEvents.fillMouseEventData(JSEvents.wheelEvent, e);
- {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaX, 'e.deltaX', 'double') }}};
- {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaY, 'e.deltaY', 'double') }}};
- {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaZ, 'e.deltaZ', 'double') }}};
- {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaMode, 'e.deltaMode', 'i32') }}};
+ {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaX, 'e["deltaX"]', 'double') }}};
+ {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaY, 'e["deltaY"]', 'double') }}};
+ {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaZ, 'e["deltaZ"]', 'double') }}};
+ {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaMode, 'e["deltaMode"]', 'i32') }}};
+ var shouldCancel = Runtime.dynCall('iiii', callbackfunc, [eventTypeId, JSEvents.wheelEvent, userData]);
+ if (shouldCancel) {
+ e.preventDefault();
+ }
+ };
+ // The 'mousewheel' event as implemented in Safari 6.0.5
+ var mouseWheelHandlerFunc = function(event) {
+ var e = event || window.event;
+ JSEvents.fillMouseEventData(JSEvents.wheelEvent, e);
+ {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaX, 'e["wheelDeltaX"]', 'double') }}};
+ {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaY, '-e["wheelDeltaY"] /* Invert to unify direction with the DOM Level 3 wheel event. */', 'double') }}};
+ {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaZ, '0 /* Not available */', 'double') }}};
+ {{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaMode, '0 /* DOM_DELTA_PIXEL */', 'i32') }}};
var shouldCancel = Runtime.dynCall('iiii', callbackfunc, [eventTypeId, JSEvents.wheelEvent, userData]);
if (shouldCancel) {
e.preventDefault();
@@ -255,7 +280,7 @@ var LibraryJSEvents = {
allowsDeferredCalls: true,
eventTypeString: eventTypeString,
callbackfunc: callbackfunc,
- handlerFunc: handlerFunc,
+ handlerFunc: (eventTypeString == 'wheel') ? wheelHandlerFunc : mouseWheelHandlerFunc,
useCapture: useCapture
};
JSEvents.registerOrRemoveHandler(eventHandler);
@@ -918,8 +943,16 @@ var LibraryJSEvents = {
},
emscripten_set_wheel_callback: function(target, userData, useCapture, callbackfunc) {
- JSEvents.registerWheelEventCallback(target, userData, useCapture, callbackfunc, {{{ cDefine('EMSCRIPTEN_EVENT_WHEEL') }}}, "wheel");
- return {{{ cDefine('EMSCRIPTEN_RESULT_SUCCESS') }}};
+ target = JSEvents.findEventTarget(target);
+ if (typeof target.onwheel !== 'undefined') {
+ JSEvents.registerWheelEventCallback(target, userData, useCapture, callbackfunc, {{{ cDefine('EMSCRIPTEN_EVENT_WHEEL') }}}, "wheel");
+ return {{{ cDefine('EMSCRIPTEN_RESULT_SUCCESS') }}};
+ } else if (typeof target.onmousewheel !== 'undefined') {
+ JSEvents.registerWheelEventCallback(target, userData, useCapture, callbackfunc, {{{ cDefine('EMSCRIPTEN_EVENT_WHEEL') }}}, "mousewheel");
+ return {{{ cDefine('EMSCRIPTEN_RESULT_SUCCESS') }}};
+ } else {
+ return {{{ cDefine('EMSCRIPTEN_RESULT_NOT_SUPPORTED') }}};
+ }
},
emscripten_set_resize_callback: function(target, userData, useCapture, callbackfunc) {
diff --git a/src/library_openal.js b/src/library_openal.js
index fd382aa1..58b11607 100644
--- a/src/library_openal.js
+++ b/src/library_openal.js
@@ -58,9 +58,21 @@ var LibraryOpenAL = {
entry.src = AL.currentContext.ctx.createBufferSource();
entry.src.buffer = entry.buffer;
entry.src.connect(src.gain);
- entry.src.start(startTime, offset);
-
+ if (typeof(entry.src.start) !== 'undefined') {
+ entry.src.start(startTime, offset);
+ } else if (typeof(entry.src.noteOn) !== 'undefined') {
+ entry.src.noteOn(startTime);
#if OPENAL_DEBUG
+ if (offset > 0) {
+ Runtime.warnOnce('The current browser does not support AudioBufferSourceNode.start(when, offset); method, so cannot play back audio with an offset '+offset+' secs! Audio glitches will occur!');
+ }
+#endif
+ }
+#if OPENAL_DEBUG
+ else {
+ Runtime.warnOnce('Unable to start AudioBufferSourceNode playback! Not supported by the browser?');
+ }
+
console.log('updateSource queuing buffer ' + i + ' for source ' + idx + ' at ' + startTime + ' (offset by ' + offset + ')');
#endif
}
@@ -204,6 +216,9 @@ var LibraryOpenAL = {
}
if (ctx) {
+ // Old Web Audio API (e.g. Safari 6.0.5) had an inconsistently named createGainNode function.
+ if (typeof(ctx.createGain) === 'undefined') ctx.createGain = ctx.createGainNode;
+
var gain = ctx.createGain();
gain.connect(ctx.destination);
var context = {
@@ -1283,16 +1298,16 @@ var LibraryOpenAL = {
ret = 'Out of Memory';
break;
case 0x1004 /* ALC_DEFAULT_DEVICE_SPECIFIER */:
- if (typeof(AudioContext) == "function" ||
- typeof(webkitAudioContext) == "function") {
+ if (typeof(AudioContext) !== "undefined" ||
+ typeof(webkitAudioContext) !== "undefined") {
ret = 'Device';
} else {
return 0;
}
break;
case 0x1005 /* ALC_DEVICE_SPECIFIER */:
- if (typeof(AudioContext) == "function" ||
- typeof(webkitAudioContext) == "function") {
+ if (typeof(AudioContext) !== "undefined" ||
+ typeof(webkitAudioContext) !== "undefined") {
ret = 'Device\0';
} else {
ret = '\0';
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 654d60f8..2606bafc 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -1765,9 +1765,9 @@ var LibrarySDL = {
// 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) === 'function') {
+ if (typeof(AudioContext) !== 'undefined') {
SDL.audioContext = new AudioContext();
- } else if (typeof(webkitAudioContext) === 'function') {
+ } else if (typeof(webkitAudioContext) !== 'undefined') {
SDL.audioContext = new webkitAudioContext();
} else {
throw 'Web Audio API is not available!';
@@ -1810,7 +1810,12 @@ var LibrarySDL = {
}
#endif
var playtime = Math.max(curtime, SDL.audio.nextPlayTime);
- SDL.audio.soundSource[SDL.audio.nextSoundSource]['start'](playtime);
+ var ss = SDL.audio.soundSource[SDL.audio.nextSoundSource];
+ if (typeof ss['start'] !== 'undefined') {
+ ss['start'](playtime);
+ } else if (typeof ss['noteOn'] !== 'undefined') {
+ ss['noteOn'](playtime);
+ }
var buffer_duration = sizeSamplesPerChannel / SDL.audio.freq;
SDL.audio.nextPlayTime = playtime + buffer_duration;
// Timer will be scheduled before the buffer completed playing.
@@ -1883,7 +1888,7 @@ var LibrarySDL = {
} else if (!SDL.audio.timer && !SDL.audio.scriptProcessorNode) {
// If we are using the same sampling frequency as the native sampling rate of the Web Audio graph is using, we can feed our buffers via
// Web Audio ScriptProcessorNode, which is a pull-mode API that calls back to our code to get audio data.
- if (SDL.audioContext !== undefined && SDL.audio.freq == SDL.audioContext['sampleRate']) {
+ if (SDL.audioContext !== undefined && SDL.audio.freq == SDL.audioContext['sampleRate'] && typeof SDL.audioContext['createScriptProcessor'] !== 'undefined') {
var sizeSamplesPerChannel = SDL.audio.bufferSize / SDL.audio.bytesPerSample / SDL.audio.channels; // How many samples per a single channel fit in the cb buffer?
SDL.audio.scriptProcessorNode = SDL.audioContext['createScriptProcessor'](sizeSamplesPerChannel, 0, SDL.audio.channels);
SDL.audio.scriptProcessorNode['onaudioprocess'] = function (e) {
diff --git a/src/postamble.js b/src/postamble.js
index 603b330c..b90049bc 100644
--- a/src/postamble.js
+++ b/src/postamble.js
@@ -48,10 +48,6 @@ Module['callMain'] = Module.callMain = function callMain(args) {
args = args || [];
- if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
- Module.printErr('preload time: ' + (Date.now() - preloadStartTime) + ' ms');
- }
-
ensureInitRuntime();
var argc = args.length+1;
@@ -130,6 +126,10 @@ function run(args) {
preMain();
+ if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+ Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
+ }
+
if (Module['_main'] && shouldRunNow) {
Module['callMain'](args);
}
diff --git a/src/preamble.js b/src/preamble.js
index 28a1dcbc..89ab5026 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -187,16 +187,16 @@ function SAFE_HEAP_STORE(dest, value, bytes, isFloat) {
Module.print('SAFE_HEAP store: ' + [dest, value, bytes, isFloat]);
#endif
assert(dest > 0, 'segmentation fault');
- assert(dest % bytes === 0);
- assert(dest < Math.max(DYNAMICTOP, STATICTOP));
+ assert(dest % bytes === 0, 'alignment error');
+ assert(dest < Math.max(DYNAMICTOP, STATICTOP), 'segmentation fault (high)');
assert(DYNAMICTOP <= TOTAL_MEMORY);
setValue(dest, value, getSafeHeapType(bytes, isFloat), 1);
}
function SAFE_HEAP_LOAD(dest, bytes, isFloat, unsigned) {
assert(dest > 0, 'segmentation fault');
- assert(dest % bytes === 0);
- assert(dest < Math.max(DYNAMICTOP, STATICTOP));
+ assert(dest % bytes === 0, 'alignment error');
+ assert(dest < Math.max(DYNAMICTOP, STATICTOP), 'segmentation fault (high)');
assert(DYNAMICTOP <= TOTAL_MEMORY);
var type = getSafeHeapType(bytes, isFloat);
var ret = getValue(dest, type, 1);
@@ -805,7 +805,14 @@ function demangle(func) {
}
}
if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
- return rawList ? list : ret + flushList();
+ if (rawList) {
+ if (ret) {
+ list.push(ret + '?');
+ }
+ return list;
+ } else {
+ return ret + flushList();
+ }
}
try {
// Special-case the entry point, since its name differs from other name mangling.
diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp
index c11de099..780a6d59 100644
--- a/src/relooper/Relooper.cpp
+++ b/src/relooper/Relooper.cpp
@@ -122,7 +122,7 @@ void Branch::Render(Block *Target, bool SetLabel) {
if (Code) PrintIndented("%s\n", Code);
if (SetLabel) PrintIndented("label = %d;\n", Target->Id);
if (Ancestor) {
- if (Type != Direct) {
+ if (Type == Break || Type == Continue) {
if (Labeled) {
PrintIndented("%s L%d;\n", Type == Break ? "break" : "continue", Ancestor->Id);
} else {
@@ -287,6 +287,11 @@ void Block::Render(bool InLoop) {
Details->Render(Target, SetCurrLabel);
if (HasFusedContent) {
Fused->InnerMap.find(Target)->second->Render(InLoop);
+ } else if (Details->Type == Branch::Nested) {
+ // Nest the parent content here, and remove it from showing up afterwards as Next
+ assert(Parent->Next);
+ Parent->Next->Render(InLoop);
+ Parent->Next = NULL;
}
if (useSwitch && iter != ProcessedBranchesOut.end()) {
PrintIndented("break;\n");
@@ -650,7 +655,7 @@ void Relooper::Calculate(Block *Entry) {
Block *Curr = *iter;
for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
Block *Target = iter->first;
- if (!contains(Hoisted, Target) && !contains(NextEntries, Target))
+ if (!contains(Hoisted, Target) && !contains(NextEntries, Target)) {
// abort this hoisting
abort = true;
break;
@@ -1077,12 +1082,48 @@ void Relooper::Calculate(Block *Entry) {
SHAPE_SWITCH(Root, {
if (Simple->Inner->BranchVar) LastLoop = NULL; // a switch clears out the loop (TODO: only for breaks, not continue)
- // If there is a next block, we already know at Simple creation time to make direct branches,
- // and we can do nothing more. If there is no next however, then Natural is where we will
- // go to by doing nothing, so we can potentially optimize some branches to direct.
if (Simple->Next) {
+ if (!Simple->Inner->BranchVar && Simple->Inner->ProcessedBranchesOut.size() == 2) {
+ // If there is a next block, we already know at Simple creation time to make direct branches,
+ // and we can do nothing more in general. But, we try to optimize the case of a break and
+ // a direct: This would normally be if (break?) { break; } .. but if we
+ // make sure to nest the else, we can save the break, if (!break?) { .. } . This is also
+ // better because the more canonical nested form is easier to further optimize later. The
+ // downside is more nesting, which adds to size in builds with whitespace.
+ // Note that we avoid switches, as it complicates control flow and is not relevant
+ // for the common case we optimize here.
+ bool Found = false;
+ bool Abort = false;
+ for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) {
+ Block *Target = iter->first;
+ Branch *Details = iter->second;
+ if (Details->Type == Branch::Break) {
+ Found = true;
+ if (!contains(NaturalBlocks, Target)) Abort = true;
+ } else if (Details->Type != Branch::Direct) {
+ Abort = true;
+ }
+ }
+ if (Found && !Abort) {
+ for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) {
+ Block *Target = iter->first;
+ Branch *Details = iter->second;
+ if (Details->Type == Branch::Break) {
+ Details->Type = Branch::Direct;
+ if (MultipleShape *Multiple = Shape::IsMultiple(Details->Ancestor)) {
+ Multiple->NeedLoop--;
+ }
+ } else {
+ assert(Details->Type == Branch::Direct);
+ Details->Type = Branch::Nested;
+ }
+ }
+ }
+ }
Next = Simple->Next;
} else {
+ // If there is no next then Natural is where we will
+ // go to by doing nothing, so we can potentially optimize some branches to direct.
for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) {
Block *Target = iter->first;
Branch *Details = iter->second;
@@ -1140,7 +1181,7 @@ void Relooper::Calculate(Block *Entry) {
for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) {
Block *Target = iter->first;
Branch *Details = iter->second;
- if (Details->Type != Branch::Direct) {
+ if (Details->Type == Branch::Break || Details->Type == Branch::Continue) {
assert(LoopStack.size() > 0);
if (Details->Ancestor != LoopStack.top() && Details->Labeled) {
LabeledShape *Labeled = Shape::IsLabeled(Details->Ancestor);
diff --git a/src/relooper/Relooper.h b/src/relooper/Relooper.h
index 85adf359..152bae0e 100644
--- a/src/relooper/Relooper.h
+++ b/src/relooper/Relooper.h
@@ -24,9 +24,11 @@ struct Shape;
// Info about a branching from one block to another
struct Branch {
enum FlowType {
- Direct = 0, // We will directly reach the right location through other means, no need for continue or break
+ Direct = 0, // We will directly reach the right location through other means, no need for continue or break
Break = 1,
- Continue = 2
+ Continue = 2,
+ Nested = 3 // This code is directly reached, but we must be careful to ensure it is nested in an if - it is not reached
+ // unconditionally, other code paths exist alongside it that we need to make sure do not intertwine
};
Shape *Ancestor; // If not NULL, this shape is the relevant one for purposes of getting to the target block. We break or continue on it
Branch::FlowType Type; // If Ancestor is not NULL, this says whether to break or continue
@@ -59,7 +61,7 @@ struct Block {
Shape *Parent; // The shape we are directly inside
int Id; // A unique identifier, defined when added to relooper. Note that this uniquely identifies a *logical* block - if we split it, the two instances have the same content *and* the same Id
const char *Code; // The string representation of the code in this block. Owning pointer (we copy the input)
- const char *BranchVar; // If we have more than one branch out, the variable whose value determines where we go
+ const char *BranchVar; // A variable whose value determines where we go; if this is not NULL, emit a switch on that variable
bool IsCheckedMultipleEntry; // If true, we are a multiple entry, so reaching us requires setting the label variable
Block(const char *CodeInit, const char *BranchVarInit);
diff --git a/src/relooper/test.cpp b/src/relooper/test.cpp
index b4ce669c..78de9e64 100644
--- a/src/relooper/test.cpp
+++ b/src/relooper/test.cpp
@@ -312,7 +312,97 @@ int main() {
printf("\n\n", "the_var");
r.Render();
- puts(buffer);
+ puts(r.GetOutputBuffer());
+ }
+
+ if (1) {
+ Relooper::MakeOutputBuffer(10);
+
+ printf("\n\n-- If chain (optimized) --\n\n");
+
+ Block *b_a = new Block("// block A\n", NULL);
+ Block *b_b = new Block("// block B\n", NULL);
+ Block *b_c = new Block("// block C\n", NULL);
+
+ b_a->AddBranchTo(b_b, "a == 10", NULL);
+ b_a->AddBranchTo(b_c, NULL, NULL);
+
+ b_b->AddBranchTo(b_c, NULL, NULL);
+
+ Relooper r;
+ r.AddBlock(b_a);
+ r.AddBlock(b_b);
+ r.AddBlock(b_c);
+
+ r.Calculate(b_a);
+ r.Render();
+
+ puts(r.GetOutputBuffer());
+ }
+
+ if (1) {
+ Relooper::MakeOutputBuffer(10);
+
+ printf("\n\n-- If chain (optimized) --\n\n");
+
+ Block *b_a = new Block("// block A\n", NULL);
+ Block *b_b = new Block("// block B\n", NULL);
+ Block *b_c = new Block("// block C\n", NULL);
+ Block *b_d = new Block("// block D\n", NULL);
+
+ b_a->AddBranchTo(b_b, "a == 10", NULL);
+ b_a->AddBranchTo(b_d, NULL, NULL);
+
+ b_b->AddBranchTo(b_c, "b == 10", NULL);
+ b_b->AddBranchTo(b_d, NULL, NULL);
+
+ b_c->AddBranchTo(b_d, NULL, NULL);
+
+ Relooper r;
+ r.AddBlock(b_a);
+ r.AddBlock(b_b);
+ r.AddBlock(b_c);
+ r.AddBlock(b_d);
+
+ r.Calculate(b_a);
+ r.Render();
+
+ puts(r.GetOutputBuffer());
+ }
+
+ if (1) {
+ Relooper::MakeOutputBuffer(10);
+
+ printf("\n\n-- If chain (optimized, long) --\n\n");
+
+ Block *b_a = new Block("// block A\n", NULL);
+ Block *b_b = new Block("// block B\n", NULL);
+ Block *b_c = new Block("// block C\n", NULL);
+ Block *b_d = new Block("// block D\n", NULL);
+ Block *b_e = new Block("// block E\n", NULL);
+
+ b_a->AddBranchTo(b_b, "a == 10", NULL);
+ b_a->AddBranchTo(b_e, NULL, NULL);
+
+ b_b->AddBranchTo(b_c, "b == 10", NULL);
+ b_b->AddBranchTo(b_e, NULL, NULL);
+
+ b_c->AddBranchTo(b_d, "c == 10", NULL);
+ b_c->AddBranchTo(b_e, NULL, NULL);
+
+ b_d->AddBranchTo(b_e, NULL, NULL);
+
+ Relooper r;
+ r.AddBlock(b_a);
+ r.AddBlock(b_b);
+ r.AddBlock(b_c);
+ r.AddBlock(b_d);
+ r.AddBlock(b_e);
+
+ r.Calculate(b_a);
+ r.Render();
+
+ puts(r.GetOutputBuffer());
}
}
diff --git a/src/relooper/test.txt b/src/relooper/test.txt
index 82b02ad7..7d79e037 100644
--- a/src/relooper/test.txt
+++ b/src/relooper/test.txt
@@ -324,10 +324,6 @@
label = 1;
L0: while(1) {
switch(label|0) {
- case 3: {
- // block C
- break;
- }
case 1: {
// block A
if (check == 10) {
@@ -357,6 +353,49 @@
}
break;
}
+ case 3: {
+ // block C
+ break;
+ }
+ }
+ }
+
+
+
+-- If chain (optimized) --
+
+ // block A
+ if (a == 10) {
+ // block B
+ }
+ // block C
+
+
+
+-- If chain (optimized) --
+
+ // block A
+ if (a == 10) {
+ // block B
+ if (b == 10) {
+ // block C
+ }
+ }
+ // block D
+
+
+
+-- If chain (optimized, long) --
+
+ // block A
+ if (a == 10) {
+ // block B
+ if (b == 10) {
+ // block C
+ if (c == 10) {
+ // block D
+ }
}
}
+ // block E
diff --git a/src/runtime.js b/src/runtime.js
index 97de7473..2ae68279 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -484,6 +484,11 @@ var Runtime = {
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++) {
diff --git a/src/settings.js b/src/settings.js
index 02f6c8b5..1c41676d 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -133,6 +133,7 @@ var PRECISE_F32 = 0; // 0: Use JS numbers for floating-point values. These are 6
// therefore recommended.
var SIMD = 0; // Whether to emit SIMD code ( https://github.com/johnmccutchan/ecmascript_simd )
+var CLOSURE_COMPILER = 0; // Whether closure compiling is being run on this output
var CLOSURE_ANNOTATIONS = 0; // If set, the generated code will be annotated for the closure
// compiler. This potentially lets closure optimize the code better.
diff --git a/src/shell.js b/src/shell.js
index 65f7b923..e1c0eb54 100644
--- a/src/shell.js
+++ b/src/shell.js
@@ -14,7 +14,11 @@
// 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 CLOSURE_COMPILER
if (!Module) Module = eval('(function() { try { return {{{ EXPORT_NAME }}} || {} } catch(e) { return {} } })()');
+#else
+if (!Module) Module = (typeof {{{ EXPORT_NAME }}} !== 'undefined' ? {{{ EXPORT_NAME }}} : null) || {};
+#endif
// Sometimes an existing Module object exists with properties
// meant to overwrite the default module functionality. Here
diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h
index 4c1f7ad7..2b883f93 100644
--- a/system/include/emscripten/emscripten.h
+++ b/system/include/emscripten/emscripten.h
@@ -96,7 +96,7 @@ extern void emscripten_async_run_script(const char *script, int millis);
* for this is to load an asset module, that is, the output of the
* file packager.
*/
-extern void emscripten_async_load_script(const char *script, void (*onload)(), void (*onerror)());
+extern void emscripten_async_load_script(const char *script, void (*onload)(void), void (*onerror)(void));
/*
* Set a C function as the main event loop. The JS environment
@@ -138,11 +138,11 @@ extern void emscripten_async_load_script(const char *script, void (*onload)(), v
* before the main loop will be called the first time.
*/
#if __EMSCRIPTEN__
-extern void emscripten_set_main_loop(void (*func)(), int fps, int simulate_infinite_loop);
+extern void emscripten_set_main_loop(void (*func)(void), int fps, int simulate_infinite_loop);
extern void emscripten_set_main_loop_arg(void (*func)(void*), void *arg, int fps, int simulate_infinite_loop);
-extern void emscripten_pause_main_loop();
-extern void emscripten_resume_main_loop();
-extern void emscripten_cancel_main_loop();
+extern void emscripten_pause_main_loop(void);
+extern void emscripten_resume_main_loop(void);
+extern void emscripten_cancel_main_loop(void);
#else
#define emscripten_set_main_loop(func, fps, simulateInfiniteLoop) \
while (1) { func(); usleep(1000000/fps); }
@@ -214,7 +214,7 @@ inline void emscripten_async_call(void (*func)(void *), void *arg, int millis) {
* etc. are not run). This is implicitly performed when you do
* an asynchronous operation like emscripten_async_call.
*/
-extern void emscripten_exit_with_live_runtime();
+extern void emscripten_exit_with_live_runtime(void);
/*
* Hide the OS mouse cursor over the canvas. Note that SDL's
@@ -222,7 +222,7 @@ extern void emscripten_exit_with_live_runtime();
* the OS one. This command is useful to hide the OS cursor
* if your app draws its own cursor.
*/
-void emscripten_hide_mouse();
+void emscripten_hide_mouse(void);
/*
* Resizes the pixel width and height of the <canvas> element
@@ -244,10 +244,10 @@ void emscripten_get_canvas_size(int *width, int *height, int *isFullscreen);
* other calls to this function. The unit is ms.
*/
#if __EMSCRIPTEN__
-double emscripten_get_now();
+double emscripten_get_now(void);
#else
#include <time.h>
-double emscripten_get_now() {
+double emscripten_get_now(void) {
return (1000*clock())/(double)CLOCKS_PER_SEC;
}
#endif
@@ -255,7 +255,7 @@ double emscripten_get_now() {
/*
* Simple random number generation in [0, 1), maps to Math.random().
*/
-float emscripten_random();
+float emscripten_random(void);
/*
* This macro-looking function will cause Emscripten to
@@ -323,6 +323,28 @@ void emscripten_async_wget_data(const char* url, void *arg, void (*onload)(void*
void emscripten_async_wget2(const char* url, const char* file, const char* requesttype, const char* param, void *arg, void (*onload)(void*, const char*), void (*onerror)(void*, int), void (*onprogress)(void*, int));
/*
+ * More feature-complete version of emscripten_async_wget_data. Note:
+ * this version is experimental.
+ *
+ * The requesttype is 'GET' or 'POST',
+ * If is post request, param is the post parameter
+ * like key=value&key2=value2.
+ * The param 'arg' is a pointer will be pass to the callback
+ * The free param tells the runtime whether to free the returned buffer
+ after onload is complete. If false freeing the buffer is the receiver's
+ responsibility.
+ * The callbacks are called with an object pointer give in parameter.
+ * When file is ready then 'onload' callback will called with a pointer to
+ the buffer in memory and the size in bytes.
+ * During the download 'onprogress' callback will called. The first argument is
+ the number of bytes loaded. The second argument is the total size in bytes,
+ or zero if the size is unavailable.
+ * If any error occurred 'onerror' will called with the HTTP status code
+ and a string with the status description.
+ */
+void emscripten_async_wget2_data(const char* url, const char* requesttype, const char* param, void *arg, int free, void (*onload)(void*, void*, unsigned), void (*onerror)(void*, int, const char*), void (*onprogress)(void*, int, int));
+
+/*
* Prepare a file in asynchronous way. This does just the
* preparation part of emscripten_async_wget, that is, it
* works on file data already present, and asynchronously
diff --git a/system/include/emscripten/html5.h b/system/include/emscripten/html5.h
index 6109d87f..db81725a 100644
--- a/system/include/emscripten/html5.h
+++ b/system/include/emscripten/html5.h
@@ -123,6 +123,10 @@ extern "C" {
/*
* The event structure passed in keyboard events keypress, keydown and keyup.
* https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keys
+ *
+ * Note that since the DOM Level 3 Events spec is very recent at the time of writing (2014-03), uniform
+ * support for the different fields in the spec is still in flux. Be sure to check the results in multiple
+ * browsers. See the unmerged pull request #2222 for an example way on how to interpret the legacy key events.
*/
typedef struct EmscriptenKeyboardEvent {
// The printed representation of the pressed key.
@@ -144,14 +148,18 @@ typedef struct EmscriptenKeyboardEvent {
EM_UTF8 locale[32];
// The following fields are values from previous versions of the DOM key events specifications.
// See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent?redirectlocale=en-US&redirectslug=DOM%2FKeyboardEvent
- // The character representation of the key.
+ // The character representation of the key. This is the field 'char' from the docs, but renamed to charValue to avoid a C reserved word.
+ // Warning: This attribute has been dropped from DOM Level 3 events.
EM_UTF8 charValue[32];
// The Unicode reference number of the key; this attribute is used only by the keypress event. For keys whose char attribute
// contains multiple characters, this is the Unicode value of the first character in that attribute.
+ // Warning: This attribute is deprecated, you should use the field 'key' instead, if available.
unsigned long charCode;
// A system and implementation dependent numerical code identifying the unmodified value of the pressed key.
+ // Warning: This attribute is deprecated, you should use the field 'key' instead, if available.
unsigned long keyCode;
// A system and implementation dependent numeric code identifying the unmodified value of the pressed key; this is usually the same as keyCode.
+ // Warning: This attribute is deprecated, you should use the field 'key' instead, if available.
unsigned long which;
} EmscriptenKeyboardEvent;
@@ -376,7 +384,7 @@ extern EMSCRIPTEN_RESULT emscripten_lock_orientation(int allowedOrientations);
/*
* Allows the screen to turn again into any orientation.
*/
-extern EMSCRIPTEN_RESULT emscripten_unlock_orientation();
+extern EMSCRIPTEN_RESULT emscripten_unlock_orientation(void);
/*
* The event structure passed in the fullscreenchange event.
@@ -420,7 +428,7 @@ extern EMSCRIPTEN_RESULT emscripten_request_fullscreen(const char *target, int d
/*
* Returns back to windowed browsing mode.
*/
-extern EMSCRIPTEN_RESULT emscripten_exit_fullscreen();
+extern EMSCRIPTEN_RESULT emscripten_exit_fullscreen(void);
/*
* The event structure passed in the pointerlockchange event.
@@ -456,7 +464,7 @@ extern EMSCRIPTEN_RESULT emscripten_request_pointerlock(const char *target, int
/*
* Exits pointer lock state and restores the mouse cursor to be visible again.
*/
-extern EMSCRIPTEN_RESULT emscripten_exit_pointerlock();
+extern EMSCRIPTEN_RESULT emscripten_exit_pointerlock(void);
#define EMSCRIPTEN_VISIBILITY_HIDDEN 0
#define EMSCRIPTEN_VISIBILITY_VISIBLE 1
@@ -573,7 +581,7 @@ extern EMSCRIPTEN_RESULT emscripten_set_gamepaddisconnected_callback(void *userD
* Returns the number of gamepads connected to the system or EMSCRIPTEN_RESULT_NOT_SUPPORTED if the current browser does not support gamepads.
* Note: A gamepad does not show up as connected until a button on it is pressed.
*/
-extern int emscripten_get_num_gamepads();
+extern int emscripten_get_num_gamepads(void);
/*
* Returns a snapshot of the current gamepad state.
*/
diff --git a/tests/cases/aliases_fastcomp.ll b/tests/cases/aliases_fastcomp.ll
new file mode 100644
index 00000000..2b8746eb
--- /dev/null
+++ b/tests/cases/aliases_fastcomp.ll
@@ -0,0 +1,41 @@
+; ModuleID = 'tests/hello_world.bc'
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:128-n32-S128"
+target triple = "asmjs-unknown-emscripten"
+
+@.str = private unnamed_addr constant [18 x i8] c"hello, world! %d\0A\00", align 1 ; [#uses=1 type=[18 x i8]*]
+
+@othername = alias internal void (i32)* @doit
+@othername2 = alias internal void (i32)* @othername
+@othername3 = alias internal void (i32)* @othername2
+
+@value = global i32 17
+@value2 = alias i32* @value
+@value3 = alias i32* @value
+
+define internal void @doit(i32 %x) {
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), i32 %x) ; [#uses=0 type=i32]
+ ret void
+}
+
+define i32 @main() {
+entry:
+ %fp = ptrtoint void (i32)* @othername3 to i32
+ %fp1 = add i32 %fp, 0
+ %pf = inttoptr i32 %fp1 to void (i32)*
+ %x = load i32* @value3
+ call void (i32)* %pf(i32 %x)
+ %x1 = load i32* @value2
+ call void (i32)* @othername3(i32 %x1)
+ %x2 = load i32* @value
+ call void (i32)* @othername2(i32 %x2)
+ store i32 18, i32* @value
+ %x3 = load i32* @value
+ call void (i32)* @othername(i32 %x3)
+ store i32 19, i32* @value3
+ %x4 = load i32* @value3
+ call void (i32)* @doit(i32 %x4)
+ ret i32 1
+}
+
+declare i32 @printf(i8*, ...)
+
diff --git a/tests/cases/aliases_fastcomp.txt b/tests/cases/aliases_fastcomp.txt
new file mode 100644
index 00000000..ae30c63c
--- /dev/null
+++ b/tests/cases/aliases_fastcomp.txt
@@ -0,0 +1,5 @@
+hello, world! 17
+hello, world! 17
+hello, world! 17
+hello, world! 18
+hello, world! 19
diff --git a/tests/emscripten_log/emscripten_log.cpp b/tests/emscripten_log/emscripten_log.cpp
index 5973e94c..f4cc41db 100644
--- a/tests/emscripten_log/emscripten_log.cpp
+++ b/tests/emscripten_log/emscripten_log.cpp
@@ -5,10 +5,6 @@
#define STRINGIZE_HELPER(x) #x
#define STRINGIZE(x) STRINGIZE_HELPER(x)
-#ifndef REPORT_RESULT
-#define REPORT_RESULT int dummy
-#endif
-
int result = 1; // If 1, this test succeeded.
// A custom assert macro to test varargs routing to emscripten_log().
@@ -134,11 +130,10 @@ void __attribute__((noinline)) Foo() // Arbitrary function signature to add some
int main()
{
Foo<int>();
-#ifndef RUN_FROM_JS_SHELL
+#ifdef REPORT_RESULT
REPORT_RESULT();
- return 0;
-#else
+#endif
if (result)
printf("Success!\n");
-#endif
+ return 0;
}
diff --git a/tests/fuzz/csmith_driver.py b/tests/fuzz/csmith_driver.py
index 238acb9a..09f1c249 100755
--- a/tests/fuzz/csmith_driver.py
+++ b/tests/fuzz/csmith_driver.py
@@ -121,7 +121,7 @@ while 1:
print "EMSCRIPTEN BUG"
notes['embug'] += 1
fails += 1
- shutil.copyfile(fullname, 'newfail%d%s' % (fails, suffix))
+ shutil.copyfile(fullname, 'newfail%d%s%s' % (fails, opts.replace('-', '_'), suffix))
continue
#if not ok:
# try: # finally, try with safe heap. if that is triggered, this is nonportable code almost certainly
@@ -138,7 +138,7 @@ while 1:
# This is ok. Try in secondary JS engine too
if opts != '-O0' and engine2 and normal:
try:
- js2 = shared.run_js(filename + '.js', stderr=PIPE, engine=engine2, full_output=True, check_timeout=True)
+ js2 = shared.run_js(filename + '.js', stderr=PIPE, engine=engine2 + ['-w'], full_output=True, check_timeout=True)
except:
print 'failed to run in secondary', js2
break
diff --git a/tests/mem_init.cpp b/tests/mem_init.cpp
new file mode 100644
index 00000000..e642bfc9
--- /dev/null
+++ b/tests/mem_init.cpp
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <emscripten.h>
+
+extern "C" {
+
+int noted = 0;
+
+void EMSCRIPTEN_KEEPALIVE note(int n) {
+ EM_ASM_({ Module.print([$0, $1]) }, n, noted);
+ noted = noted | n;
+ EM_ASM_({ Module.print(['noted is now', $0]) }, noted);
+ if (noted == 3) {
+ int result = noted;
+ REPORT_RESULT();
+ }
+}
+
+}
+
+int main() {
+ EM_ASM( myJSCallback() ); // calls a global JS func
+ return 0;
+}
+
diff --git a/tests/openal_playback.cpp b/tests/openal_playback.cpp
index 880b6906..46c4f8a3 100644
--- a/tests/openal_playback.cpp
+++ b/tests/openal_playback.cpp
@@ -25,7 +25,7 @@ void playSource(void* arg)
alGetSourcei(source, AL_SOURCE_STATE, &state);
assert(state == AL_STOPPED);
-#ifdef __EMSCRIPTEN__
+#ifdef REPORT_RESULT
int result = 1;
REPORT_RESULT();
#endif
diff --git a/tests/runner.py b/tests/runner.py
index c13a16eb..26912f25 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -779,14 +779,11 @@ A recommended order is:
(the main test suite)
other - tests separate from the main suite
browser - runs pages in a web browser
+ interactive - runs interactive browser tests that need human verification, and could not be automated
sockets - runs websocket networking tests
benchmark - run before and after each set of changes before pushing to
master, verify no regressions
-There are also commands to run specific subsets of the test suite:
-
- browser.audio - runs audio tests in a web browser (requires human verification)
-
To run one of those parts, do something like
python tests/runner.py sanity
diff --git a/tests/sdl_wm_togglefullscreen.c b/tests/sdl_wm_togglefullscreen.c
new file mode 100644
index 00000000..c76ced76
--- /dev/null
+++ b/tests/sdl_wm_togglefullscreen.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+#include <assert.h>
+#include <emscripten.h>
+
+int result = 1;
+
+SDL_Surface *screen = 0;
+
+int inFullscreen = 0;
+
+int wasFullscreen = 0;
+
+void render() {
+ int width, height, isfs;
+ emscripten_get_canvas_size(&width, &height, &isfs);
+ SDL_Rect rect = { 0, 0, width, height };
+ SDL_FillRect(screen, &rect, 0xff00ffff);
+}
+
+void mainloop() {
+ render();
+ SDL_Event event;
+ int isInFullscreen = EM_ASM_INT_V(return !!(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement));
+ if (isInFullscreen && !wasFullscreen) {
+ printf("Successfully transitioned to fullscreen mode!\n");
+ wasFullscreen = isInFullscreen;
+ }
+
+ if (wasFullscreen && !isInFullscreen) {
+ printf("Exited fullscreen. Test succeeded.\n");
+ result = 1;
+#ifdef REPORT_RESULT
+ REPORT_RESULT();
+#endif
+ wasFullscreen = isInFullscreen;
+ emscripten_cancel_main_loop();
+ return;
+ }
+
+ int haveEvent = SDL_PollEvent(&event);
+ if (haveEvent) {
+ switch(event.type) {
+ case SDL_MOUSEBUTTONDOWN: {
+ SDL_WM_ToggleFullScreen(screen);
+ inFullscreen = 1 - inFullscreen;
+ if (inFullscreen == 0) {
+ result = wasFullscreen;
+ if (result) {
+ printf("Exited fullscreen. Test succeeded.\n");
+ } else {
+ printf("Exited fullscreen. Test failed, fullscreen transition did not happen!\n");
+ }
+#ifdef REPORT_RESULT
+ REPORT_RESULT();
+#endif
+ emscripten_cancel_main_loop();
+ return;
+ } else {
+ printf("Entering fullscreen...\n");
+ }
+ break;
+ }
+ }
+ }
+}
+
+int main() {
+ SDL_Init(SDL_INIT_VIDEO);
+ screen = SDL_SetVideoMode(600, 450, 32, SDL_HWSURFACE);
+
+ printf("You should see a yellow canvas.\n");
+ printf("Click on the canvas to enter full screen, and then click on the canvas again to finish the test.\n");
+ printf("When in full screen, you should see the whole screen filled yellow, and after exiting, the yellow canvas should be restored in the window.\n");
+ emscripten_set_main_loop(mainloop, 0, 0);
+ return 0;
+}
diff --git a/tests/test_browser.py b/tests/test_browser.py
index dfb1ef69..f0343669 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -51,23 +51,6 @@ def test_chunked_synchronous_xhr_server(support_byte_ranges, chunkSize, data, ch
httpd.handle_request()
class browser(BrowserCore):
- @staticmethod
- def audio():
- print
- print 'Running the browser audio tests. Make sure to listen to hear the correct results!'
- print
- audio_test_cases = [
- 'test_sdl_audio',
- 'test_sdl_audio_mix_channels',
- 'test_sdl_audio_mix',
- 'test_sdl_audio_quickload',
- 'test_sdl_audio_beeps',
- 'test_openal_playback',
- 'test_openal_buffers',
- 'test_freealut'
- ]
- return unittest.TestSuite(map(browser, audio_test_cases))
-
@classmethod
def setUpClass(self):
super(browser, self).setUpClass()
@@ -1130,47 +1113,6 @@ keydown(100);keyup(100); // trigger the end
''')
self.btest('sdl_pumpevents.c', expected='7', args=['--pre-js', 'pre.js'])
- def test_sdl_audio(self):
- shutil.copyfile(path_from_root('tests', 'sounds', 'alarmvictory_1.ogg'), os.path.join(self.get_dir(), 'sound.ogg'))
- shutil.copyfile(path_from_root('tests', 'sounds', 'alarmcreatemiltaryfoot_1.wav'), os.path.join(self.get_dir(), 'sound2.wav'))
- shutil.copyfile(path_from_root('tests', 'sounds', 'noise.ogg'), os.path.join(self.get_dir(), 'noise.ogg'))
- shutil.copyfile(path_from_root('tests', 'sounds', 'the_entertainer.ogg'), os.path.join(self.get_dir(), 'the_entertainer.ogg'))
- open(os.path.join(self.get_dir(), 'bad.ogg'), 'w').write('I claim to be audio, but am lying')
- open(os.path.join(self.get_dir(), 'sdl_audio.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio.c')).read()))
-
- # use closure to check for a possible bug with closure minifying away newer Audio() attributes
- Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio.c'), '--preload-file', 'sound.ogg', '--preload-file', 'sound2.wav', '--embed-file', 'the_entertainer.ogg', '--preload-file', 'noise.ogg', '--preload-file', 'bad.ogg', '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play", "_play2"]']).communicate()
- self.run_browser('page.html', '', '/report_result?1')
-
- def test_sdl_audio_mix_channels(self):
- shutil.copyfile(path_from_root('tests', 'sounds', 'noise.ogg'), os.path.join(self.get_dir(), 'sound.ogg'))
- open(os.path.join(self.get_dir(), 'sdl_audio_mix_channels.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_mix_channels.c')).read()))
-
- Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_mix_channels.c'), '--preload-file', 'sound.ogg', '-o', 'page.html']).communicate()
- self.run_browser('page.html', '', '/report_result?1')
-
- def test_sdl_audio_mix(self):
- shutil.copyfile(path_from_root('tests', 'sounds', 'pluck.ogg'), os.path.join(self.get_dir(), 'sound.ogg'))
- shutil.copyfile(path_from_root('tests', 'sounds', 'the_entertainer.ogg'), os.path.join(self.get_dir(), 'music.ogg'))
- shutil.copyfile(path_from_root('tests', 'sounds', 'noise.ogg'), os.path.join(self.get_dir(), 'noise.ogg'))
- open(os.path.join(self.get_dir(), 'sdl_audio_mix.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_mix.c')).read()))
-
- Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_mix.c'), '--preload-file', 'sound.ogg', '--preload-file', 'music.ogg', '--preload-file', 'noise.ogg', '-o', 'page.html']).communicate()
- self.run_browser('page.html', '', '/report_result?1')
-
- def test_sdl_audio_quickload(self):
- open(os.path.join(self.get_dir(), 'sdl_audio_quickload.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_quickload.c')).read()))
-
- Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_quickload.c'), '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play"]']).communicate()
- self.run_browser('page.html', '', '/report_result?1')
-
- def test_sdl_audio_beeps(self):
- open(os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_beep.cpp')).read()))
-
- # use closure to check for a possible bug with closure minifying away newer Audio() attributes
- Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), '-s', 'DISABLE_EXCEPTION_CATCHING=0', '-o', 'page.html']).communicate()
- self.run_browser('page.html', '', '/report_result?1')
-
def test_sdl_canvas_size(self):
self.btest('sdl_canvas_size.c', reference='screenshot-gray-purple.png', reference_slack=1,
args=['-O2', '--minify', '0', '--shell-file', path_from_root('tests', 'sdl_canvas_size.html'), '--preload-file', path_from_root('tests', 'screenshot.png') + '@/', '-s', 'LEGACY_GL_EMULATION=1'],
@@ -1236,17 +1178,6 @@ keydown(100);keyup(100); // trigger the end
args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
- def test_openal_playback(self):
- shutil.copyfile(path_from_root('tests', 'sounds', 'audio.wav'), os.path.join(self.get_dir(), 'audio.wav'))
- open(os.path.join(self.get_dir(), 'openal_playback.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'openal_playback.cpp')).read()))
-
- Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'openal_playback.cpp'), '--preload-file', 'audio.wav', '-o', 'page.html']).communicate()
- self.run_browser('page.html', '', '/report_result?1')
-
- def test_openal_buffers(self):
- shutil.copyfile(path_from_root('tests', 'sounds', 'the_entertainer.wav'), os.path.join(self.get_dir(), 'the_entertainer.wav'))
- self.btest('openal_buffers.c', '0', args=['--preload-file', 'the_entertainer.wav'],)
-
def test_glfw(self):
self.btest('glfw.c', '1', args=['-s', 'LEGACY_GL_EMULATION=1'])
@@ -1262,19 +1193,6 @@ keydown(100);keyup(100); // trigger the end
Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'test_egl_width_height.c'), '-o', 'page.html']).communicate()
self.run_browser('page.html', 'Should print "(300, 150)" -- the size of the canvas in pixels', '/report_result?1')
- def get_freealut_library(self):
- if WINDOWS and Building.which('cmake'):
- return self.get_library('freealut', os.path.join('hello_world.bc'), configure=['cmake', '.'], configure_args=['-DBUILD_TESTS=ON'])
- else:
- return self.get_library('freealut', os.path.join('examples', '.libs', 'hello_world.bc'), make_args=['EXEEXT=.bc'])
-
- def test_freealut(self):
- programs = self.get_freealut_library()
- for program in programs:
- assert os.path.exists(program)
- Popen([PYTHON, EMCC, '-O2', program, '-o', 'page.html']).communicate()
- self.run_browser('page.html', 'You should hear "Hello World!"')
-
def test_worker(self):
# Test running in a web worker
open('file.dat', 'w').write('data for worker')
@@ -1752,6 +1670,23 @@ void *getBindBuffer() {
for mem in [0, 1]:
self.btest('pre_run_deps.cpp', expected='10', args=['--pre-js', 'pre.js', '--memory-init-file', str(mem)])
+ def test_mem_init(self):
+ open(os.path.join(self.get_dir(), 'pre.js'), 'w').write('''
+ function myJSCallback() { // called from main()
+ Module._note(1);
+ }
+ Module.preRun = function() {
+ addOnPreMain(function() {
+ Module._note(2);
+ });
+ };
+ ''')
+ open(os.path.join(self.get_dir(), 'post.js'), 'w').write('''
+ Module._note(4); // this happens too early! and is overwritten when the mem init arrives
+ ''')
+
+ self.btest('mem_init.cpp', expected='3', args=['--pre-js', 'pre.js', '--post-js', 'post.js', '--memory-init-file', '1'])
+
def test_worker_api(self):
Popen([PYTHON, EMCC, path_from_root('tests', 'worker_api_worker.cpp'), '-o', 'worker.js', '-s', 'BUILD_AS_WORKER=1', '-s', 'EXPORTED_FUNCTIONS=["_one"]']).communicate()
self.btest('worker_api_main.cpp', expected='566')
@@ -1851,10 +1786,14 @@ Module["preRun"].push(function () {
self.btest('doublestart.c', args=['--pre-js', 'pre.js', '-o', 'test.html'], expected='1')
def test_html5(self):
- self.btest(path_from_root('tests', 'test_html5.c'), expected='0')
-
- def test_html5_fullscreen(self):
- self.btest(path_from_root('tests', 'test_html5_fullscreen.c'), expected='0')
+ for opts in [[], ['-O2', '-g1', '--closure', '1']]:
+ print opts
+ self.btest(path_from_root('tests', 'test_html5.c'), args=opts, expected='0')
+
+ def test_html5_mouse(self):
+ for opts in [[], ['-O2', '-g1', '--closure', '1']]:
+ print opts
+ self.btest(path_from_root('tests', 'test_html5_mouse.c'), args=opts + ['-DAUTOMATE_SUCCESS=1'], expected='0')
def test_codemods(self):
for opt_level in [0, 2]:
diff --git a/tests/test_core.py b/tests/test_core.py
index 5c34d47e..a954e312 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -1938,7 +1938,7 @@ def process(filename):
def test_emscripten_get_now(self):
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2')
- if self.run_name == 'o2':
+ if self.run_name == 'slow2asm':
self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage
self.do_run(open(path_from_root('tests', 'emscripten_get_now.cpp')).read(), 'Timer resolution is good.')
diff --git a/tests/test_html5_fullscreen.c b/tests/test_html5_fullscreen.c
index 9a284b09..54b834bd 100644
--- a/tests/test_html5_fullscreen.c
+++ b/tests/test_html5_fullscreen.c
@@ -3,7 +3,6 @@
#include <string.h>
#include <emscripten/html5.h>
-#ifdef REPORT_RESULT
void report_result(int result)
{
if (result == 0) {
@@ -11,9 +10,10 @@ void report_result(int result)
} else {
printf("Test failed!\n");
}
+#ifdef REPORT_RESULT
REPORT_RESULT();
-}
#endif
+}
static inline const char *emscripten_event_type_to_string(int eventType) {
const char *events[] = { "(invalid)", "(none)", "keypress", "keydown", "keyup", "click", "mousedown", "mouseup", "dblclick", "mousemove", "wheel", "resize",
@@ -90,6 +90,11 @@ EM_BOOL fullscreenchange_callback(int eventType, const EmscriptenFullscreenChang
return 0;
}
+EM_BOOL mouse_callback(int eventType, const EmscriptenMouseEvent *e, void *userData)
+{
+ return 0;
+}
+
int main()
{
EMSCRIPTEN_RESULT ret = emscripten_set_keypress_callback(0, 0, 1, key_callback);
@@ -98,7 +103,21 @@ int main()
ret = emscripten_set_fullscreenchange_callback(0, 0, 1, fullscreenchange_callback);
TEST_RESULT(emscripten_set_fullscreenchange_callback);
+ // For Internet Explorer, fullscreen and pointer lock requests cannot be run
+ // from inside keyboard event handlers. Therefore we must register a callback to
+ // mouse events (any other than mousedown) to activate deferred fullscreen/pointerlock
+ // requests to occur for IE. The callback itself can be a no-op.
+ ret = emscripten_set_click_callback(0, 0, 1, mouse_callback);
+ TEST_RESULT(emscripten_set_click_callback);
+ ret = emscripten_set_mousedown_callback(0, 0, 1, mouse_callback);
+ TEST_RESULT(emscripten_set_mousedown_callback);
+ ret = emscripten_set_mouseup_callback(0, 0, 1, mouse_callback);
+ TEST_RESULT(emscripten_set_mouseup_callback);
+ ret = emscripten_set_dblclick_callback(0, 0, 1, mouse_callback);
+ TEST_RESULT(emscripten_set_dblclick_callback);
+
printf("To finish this test, press f to enter fullscreen mode, and then exit it.\n");
+ printf("On IE, press a mouse key over the canvas after pressing f to activate the fullscreen request event.\n");
/* For the events to function, one must either call emscripten_set_main_loop or enable Module.noExitRuntime by some other means.
Otherwise the application will exit after leaving main(), and the atexit handlers will clean up all event hooks (by design). */
diff --git a/tests/test_html5_mouse.c b/tests/test_html5_mouse.c
new file mode 100644
index 00000000..f087a62b
--- /dev/null
+++ b/tests/test_html5_mouse.c
@@ -0,0 +1,159 @@
+#include <stdio.h>
+#include <emscripten.h>
+#include <string.h>
+#include <emscripten/html5.h>
+
+void report_result(int result)
+{
+ if (result == 0) {
+ printf("Test successful!\n");
+ } else {
+ printf("Test failed!\n");
+ }
+#ifdef REPORT_RESULT
+ REPORT_RESULT();
+#endif
+}
+
+static inline const char *emscripten_event_type_to_string(int eventType) {
+ const char *events[] = { "(invalid)", "(none)", "keypress", "keydown", "keyup", "click", "mousedown", "mouseup", "dblclick", "mousemove", "wheel", "resize",
+ "scroll", "blur", "focus", "focusin", "focusout", "deviceorientation", "devicemotion", "orientationchange", "fullscreenchange", "pointerlockchange",
+ "visibilitychange", "touchstart", "touchend", "touchmove", "touchcancel", "gamepadconnected", "gamepaddisconnected", "beforeunload",
+ "batterychargingchange", "batterylevelchange", "webglcontextlost", "webglcontextrestored", "(invalid)" };
+ ++eventType;
+ if (eventType < 0) eventType = 0;
+ if (eventType >= sizeof(events)/sizeof(events[0])) eventType = sizeof(events)/sizeof(events[0])-1;
+ return events[eventType];
+}
+
+const char *emscripten_result_to_string(EMSCRIPTEN_RESULT result) {
+ if (result == EMSCRIPTEN_RESULT_SUCCESS) return "EMSCRIPTEN_RESULT_SUCCESS";
+ if (result == EMSCRIPTEN_RESULT_DEFERRED) return "EMSCRIPTEN_RESULT_DEFERRED";
+ if (result == EMSCRIPTEN_RESULT_NOT_SUPPORTED) return "EMSCRIPTEN_RESULT_NOT_SUPPORTED";
+ if (result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED) return "EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED";
+ if (result == EMSCRIPTEN_RESULT_INVALID_TARGET) return "EMSCRIPTEN_RESULT_INVALID_TARGET";
+ if (result == EMSCRIPTEN_RESULT_UNKNOWN_TARGET) return "EMSCRIPTEN_RESULT_UNKNOWN_TARGET";
+ if (result == EMSCRIPTEN_RESULT_INVALID_PARAM) return "EMSCRIPTEN_RESULT_INVALID_PARAM";
+ if (result == EMSCRIPTEN_RESULT_FAILED) return "EMSCRIPTEN_RESULT_FAILED";
+ if (result == EMSCRIPTEN_RESULT_NO_DATA) return "EMSCRIPTEN_RESULT_NO_DATA";
+ return "Unknown EMSCRIPTEN_RESULT!";
+}
+
+#define TEST_RESULT(x) if (ret != EMSCRIPTEN_RESULT_SUCCESS) printf("%s returned %s.\n", #x, emscripten_result_to_string(ret));
+
+int gotClick = 0;
+int gotMouseDown = 0;
+int gotMouseUp = 0;
+int gotDblClick = 0;
+int gotMouseMove = 0;
+int gotWheel = 0;
+
+void instruction()
+{
+ if (!gotClick) { printf("Please click on the canvas.\n"); return; }
+ if (!gotMouseDown) { printf("Please click on the canvas.\n"); return; }
+ if (!gotMouseUp) { printf("Please click on the canvas.\n"); return; }
+ if (!gotDblClick) { printf("Please double-click on the canvas.\n"); return; }
+ if (!gotMouseMove) { printf("Please move the mouse on the canvas.\n"); return; }
+ if (!gotWheel) { printf("Please scroll the mouse wheel.\n"); return; }
+
+ if (gotClick && gotMouseDown && gotMouseUp && gotDblClick && gotMouseMove && gotWheel) report_result(0);
+}
+
+EM_BOOL mouse_callback(int eventType, const EmscriptenMouseEvent *e, void *userData)
+{
+ printf("%s, screen: (%ld,%ld), client: (%ld,%ld),%s%s%s%s button: %hu, buttons: %hu, movement: (%ld,%ld), canvas: (%ld,%ld)\n",
+ emscripten_event_type_to_string(eventType), e->screenX, e->screenY, e->clientX, e->clientY,
+ e->ctrlKey ? " CTRL" : "", e->shiftKey ? " SHIFT" : "", e->altKey ? " ALT" : "", e->metaKey ? " META" : "",
+ e->button, e->buttons, e->movementX, e->movementY, e->canvasX, e->canvasY);
+
+ if (e->screenX != 0 && e->screenY != 0 && e->clientX != 0 && e->clientY != 0 && e->canvasX != 0 && e->canvasY != 0)
+ {
+ if (e->buttons != 0)
+ {
+ if (eventType == EMSCRIPTEN_EVENT_CLICK) gotClick = 1;
+ if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN) gotMouseDown = 1;
+ if (eventType == EMSCRIPTEN_EVENT_DBLCLICK) gotDblClick = 1;
+ }
+ if (eventType == EMSCRIPTEN_EVENT_MOUSEUP) gotMouseUp = 1;
+ if (eventType == EMSCRIPTEN_EVENT_MOUSEMOVE && (e->movementX != 0 || e->movementY != 0)) gotMouseMove = 1;
+ }
+
+ if (eventType == EMSCRIPTEN_EVENT_CLICK && e->screenX == -500000)
+ {
+ printf("ERROR! Received an event to a callback that should have been unregistered!\n");
+ gotClick = 0;
+ report_result(1);
+ }
+
+ instruction();
+ return 0;
+}
+
+EM_BOOL wheel_callback(int eventType, const EmscriptenWheelEvent *e, void *userData)
+{
+ printf("%s, screen: (%ld,%ld), client: (%ld,%ld),%s%s%s%s button: %hu, buttons: %hu, canvas: (%ld,%ld), delta:(%g,%g,%g), deltaMode:%lu\n",
+ emscripten_event_type_to_string(eventType), e->mouse.screenX, e->mouse.screenY, e->mouse.clientX, e->mouse.clientY,
+ e->mouse.ctrlKey ? " CTRL" : "", e->mouse.shiftKey ? " SHIFT" : "", e->mouse.altKey ? " ALT" : "", e->mouse.metaKey ? " META" : "",
+ e->mouse.button, e->mouse.buttons, e->mouse.canvasX, e->mouse.canvasY,
+ (float)e->deltaX, (float)e->deltaY, (float)e->deltaZ, e->deltaMode);
+
+ if (e->deltaY > 0.f || e->deltaY < 0.f)
+ gotWheel = 1;
+
+ instruction();
+ return 0;
+}
+
+int main()
+{
+ EMSCRIPTEN_RESULT ret = emscripten_set_click_callback(0, 0, 1, mouse_callback);
+ TEST_RESULT(emscripten_set_click_callback);
+ ret = emscripten_set_mousedown_callback(0, 0, 1, mouse_callback);
+ TEST_RESULT(emscripten_set_mousedown_callback);
+ ret = emscripten_set_mouseup_callback(0, 0, 1, mouse_callback);
+ TEST_RESULT(emscripten_set_mouseup_callback);
+ ret = emscripten_set_dblclick_callback(0, 0, 1, mouse_callback);
+ TEST_RESULT(emscripten_set_dblclick_callback);
+ ret = emscripten_set_mousemove_callback(0, 0, 1, mouse_callback);
+ TEST_RESULT(emscripten_set_mousemove_callback);
+
+ ret = emscripten_set_wheel_callback(0, 0, 1, wheel_callback);
+ TEST_RESULT(emscripten_set_wheel_callback);
+
+#ifdef AUTOMATE_SUCCESS
+ EM_ASM(
+ function sendEvent(type, data) {
+ var event = document.createEvent('Event');
+ event.initEvent(type, true, true);
+ for(var d in data) event[d] = data[d];
+ window.dispatchEvent(event);
+ }
+ sendEvent('click', { screenX: 1, screenY: 1, clientX: 1, clientY: 1, button: 0, buttons: 1 });
+ );
+ // Test that unregistering a callback works. Clicks should no longer be received.
+ ret = emscripten_set_click_callback(0, 0, 1, 0);
+ TEST_RESULT(emscripten_set_click_callback);
+
+ EM_ASM(
+ function sendEvent(type, data) {
+ var event = document.createEvent('Event');
+ event.initEvent(type, true, true);
+ for(var d in data) event[d] = data[d];
+ window.dispatchEvent(event);
+ }
+ sendEvent('click', { screenX: -500000, screenY: -500000, clientX: -500000, clientY: -500000, button: 0, buttons: 1 }); // Send a dummy event that should not be received.
+ sendEvent('mousedown', { screenX: 1, screenY: 1, clientX: 1, clientY: 1, button: 0, buttons: 1 });
+ sendEvent('mouseup', { screenX: 1, screenY: 1, clientX: 1, clientY: 1, button: 0, buttons: 0 });
+ sendEvent('dblclick', { screenX: 1, screenY: 1, clientX: 1, clientY: 1, button: 0, buttons: 1 });
+ sendEvent('mousemove', { screenX: 1, screenY: 1, clientX: 1, clientY: 1, button: 0, buttons: 0, movementX: 1, movementY: 1 });
+ sendEvent('wheel', { screenX: 1, screenY: 1, clientX: 1, clientY: 1, button: 0, buttons: 0, deltaX: 1, deltaY: 1, deltaZ: 1, deltaMode: 1 });
+ sendEvent('mousewheel', { screenX: 1, screenY: 1, clientX: 1, clientY: 1, button: 0, buttons: 0, wheelDeltaX: 1, wheelDeltaY: 1 });
+ );
+#endif
+
+ /* For the events to function, one must either call emscripten_set_main_loop or enable Module.noExitRuntime by some other means.
+ Otherwise the application will exit after leaving main(), and the atexit handlers will clean up all event hooks (by design). */
+ EM_ASM(Module['noExitRuntime'] = true);
+ return 0;
+}
diff --git a/tests/test_interactive.py b/tests/test_interactive.py
new file mode 100644
index 00000000..4ac52f55
--- /dev/null
+++ b/tests/test_interactive.py
@@ -0,0 +1,94 @@
+import BaseHTTPServer, multiprocessing, os, shutil, subprocess, unittest, zlib, webbrowser, time, shlex
+from runner import BrowserCore, path_from_root, nonfastcomp
+from tools.shared import *
+
+# User can specify an environment variable EMSCRIPTEN_BROWSER to force the browser test suite to
+# run using another browser command line than the default system browser.
+emscripten_browser = os.environ.get('EMSCRIPTEN_BROWSER')
+if emscripten_browser:
+ cmd = shlex.split(emscripten_browser)
+ def run_in_other_browser(url):
+ Popen(cmd + [url])
+ webbrowser.open_new = run_in_other_browser
+
+class interactive(BrowserCore):
+ @classmethod
+ def setUpClass(self):
+ super(interactive, self).setUpClass()
+ print
+ print 'Running the browser tests. Make sure the browser allows popups from localhost.'
+ print
+
+ def test_html5_fullscreen(self):
+ self.btest(path_from_root('tests', 'test_html5_fullscreen.c'), expected='0')
+
+ def test_html5_mouse(self):
+ self.btest(path_from_root('tests', 'test_html5_mouse.c'), expected='0')
+
+ def test_sdl_wm_togglefullscreen(self):
+ self.btest('sdl_wm_togglefullscreen.c', expected='1', args=['-s', 'NO_EXIT_RUNTIME=1'])
+
+ def test_sdl_audio(self):
+ shutil.copyfile(path_from_root('tests', 'sounds', 'alarmvictory_1.ogg'), os.path.join(self.get_dir(), 'sound.ogg'))
+ shutil.copyfile(path_from_root('tests', 'sounds', 'alarmcreatemiltaryfoot_1.wav'), os.path.join(self.get_dir(), 'sound2.wav'))
+ shutil.copyfile(path_from_root('tests', 'sounds', 'noise.ogg'), os.path.join(self.get_dir(), 'noise.ogg'))
+ shutil.copyfile(path_from_root('tests', 'sounds', 'the_entertainer.ogg'), os.path.join(self.get_dir(), 'the_entertainer.ogg'))
+ open(os.path.join(self.get_dir(), 'bad.ogg'), 'w').write('I claim to be audio, but am lying')
+ open(os.path.join(self.get_dir(), 'sdl_audio.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio.c')).read()))
+
+ # use closure to check for a possible bug with closure minifying away newer Audio() attributes
+ Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio.c'), '--preload-file', 'sound.ogg', '--preload-file', 'sound2.wav', '--embed-file', 'the_entertainer.ogg', '--preload-file', 'noise.ogg', '--preload-file', 'bad.ogg', '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play", "_play2"]']).communicate()
+ self.run_browser('page.html', '', '/report_result?1')
+
+ def test_sdl_audio_mix_channels(self):
+ shutil.copyfile(path_from_root('tests', 'sounds', 'noise.ogg'), os.path.join(self.get_dir(), 'sound.ogg'))
+ open(os.path.join(self.get_dir(), 'sdl_audio_mix_channels.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_mix_channels.c')).read()))
+
+ Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_mix_channels.c'), '--preload-file', 'sound.ogg', '-o', 'page.html']).communicate()
+ self.run_browser('page.html', '', '/report_result?1')
+
+ def test_sdl_audio_mix(self):
+ shutil.copyfile(path_from_root('tests', 'sounds', 'pluck.ogg'), os.path.join(self.get_dir(), 'sound.ogg'))
+ shutil.copyfile(path_from_root('tests', 'sounds', 'the_entertainer.ogg'), os.path.join(self.get_dir(), 'music.ogg'))
+ shutil.copyfile(path_from_root('tests', 'sounds', 'noise.ogg'), os.path.join(self.get_dir(), 'noise.ogg'))
+ open(os.path.join(self.get_dir(), 'sdl_audio_mix.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_mix.c')).read()))
+
+ Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_mix.c'), '--preload-file', 'sound.ogg', '--preload-file', 'music.ogg', '--preload-file', 'noise.ogg', '-o', 'page.html']).communicate()
+ self.run_browser('page.html', '', '/report_result?1')
+
+ def test_sdl_audio_quickload(self):
+ open(os.path.join(self.get_dir(), 'sdl_audio_quickload.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_quickload.c')).read()))
+
+ Popen([PYTHON, EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_quickload.c'), '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play"]']).communicate()
+ self.run_browser('page.html', '', '/report_result?1')
+
+ def test_sdl_audio_beeps(self):
+ open(os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_beep.cpp')).read()))
+
+ # use closure to check for a possible bug with closure minifying away newer Audio() attributes
+ Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), '-s', 'DISABLE_EXCEPTION_CATCHING=0', '-o', 'page.html']).communicate()
+ self.run_browser('page.html', '', '/report_result?1')
+
+ def test_openal_playback(self):
+ shutil.copyfile(path_from_root('tests', 'sounds', 'audio.wav'), os.path.join(self.get_dir(), 'audio.wav'))
+ open(os.path.join(self.get_dir(), 'openal_playback.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'openal_playback.cpp')).read()))
+
+ Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'openal_playback.cpp'), '--preload-file', 'audio.wav', '-o', 'page.html']).communicate()
+ self.run_browser('page.html', '', '/report_result?1')
+
+ def test_openal_buffers(self):
+ shutil.copyfile(path_from_root('tests', 'sounds', 'the_entertainer.wav'), os.path.join(self.get_dir(), 'the_entertainer.wav'))
+ self.btest('openal_buffers.c', '0', args=['--preload-file', 'the_entertainer.wav'],)
+
+ def get_freealut_library(self):
+ if WINDOWS and Building.which('cmake'):
+ return self.get_library('freealut', os.path.join('hello_world.bc'), configure=['cmake', '.'], configure_args=['-DBUILD_TESTS=ON'])
+ else:
+ return self.get_library('freealut', os.path.join('examples', '.libs', 'hello_world.bc'), make_args=['EXEEXT=.bc'])
+
+ def test_freealut(self):
+ programs = self.get_freealut_library()
+ for program in programs:
+ assert os.path.exists(program)
+ Popen([PYTHON, EMCC, '-O2', program, '-o', 'page.html']).communicate()
+ self.run_browser('page.html', 'You should hear "Hello World!"')
diff --git a/tests/test_other.py b/tests/test_other.py
index 9e9c9bef..7200b9fd 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -114,8 +114,6 @@ Options that are modified or new in %s include:
os.chdir(self.get_dir())
self.clear()
- # dlmalloc. dlmalloc is special in that it is the only part of libc that is (1) hard to write well, and
- # very speed-sensitive. So we do not implement it in JS in library.js, instead we compile it from source
for source, has_malloc in [('hello_world' + suffix, False), ('hello_malloc.cpp', True)]:
print source, has_malloc
self.clear()
@@ -193,6 +191,7 @@ Options that are modified or new in %s include:
(['-O2', '-g1'], lambda generated: 'var b = 0' in generated and not 'function _main' in generated, 'compress is cancelled by -g1'),
(['-O2', '-g2'], lambda generated: ('var b = 0' in generated or 'var i1 = 0' in generated) and 'function _main' in generated, 'minify is cancelled by -g2'),
(['-O2', '-g3'], lambda generated: 'var b=0' not in generated and 'var b = 0' not in generated and 'function _main' in generated, 'registerize is cancelled by -g3'),
+ (['-O2', '-profiling'], lambda generated: ('var b = 0' in generated or 'var i1 = 0' in generated) and 'function _main' in generated, 'similar to -g2'),
#(['-O2', '-g4'], lambda generated: 'var b=0' not in generated and 'var b = 0' not in generated and 'function _main' in generated, 'same as -g3 for now'),
(['-s', 'INLINING_LIMIT=0'], lambda generated: 'function _dump' in generated, 'no inlining without opts'),
(['-s', 'USE_TYPED_ARRAYS=0'], lambda generated: 'new Int32Array' not in generated, 'disable typed arrays'),
@@ -2106,6 +2105,7 @@ done.
EM_ASM(Module.print(demangle('__Z5multiwahtjmxyz')));
EM_ASM(Module.print(demangle('__Z1aA32_iPA5_c')));
EM_ASM(Module.print(demangle('__ZN21FWakaGLXFleeflsMarfooC2EjjjPKvbjj')));
+ EM_ASM(Module.print(demangle('__ZN5wakaw2Cm10RasterBaseINS_6watwat9PolocatorEE8merbine1INS4_2OREEEvPKjj'))); // we get this wrong, but at least emit a '?'
one(17);
return 0;
}
@@ -2129,6 +2129,7 @@ parseword(char*&, int, int&)
multi(wchar_t, signed char, unsigned char, unsigned short, unsigned int, unsigned long, long long, unsigned long long, ...)
a(int [32], char [5]*)
FWakaGLXFleeflsMarfoo::FWakaGLXFleeflsMarfoo(unsigned int, unsigned int, unsigned int, void*, bool, unsigned int, unsigned int)
+void wakaw::Cm::RasterBase<wakaw::watwat::Polocator?>(unsigned int*, unsigned int)
''', output)
# test for multiple functions in one stack trace
assert 'one(int)' in output
@@ -2563,3 +2564,14 @@ int main()
p.communicate()
assert p.returncode == 0, 'LLVM tests must pass with exit code 0'
+ def test_odin_validation(self):
+ Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '-O1'], stdout=PIPE, stderr=PIPE).communicate()
+ output = run_js('a.out.js', stderr=PIPE, full_output=True, engine=SPIDERMONKEY_ENGINE)
+ assert 'asm.js' in output, 'spidermonkey should mention asm.js compilation: ' + output
+
+ def test_bad_triple(self):
+ Popen([CLANG, path_from_root('tests', 'hello_world.c'), '-c', '-emit-llvm', '-o', 'a.bc'], stdout=PIPE, stderr=PIPE).communicate()
+ out, err = Popen([PYTHON, EMCC, 'a.bc'], stdout=PIPE, stderr=PIPE).communicate()
+ assert 'warning' in err, err
+ assert 'incorrect target triple' in err, err
+
diff --git a/tools/file_packager.py b/tools/file_packager.py
index 12cc5475..0ab68511 100644
--- a/tools/file_packager.py
+++ b/tools/file_packager.py
@@ -113,7 +113,7 @@ for arg in sys.argv[2:]:
try:
from shared import CRUNCH
except Exception, e:
- print >> sys.stderr, 'count not import CRUNCH (make sure it is defined properly in ~/.emscripten)'
+ print >> sys.stderr, 'could not import CRUNCH (make sure it is defined properly in ~/.emscripten)'
raise e
crunch = arg.split('=')[1] if '=' in arg else '128'
leading = ''
@@ -123,12 +123,13 @@ for arg in sys.argv[2:]:
leading = ''
elif leading == 'preload' or leading == 'embed':
mode = leading
- if '@' in arg:
+ uses_at_notation = '@' in arg
+ if uses_at_notation:
srcpath, dstpath = arg.split('@') # User is specifying destination filename explicitly.
else:
srcpath = dstpath = arg # Use source path as destination path.
if os.path.isfile(srcpath) or os.path.isdir(srcpath):
- data_files.append({ 'srcpath': srcpath, 'dstpath': dstpath, 'mode': mode })
+ data_files.append({ 'srcpath': srcpath, 'dstpath': dstpath, 'mode': mode, 'explicit_dst_path': uses_at_notation })
else:
print >> sys.stderr, 'Warning: ' + arg + ' does not exist, ignoring.'
elif leading == 'exclude':
@@ -206,7 +207,7 @@ def add(arg, dirname, names):
new_names.append(name)
if not os.path.isdir(fullname):
dstpath = os.path.join(rootpathdst, os.path.relpath(fullname, rootpathsrc)) # Convert source filename relative to root directory of target FS.
- new_data_files.append({ 'srcpath': fullname, 'dstpath': dstpath, 'mode': mode })
+ new_data_files.append({ 'srcpath': fullname, 'dstpath': dstpath, 'mode': mode, 'explicit_dst_path': True })
del names[:]
names.extend(new_names)
@@ -223,13 +224,14 @@ if len(data_files) == 0:
sys.exit(1)
# Absolutize paths, and check that they make sense
-curr_abspath = os.path.abspath(os.getcwd())
+curr_abspath = os.path.abspath(os.getcwd()) # os.getcwd() always returns the hard path with any symbolic links resolved, even if we cd'd into a symbolic link.
+
for file_ in data_files:
- if file_['srcpath'] == file_['dstpath']:
+ if not file_['explicit_dst_path']:
# This file was not defined with src@dst, so we inferred the destination from the source. In that case,
# we require that the destination not be under the current location
path = file_['dstpath']
- abspath = os.path.abspath(path)
+ abspath = os.path.realpath(os.path.abspath(path)) # Use os.path.realpath to resolve any symbolic links to hard paths, to match the structure in curr_abspath.
if DEBUG: print >> sys.stderr, path, abspath, curr_abspath
if not abspath.startswith(curr_abspath):
print >> sys.stderr, 'Error: Embedding "%s" which is below the current directory "%s". This is invalid since the current directory becomes the root that the generated code will see' % (path, curr_abspath)
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 240ee2bd..81bf8824 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -279,6 +279,28 @@ function clearEmptyNodes(list) {
}
}
+function filterEmptyNodes(list) { // creates a copy and returns it
+ return list.filter(function(node) {
+ return !(isEmptyNode(node) || (node[0] === 'stat' && isEmptyNode(node[1])));
+ });
+}
+
+function removeEmptySubNodes(node) {
+ if (node[0] === 'defun') {
+ node[3] = filterEmptyNodes(node[3]);
+ } else if (node[0] === 'block' && node[1]) {
+ node[1] = filterEmptyNodes(node[1]);
+ }
+/*
+ var stats = getStatements(node);
+ if (stats) clearEmptyNodes(stats);
+*/
+}
+
+function removeAllEmptySubNodes(ast) {
+ traverse(ast, removeEmptySubNodes);
+}
+
// Passes
// Dump the AST. Useful for debugging. For example,
@@ -1281,6 +1303,7 @@ function vacuum(ast) {
traverseGeneratedFunctions(ast, function(node) {
vacuumInternal(node);
simplifyNotComps(node);
+ removeEmptySubNodes(node);
});
}
@@ -1687,6 +1710,11 @@ function denormalizeAsm(func, data) {
if (!isEmptyNode(stats[i])) break;
}
}
+ // calculate variable definitions
+ var varDefs = [];
+ for (var v in data.vars) {
+ varDefs.push(makeAsmVarDef(v, data.vars[v]));
+ }
// each param needs a line; reuse emptyNodes as much as we can
var numParams = 0;
for (var i in data.params) numParams++;
@@ -1695,26 +1723,21 @@ function denormalizeAsm(func, data) {
if (!isEmptyNode(stats[emptyNodes])) break;
emptyNodes++;
}
- var neededEmptyNodes = numParams + 1; // params plus one big var
+ var neededEmptyNodes = numParams + (varDefs.length ? 1 : 0); // params plus one big var if there are vars
if (neededEmptyNodes > emptyNodes) {
var args = [0, 0];
for (var i = 0; i < neededEmptyNodes - emptyNodes; i++) args[i+2] = 0;
stats.splice.apply(stats, args);
+ } else if (neededEmptyNodes < emptyNodes) {
+ stats.splice(0, emptyNodes - neededEmptyNodes);
}
// add param coercions
var next = 0;
func[2].forEach(function(param) {
stats[next++] = ['stat', ['assign', true, ['name', param], makeAsmCoercion(['name', param], data.params[param])]];
});
- // add variable definitions
- var varDefs = [];
- for (var v in data.vars) {
- varDefs.push(makeAsmVarDef(v, data.vars[v]));
- }
if (varDefs.length) {
stats[next] = ['var', varDefs];
- } else {
- stats[next] = emptyNode();
}
if (data.inlines.length > 0) {
var i = 0;
@@ -3877,6 +3900,8 @@ function eliminate(ast, memSafe) {
}
new ExpressionOptimizer(ast).run();
}
+
+ removeAllEmptySubNodes(ast);
}
function eliminateMemSafe(ast) {
@@ -4247,6 +4272,8 @@ function aggressiveVariableEliminationInternal(func, asmData) {
}
}
});
+
+ removeAllEmptySubNodes(func);
}
function aggressiveVariableElimination(ast) {
@@ -5281,7 +5308,15 @@ if (extraInfoStart > 0) extraInfo = JSON.parse(src.substr(extraInfoStart + 14));
arguments_.slice(1).forEach(function(arg) {
+ //traverse(ast, function(node) {
+ // if (node[0] === 'defun' && node[1] === 'copyTempFloat') printErr('pre ' + JSON.stringify(node, null, ' '));
+ //});
passes[arg](ast);
+ //var func;
+ //traverse(ast, function(node) {
+ // if (node[0] === 'defun') func = node;
+ // if (isEmptyNode(node)) throw 'empty node after ' + arg + ', in ' + func[1];
+ //});
});
if (asm && last) {
asmLastOpts(ast); // TODO: move out of last, to make last faster when done later (as in side modules)
diff --git a/tools/profile_stripper.py b/tools/profile_stripper.py
new file mode 100644
index 00000000..3e538ef3
--- /dev/null
+++ b/tools/profile_stripper.py
@@ -0,0 +1,43 @@
+# See profile_used.py
+#
+# profile file, js file
+
+import sys, json
+
+used = json.loads(open(sys.argv[1]).read())
+
+show = True
+in_table = False
+
+for orig in open(sys.argv[2]).readlines():
+ line = orig.strip()
+
+ if orig.startswith('function _') and line.endswith(('){', ') {')):
+ name = line.split(' ')[1].split('(')[0]
+ if name.startswith('_') and not used.get(name):
+ #print >> sys.stderr, 'remove', name
+ show = False
+
+ if line.startswith('var FUNCTION_TABLE'):
+ in_table = True
+
+ if in_table:
+ start = 0
+ if 'var ' in line:
+ start = line.index('[')+1
+ end = len(line)
+ if ']' in line:
+ end = line.index(']')
+ contents = line[start:end]
+ fixed = map(lambda name: '"' + name + '"' if not used.get(name) else name, contents.split(','))
+ print (line[:start] + ','.join(fixed) + line[end:]).replace('""', '')
+ else:
+ if show:
+ print orig,
+
+ if orig.startswith('}'):
+ show = True
+
+ if in_table and line.endswith(';'):
+ in_table = False
+
diff --git a/tools/profile_used.py b/tools/profile_used.py
new file mode 100644
index 00000000..45420e0f
--- /dev/null
+++ b/tools/profile_used.py
@@ -0,0 +1,17 @@
+# Run, then execute
+'''
+dump(JSON.stringify(usedFunctions))
+'''
+# then strip with profile_strip.py
+
+import sys
+
+print 'var usedFunctions = {};'
+
+for line in open(sys.argv[1]).readlines():
+ line = line.strip()
+ print line
+ if line.startswith('function _') and line.endswith(('){', ') {')):
+ name = line.split(' ')[1].split('(')[0]
+ print 'usedFunctions["%s"] = 1;' % name
+
diff --git a/tools/shared.py b/tools/shared.py
index 533906c9..1adbdfaa 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -316,8 +316,10 @@ def check_fastcomp():
llvm_version = open(os.path.join(d, 'emscripten-version.txt')).read().strip()
if os.path.exists(os.path.join(d, 'tools', 'clang', 'emscripten-version.txt')):
clang_version = open(os.path.join(d, 'tools', 'clang', 'emscripten-version.txt')).read().strip()
+ elif os.path.exists(os.path.join(d, 'tools', 'clang')):
+ clang_version = '?' # Looks like the LLVM compiler tree has an old checkout from the time before it contained a version.txt: Should update!
else:
- clang_version = '?'
+ clang_version = llvm_version # This LLVM compiler tree does not have a tools/clang, so it's probably an out-of-source build directory. No need for separate versioning.
if EMSCRIPTEN_VERSION != llvm_version or EMSCRIPTEN_VERSION != clang_version:
logging.error('Emscripten, llvm and clang versions do not match, this is dangerous (%s, %s, %s)', EMSCRIPTEN_VERSION, llvm_version, clang_version)
logging.error('Make sure to use the same branch in each repo, and to be up-to-date on each. See https://github.com/kripken/emscripten/wiki/LLVM-Backend')
@@ -707,13 +709,14 @@ else:
# Engine tweaks
try:
+ SPIDERMONKEY_ENGINE = listify(SPIDERMONKEY_ENGINE)
if 'gcparam' not in str(SPIDERMONKEY_ENGINE):
new_spidermonkey = SPIDERMONKEY_ENGINE
- if type(SPIDERMONKEY_ENGINE) is str:
- new_spidermonkey = [SPIDERMONKEY_ENGINE]
new_spidermonkey += ['-e', "gcparam('maxBytes', 1024*1024*1024);"] # Our very large files need lots of gc heap
JS_ENGINES = map(lambda x: x if x != SPIDERMONKEY_ENGINE else new_spidermonkey, JS_ENGINES)
SPIDERMONKEY_ENGINE = new_spidermonkey
+ if '-w' not in SPIDERMONKEY_ENGINE:
+ SPIDERMONKEY_ENGINE += ['-w']
except NameError:
pass
diff --git a/tools/system_libs.py b/tools/system_libs.py
index 3723a5c3..ee185a51 100644
--- a/tools/system_libs.py
+++ b/tools/system_libs.py
@@ -335,8 +335,10 @@ def calculate(temp_files, in_temp, stdout, stderr):
# Settings this in the environment will avoid checking dependencies and make building big projects a little faster
# 1 means include everything; otherwise it can be the name of a lib (libcxx, etc.)
+ # You can provide 1 to include everything, or a comma-separated list with the ones you want
force = os.environ.get('EMCC_FORCE_STDLIBS')
force_all = force == '1'
+ force = set((force or '').split(','))
# Scan symbols
symbolses = map(lambda temp_file: shared.Building.llvm_nm(temp_file), temp_files)
@@ -364,15 +366,14 @@ def calculate(temp_files, in_temp, stdout, stderr):
all_needed.difference_update(symbols.defs)
# Go over libraries to figure out which we must include
- # If we have libcxx, we must force inclusion of libc, since libcxx uses new internally. Note: this is kind of hacky.
ret = []
has = need = None
- for name, create, apply_, library_symbols in [('libcxx', create_libcxx, apply_libcxx, libcxx_symbols),
- ('libcextra', create_libcextra, lambda x: True, libcextra_symbols),
- ('libcxxabi', create_libcxxabi, apply_libcxxabi, libcxxabi_symbols),
- ('gl', create_gl, lambda x: True, gl_symbols),
- ('libc', create_libc, apply_libc, libc_symbols)]:
- force_this = force_all or force == name
+ for name, create, apply_, library_symbols, deps in [('libcxx', create_libcxx, apply_libcxx, libcxx_symbols, ['libcextra', 'libcxxabi']),
+ ('libcextra', create_libcextra, lambda x: True, libcextra_symbols, ['libc']),
+ ('libcxxabi', create_libcxxabi, apply_libcxxabi, libcxxabi_symbols, ['libc']),
+ ('gl', create_gl, lambda x: True, gl_symbols, ['libc']),
+ ('libc', create_libc, apply_libc, libc_symbols, [])]:
+ force_this = force_all or name in force
if not force_this:
need = set()
has = set()
@@ -387,11 +388,11 @@ def calculate(temp_files, in_temp, stdout, stderr):
need.remove(haz)
if shared.Settings.VERBOSE: logging.debug('considering %s: we need %s and have %s' % (name, str(need), str(has)))
if force_this or len(need) > 0:
- force_all = True
if apply_(need):
# We need to build and link the library in
logging.debug('including %s' % name)
libfile = shared.Cache.get(name, create)
ret.append(libfile)
+ force = force.union(deps)
return ret
diff --git a/tools/test-js-optimizer-asm-outline1-output.js b/tools/test-js-optimizer-asm-outline1-output.js
index c4792c51..40c028c6 100644
--- a/tools/test-js-optimizer-asm-outline1-output.js
+++ b/tools/test-js-optimizer-asm-outline1-output.js
@@ -176,11 +176,12 @@ function vars(x, y) {
y = +y;
var sp = 0;
sp = STACKTOP;
- STACKTOP = STACKTOP + 152 | 0;
+ STACKTOP = STACKTOP + 136 | 0;
c(1 + (x + y));
c(2 + y * x);
c(3 + (x + y));
c(4 + y * x);
+ c(5 + (x + y));
HEAP32[sp + 8 >> 2] = x;
HEAPF32[sp + 16 >> 2] = y;
HEAP32[sp + 24 >> 2] = 0;
@@ -213,7 +214,7 @@ function vars3(x, y) {
y = +y;
var a = 0, sp = 0;
sp = STACKTOP;
- STACKTOP = STACKTOP + 160 | 0;
+ STACKTOP = STACKTOP + 144 | 0;
a = x + y;
a = c(1 + a);
a = c(2 + y * x);
@@ -256,15 +257,11 @@ function vars_w_stack(x, y) {
var a = 0, b = +0, sp = 0;
sp = STACKTOP;
STACKTOP = STACKTOP + 208 | 0;
- HEAP32[sp + 24 >> 2] = x;
- HEAPF32[sp + 32 >> 2] = y;
- HEAP32[sp + 40 >> 2] = a;
- HEAPF32[sp + 48 >> 2] = b;
- HEAP32[sp + 72 >> 2] = 0;
- HEAP32[sp + 76 >> 2] = 0;
- vars_w_stack$1(sp);
- a = HEAP32[sp + 40 >> 2] | 0;
- b = +HEAPF32[sp + 48 >> 2];
+ a = x + y;
+ b = y * x;
+ a = c(1 + a);
+ a = c(2 + a);
+ a = c(3 + a);
HEAP32[sp + 40 >> 2] = a;
HEAPF32[sp + 48 >> 2] = b;
HEAP32[sp + 64 >> 2] = 0;
@@ -585,10 +582,9 @@ function mix$1(sp) {
}
function vars$0(sp) {
sp = sp | 0;
- var x = 0, y = +0;
+ var y = +0, x = 0;
x = HEAP32[sp + 8 >> 2] | 0;
y = +HEAPF32[sp + 16 >> 2];
- c(5 + (x + y));
c(6 + y * x);
c(7 + (x + y));
c(8 + y * x);
@@ -632,6 +628,7 @@ function vars_w_stack$0(sp) {
var a = 0, b = +0;
a = HEAP32[sp + 40 >> 2] | 0;
b = +HEAPF32[sp + 48 >> 2];
+ a = c(4 + a);
a = c(5 + a);
a = c(6 + a);
b = c(7 + a);
@@ -639,22 +636,6 @@ function vars_w_stack$0(sp) {
HEAP32[sp + 40 >> 2] = a;
HEAPF32[sp + 48 >> 2] = b;
}
-function vars_w_stack$1(sp) {
- sp = sp | 0;
- var a = 0, x = 0, y = +0, b = +0;
- x = HEAP32[sp + 24 >> 2] | 0;
- y = +HEAPF32[sp + 32 >> 2];
- a = HEAP32[sp + 40 >> 2] | 0;
- b = +HEAPF32[sp + 48 >> 2];
- a = x + y;
- b = y * x;
- a = c(1 + a);
- a = c(2 + a);
- a = c(3 + a);
- a = c(4 + a);
- HEAP32[sp + 40 >> 2] = a;
- HEAPF32[sp + 48 >> 2] = b;
-}
function chain$0(sp) {
sp = sp | 0;
var helper$0 = 0;