From 78ceb79db1ea03613f0760a412166e13ed0e1da4 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Mon, 25 Sep 2023 10:10:09 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1248863 - IonMonkey: MIPS: Fix MDefinition::constantValue re-factored. r=luke (c38ce4f8dd) - Bug 1231024 - narrow the live range for values. r=jandem (bfe06e964d) - Bug 1248007 part 1 - Refactor useBox and friends to work more like useRegister. r=nbp (8585828647) - Bug 1248007 part 2 - Remove unused This operands from LCallDirectEval. r=nbp (ca16fc594e) - Bug 1248598 part 3 - Enable i64 on x64 and various related changes. r=sunfish (75311df85c) - Bug 1248863 - IonMonkey: MIPS32: Fix LIRGeneratorMIPS::visitBox. r=arai (2d6f64ed18) - Bug 1244889 - Handle all SIMD types in js::SimdTypeToName. r=bbouvier (7e8952b52d) - Bug 1244889 - Add support for Uint32x4 as an asm.js type. r=luke (cab8e0e725) - Bug 1244889 - Fix Float32x4toUint32x4 for asm.js. r=bbouvier (3b34875729) - Bug 1244889 - Disallow unsigned SIMD types for global variables. r=luke (cde605325d) - Bug 1201934 - Remove SIMD shiftRight***ByScalar. r=sunfish (db2a308c6f) - Bug 1246800 - Masked shift-by-scalar amounts. r=sunfish (58f335a1cf) - Bug 1226017 - Drop support for b2g desktop in reftests, r=jgriffin (b71bfbea26) - Bug 1231261 - Append plugins to extra profile files instead of overwriting. r=dbaron (cce158e2bf) - Bug 1193223 - Add reftest support to mach test, r=chmanchester (44e12e1622) - Bug 1087791 - Add |mach {reftest,crashtest,jstestbrowser}| for mobile/android. r=nalexander (711a6eb376) - Bug 1087791 - Follow-up on 340c1df41b69 (pushed wrong version of patch); r=nalexander (d4e7b53834) - Bug 1228636 - Add mach support for running reftests on mulet, r=jgriffin (25fa23feb4) - Bug 1232792 - Convert JS callsites to use open2 within layout/ (r=sicking) (8ee4616658) - Bug 1196831 - Add 'run-until-failure' and 'repeat' flags to reftest. r=jmaher (7792c9fa22) - Bug 1215148 - Object-count based leak checking for Mochitest. r=jgriffin (afe3a307b2) - Bug 1219371 - Add suppression for Aurora-only Windows leak. r=erahm (2e74e92da2) - Bug 1218393 - Give a summary for object-count leak checking. r=jgriffin (b1bd4844e9) - Bug 1219919 - Add suppressions for Windows-specific content process graphics leaks. r=erahm (a651f412b3) - Bug 1140394 - Protect standard output from interleaving. r=ahal (0ef5d8f71f) - Bug 1034290 - Use structured log output for test results in reftest, r=jmaher (3e93bd862b) - Bug 1249787 - OdinMonkey: Add offset and align fields to the encoding of load and store. r=luke (822e9b01f9) - Bug 1248203 - streamline h2 stream flow control buffer r=hurley (739a39a255) - Bug 1221320 - XMLHttpRequest authentication should not require auth prompt dialog, r=honzab.moz (12d9bcc6d0) - Bug 1158543 - Remove SpdyConnectTransaction::mRequestHead and make the base class mRequestHead protected; r=mcmanus (9678015004) - Bug 844948 - Allow changing padding of themed button on OS X. r=mstange,heycam (56cbcffbfe) - Bug 1248983 - Fix spelling for nsCocoaWindow.mm. r=jdm (e185ad5889) - Bug 917505 - Add WEBGL_compressed_texture_es3 support. r=jgilbert r=smaug (bf4ef11229) - Bug 1243072 - Make GfxTexturesReporter work again r=nical,jgilbert (6942d70ecf) --- build/automation.py.in | 14 +- build/mobile/b2gautomation.py | 29 +- build/mobile/remoteautomation.py | 38 +- dom/base/nsXMLHttpRequest.cpp | 162 +- dom/base/nsXMLHttpRequest.h | 2 + dom/base/test/mochitest.ini | 1 - dom/bindings/Bindings.conf | 5 + dom/canvas/WebGLContext.h | 1 + dom/canvas/WebGLContextExtensions.cpp | 6 + .../WebGLExtensionCompressedTextureES3.cpp | 55 + dom/canvas/WebGLExtensions.h | 10 + dom/canvas/WebGLProgram.h | 1 + dom/canvas/WebGLTypes.h | 1 + dom/canvas/moz.build | 1 + dom/canvas/test/webgl-mochitest.ini | 2 + dom/canvas/test/webgl-mochitest/es3-data.js | 4719 +++++++++++++++++ .../test_webgl_compressed_texture_es3.html | 753 +++ dom/webidl/WebGLRenderingContext.webidl | 15 + gfx/gl/GLTextureImage.cpp | 23 +- gfx/gl/GLTextureImage.h | 7 +- gfx/gl/GLUploadHelpers.cpp | 64 +- gfx/gl/GLUploadHelpers.h | 3 + gfx/gl/GfxTexturesReporter.cpp | 75 +- gfx/gl/GfxTexturesReporter.h | 13 +- gfx/gl/TextureImageEGL.cpp | 5 + js/src/asmjs/AsmJS.cpp | 234 +- js/src/asmjs/Wasm.cpp | 33 +- js/src/asmjs/WasmBinary.h | 9 + js/src/asmjs/WasmIonCompile.cpp | 68 +- js/src/asmjs/WasmTypes.h | 25 +- js/src/builtin/SIMD.cpp | 57 +- js/src/builtin/SIMD.h | 23 +- js/src/jit-test/tests/SIMD/shift.js | 55 +- js/src/jit-test/tests/asm.js/testSIMD.js | 204 +- js/src/jit-test/tests/wasm/basic.js | 25 +- js/src/jit/CodeGenerator.cpp | 16 +- js/src/jit/CodeGenerator.h | 1 + js/src/jit/LIR.h | 57 + js/src/jit/Lowering.cpp | 319 +- js/src/jit/Lowering.h | 6 +- js/src/jit/MCallOptimize.cpp | 4 - js/src/jit/MacroAssembler.h | 6 + js/src/jit/arm/LIR-arm.h | 11 +- js/src/jit/arm/Lowering-arm.cpp | 15 +- js/src/jit/arm/Lowering-arm.h | 7 +- js/src/jit/arm/MacroAssembler-arm-inl.h | 15 + js/src/jit/arm/MacroAssembler-arm.h | 4 - js/src/jit/arm64/LIR-arm64.h | 5 +- js/src/jit/arm64/Lowering-arm64.cpp | 4 +- js/src/jit/arm64/Lowering-arm64.h | 7 +- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 13 + js/src/jit/arm64/MacroAssembler-arm64.h | 3 - js/src/jit/mips-shared/LIR-mips-shared.h | 6 +- .../jit/mips-shared/Lowering-mips-shared.cpp | 19 +- js/src/jit/mips32/LIR-mips32.h | 6 +- js/src/jit/mips32/Lowering-mips32.cpp | 14 +- js/src/jit/mips32/Lowering-mips32.h | 7 +- js/src/jit/mips32/MacroAssembler-mips32-inl.h | 15 + js/src/jit/mips32/MacroAssembler-mips32.h | 4 - js/src/jit/mips64/CodeGenerator-mips64.cpp | 4 +- js/src/jit/mips64/Lowering-mips64.cpp | 9 +- js/src/jit/mips64/Lowering-mips64.h | 7 +- js/src/jit/mips64/MacroAssembler-mips64-inl.h | 13 + js/src/jit/mips64/MacroAssembler-mips64.h | 3 - js/src/jit/none/Lowering-none.h | 2 +- js/src/jit/shared/CodeGenerator-shared-inl.h | 12 + js/src/jit/shared/LIR-shared.h | 330 +- js/src/jit/shared/LOpcodes-shared.h | 1 + js/src/jit/shared/Lowering-shared-inl.h | 64 +- js/src/jit/shared/Lowering-shared.cpp | 3 + js/src/jit/shared/Lowering-shared.h | 17 +- js/src/jit/x64/Assembler-x64.cpp | 2 + js/src/jit/x64/Lowering-x64.cpp | 6 +- js/src/jit/x64/Lowering-x64.h | 4 +- js/src/jit/x64/MacroAssembler-x64-inl.h | 12 + js/src/jit/x64/MacroAssembler-x64.h | 3 - .../x86-shared/CodeGenerator-x86-shared.cpp | 37 +- js/src/jit/x86-shared/LIR-x86-shared.h | 6 +- js/src/jit/x86-shared/Lowering-x86-shared.cpp | 3 +- js/src/jit/x86/LIR-x86.h | 6 +- js/src/jit/x86/Lowering-x86.cpp | 12 +- js/src/jit/x86/Lowering-x86.h | 7 +- js/src/jit/x86/MacroAssembler-x86-inl.h | 15 + js/src/jit/x86/MacroAssembler-x86.h | 4 - js/src/tests/ecma_7/SIMD/shifts.js | 60 +- layout/reftests/bugs/reftest.list | 2 +- layout/reftests/forms/input/file/reftest.list | 8 +- layout/reftests/reftest-sanity/reftest.list | 20 +- layout/style/forms.css | 2 + layout/tools/reftest/Makefile.in | 3 +- layout/tools/reftest/jar.mn | 1 + layout/tools/reftest/mach_commands.py | 261 +- layout/tools/reftest/output.py | 144 + layout/tools/reftest/reftest.js | 347 +- layout/tools/reftest/reftestcommandline.py | 37 +- layout/tools/reftest/remotereftest.py | 48 +- layout/tools/reftest/runreftest.py | 187 +- layout/tools/reftest/runreftestb2g.py | 28 +- .../{b2g_desktop.py => runreftestmulet.py} | 68 +- netwerk/base/SimpleBuffer.cpp | 95 + netwerk/base/SimpleBuffer.h | 57 + netwerk/base/moz.build | 1 + netwerk/ipc/NeckoChannelParams.ipdlh | 1 + netwerk/protocol/http/ASpdySession.h | 2 +- netwerk/protocol/http/Http2Stream.cpp | 55 +- netwerk/protocol/http/Http2Stream.h | 6 +- netwerk/protocol/http/HttpBaseChannel.cpp | 21 + netwerk/protocol/http/HttpBaseChannel.h | 10 +- netwerk/protocol/http/HttpChannelChild.cpp | 2 + netwerk/protocol/http/HttpChannelParent.cpp | 4 +- netwerk/protocol/http/HttpChannelParent.h | 1 + netwerk/protocol/http/NullHttpTransaction.cpp | 2 +- netwerk/protocol/http/NullHttpTransaction.h | 2 +- netwerk/protocol/http/TunnelUtils.cpp | 3 - netwerk/protocol/http/TunnelUtils.h | 1 - .../http/nsHttpChannelAuthProvider.cpp | 13 + .../protocol/http/nsIHttpChannelInternal.idl | 10 +- testing/mach_commands.py | 7 +- testing/modules/StructuredLog.jsm | 32 +- testing/mozbase/mozleak/mozleak/leaklog.py | 135 +- .../mozlog/mozlog/formatters/tbplformatter.py | 15 +- testing/mozbase/mozlog/mozlog/logtypes.py | 4 +- .../mozbase/mozlog/mozlog/structuredlog.py | 5 +- widget/cocoa/nsChildView.mm | 5 +- widget/cocoa/nsCocoaWindow.mm | 2 +- widget/cocoa/nsNativeThemeCocoa.mm | 1 - 126 files changed, 8131 insertions(+), 1461 deletions(-) create mode 100644 dom/canvas/WebGLExtensionCompressedTextureES3.cpp create mode 100644 dom/canvas/test/webgl-mochitest/es3-data.js create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl_compressed_texture_es3.html create mode 100644 layout/tools/reftest/output.py rename layout/tools/reftest/{b2g_desktop.py => runreftestmulet.py} (83%) create mode 100644 netwerk/base/SimpleBuffer.cpp create mode 100644 netwerk/base/SimpleBuffer.h diff --git a/build/automation.py.in b/build/automation.py.in index ab52897f80..48af6ec7cc 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -396,7 +396,7 @@ class Automation(object): self.log.info("Can't trigger Breakpad, just killing process") self.killPid(processPID) - def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath): + def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath, outputHandler=None): """ Look for timeout or crashes and return the status after the process terminates """ stackFixerFunction = None didTimeout = False @@ -437,7 +437,12 @@ class Automation(object): while line != "" and not didTimeout: if stackFixerFunction: line = stackFixerFunction(line) - self.log.info(line.rstrip().decode("UTF-8", "ignore")) + + if outputHandler is None: + self.log.info(line.rstrip().decode("UTF-8", "ignore")) + else: + outputHandler(line) + if "TEST-START" in line and "|" in line: self.lastTestSeen = line.split("|")[1].strip() if not debuggerInfo and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line: @@ -531,7 +536,7 @@ class Automation(object): debuggerInfo = None, symbolsPath = None, timeout = -1, maxTime = None, onLaunch = None, detectShutdownLeaks = False, screenshotOnFail=False, testPath=None, bisectChunk=None, - valgrindPath=None, valgrindArgs=None, valgrindSuppFiles=None): + valgrindPath=None, valgrindArgs=None, valgrindSuppFiles=None, outputHandler=None): """ Run the app, log the duration it took to execute, return the status code. Kills the app if it runs for longer than |maxTime| seconds, or outputs nothing for |timeout| seconds. @@ -580,7 +585,8 @@ class Automation(object): # app is launched. onLaunch() - status = self.waitForFinish(proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath) + status = self.waitForFinish(proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath, + outputHandler=outputHandler) self.log.info("INFO | automation.py | Application ran for: %s", str(datetime.now() - startTime)) # Do a final check for zombie child processes. diff --git a/build/mobile/b2gautomation.py b/build/mobile/b2gautomation.py index ba307756d0..97f88895be 100644 --- a/build/mobile/b2gautomation.py +++ b/build/mobile/b2gautomation.py @@ -205,23 +205,31 @@ class B2GRemoteAutomation(Automation): return app, args def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, - debuggerInfo, symbolsPath): + debuggerInfo, symbolsPath, outputHandler=None): """ Wait for tests to finish (as evidenced by a signature string in logcat), or for a given amount of time to elapse with no output. """ timeout = timeout or 120 while True: - currentlog = proc.getStdoutLines(timeout) - if currentlog: - print currentlog + lines = proc.getStdoutLines(timeout) + if lines: + currentlog = '\n'.join(lines) + + if outputHandler: + for line in lines: + outputHandler(line) + else: + print(currentlog) + # Match the test filepath from the last TEST-START line found in the new # log content. These lines are in the form: # ... INFO TEST-START | /filepath/we/wish/to/capture.html\n testStartFilenames = re.findall(r"TEST-START \| ([^\s]*)", currentlog) if testStartFilenames: self.lastTestSeen = testStartFilenames[-1] - if hasattr(self, 'logFinish') and self.logFinish in currentlog: + if (outputHandler and outputHandler.suite_finished) or ( + hasattr(self, 'logFinish') and self.logFinish in currentlog): return 0 else: self.log.info("TEST-UNEXPECTED-FAIL | %s | application timed " @@ -431,11 +439,12 @@ class B2GRemoteAutomation(Automation): break # wait 'timeout' for any additional lines - try: - lines.append(self.queue.get(True, timeout)) - except Queue.Empty: - pass - return '\n'.join(lines) + if not lines: + try: + lines.append(self.queue.get(True, timeout)) + except Queue.Empty: + pass + return lines def wait(self, timeout=None): # this should never happen diff --git a/build/mobile/remoteautomation.py b/build/mobile/remoteautomation.py index 67dcd72cd2..79a395a1ef 100644 --- a/build/mobile/remoteautomation.py +++ b/build/mobile/remoteautomation.py @@ -80,7 +80,7 @@ class RemoteAutomation(Automation): return env - def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath): + def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath, outputHandler=None): """ Wait for tests to finish. If maxTime seconds elapse or no output is detected for timeout seconds, kill the process and fail the test. @@ -264,20 +264,21 @@ class RemoteAutomation(Automation): return pid def read_stdout(self): - """ Fetch the full remote log file using devicemanager and return just - the new log entries since the last call (as a list of messages or lines). + """ + Fetch the full remote log file using devicemanager, process them and + return whether there were any new log entries since the last call. """ if not self.dm.fileExists(self.proc): - return [] + return False try: newLogContent = self.dm.pullFile(self.proc, self.stdoutlen) except DMError: # we currently don't retry properly in the pullFile # function in dmSUT, so an error here is not necessarily # the end of the world - return [] + return False if not newLogContent: - return [] + return False self.stdoutlen += len(newLogContent) @@ -286,26 +287,27 @@ class RemoteAutomation(Automation): if testStartFilenames: self.lastTestSeen = testStartFilenames[-1] print newLogContent - return [newLogContent] + return True self.logBuffer += newLogContent lines = self.logBuffer.split('\n') - if not lines: - return - # We only keep the last (unfinished) line in the buffer - self.logBuffer = lines[-1] - del lines[-1] - messages = [] + if lines: + # We only keep the last (unfinished) line in the buffer + self.logBuffer = lines[-1] + del lines[-1] + + if not lines: + return False + for line in lines: # This passes the line to the logger (to be logged or buffered) # and returns a list of structured messages (dict) parsed_messages = self.messageLogger.write(line) for message in parsed_messages: - if message['action'] == 'test_start': + if isinstance(message, dict) and message.get('action') == 'test_start': self.lastTestSeen = message['test'] - messages += parsed_messages - return messages + return True @property def getLastTestSeen(self): @@ -331,10 +333,10 @@ class RemoteAutomation(Automation): # too long, only do it every 60 seconds if (not slowLog) or (timer % 60 == 0): startRead = datetime.datetime.now() - messages = self.read_stdout() + hasOutput = self.read_stdout() if (datetime.datetime.now() - startRead) > datetime.timedelta(seconds=5): slowLog = True - if messages: + if hasOutput: noOutputTimer = 0 time.sleep(interval) timer += interval diff --git a/dom/base/nsXMLHttpRequest.cpp b/dom/base/nsXMLHttpRequest.cpp index b001665d0e..97d72f14ee 100644 --- a/dom/base/nsXMLHttpRequest.cpp +++ b/dom/base/nsXMLHttpRequest.cpp @@ -179,72 +179,6 @@ static void AddLoadFlags(nsIRequest *request, nsLoadFlags newFlags) request->SetLoadFlags(flags); } -//----------------------------------------------------------------------------- -// XMLHttpRequestAuthPrompt -//----------------------------------------------------------------------------- - -class XMLHttpRequestAuthPrompt : public nsIAuthPrompt -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIAUTHPROMPT - - XMLHttpRequestAuthPrompt(); - -protected: - virtual ~XMLHttpRequestAuthPrompt(); -}; - -NS_IMPL_ISUPPORTS(XMLHttpRequestAuthPrompt, nsIAuthPrompt) - -XMLHttpRequestAuthPrompt::XMLHttpRequestAuthPrompt() -{ - MOZ_COUNT_CTOR(XMLHttpRequestAuthPrompt); -} - -XMLHttpRequestAuthPrompt::~XMLHttpRequestAuthPrompt() -{ - MOZ_COUNT_DTOR(XMLHttpRequestAuthPrompt); -} - -NS_IMETHODIMP -XMLHttpRequestAuthPrompt::Prompt(const char16_t* aDialogTitle, - const char16_t* aText, - const char16_t* aPasswordRealm, - uint32_t aSavePassword, - const char16_t* aDefaultText, - char16_t** aResult, - bool* aRetval) -{ - *aRetval = false; - return NS_OK; -} - -NS_IMETHODIMP -XMLHttpRequestAuthPrompt::PromptUsernameAndPassword(const char16_t* aDialogTitle, - const char16_t* aDialogText, - const char16_t* aPasswordRealm, - uint32_t aSavePassword, - char16_t** aUser, - char16_t** aPwd, - bool* aRetval) -{ - *aRetval = false; - return NS_OK; -} - -NS_IMETHODIMP -XMLHttpRequestAuthPrompt::PromptPassword(const char16_t* aDialogTitle, - const char16_t* aText, - const char16_t* aPasswordRealm, - uint32_t aSavePassword, - char16_t** aPwd, - bool* aRetval) -{ - *aRetval = false; - return NS_OK; -} - ///////////////////////////////////////////// NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget) @@ -2930,6 +2864,10 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable& aBody) mChannel->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks)); mChannel->SetNotificationCallbacks(this); + if (internalHttpChannel) { + internalHttpChannel->SetBlockAuthPrompt(ShouldBlockAuthPrompt()); + } + // Start reading from the channel // Because of bug 682305, we can't let listener be the XHR object itself // because JS wouldn't be able to use it. So create a listener around 'this'. @@ -3543,59 +3481,6 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult) } else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) || aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) { - - nsCOMPtr uri; - rv = mChannel->GetURI(getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - - // Verify that it's ok to prompt for credentials here, per spec - // http://xhr.spec.whatwg.org/#the-send%28%29-method - bool showPrompt = true; - - // If authentication fails, XMLHttpRequest origin and - // the request URL are same origin, ... - /* Disabled - bug: 799540 - if (IsCrossSiteCORSRequest()) { - showPrompt = false; - } - */ - - // ... Authorization is not in the list of author request headers, ... - if (showPrompt) { - for (uint32_t i = 0, len = mModifiedRequestHeaders.Length(); i < len; ++i) { - if (mModifiedRequestHeaders[i].header. - LowerCaseEqualsLiteral("authorization")) { - showPrompt = false; - break; - } - } - } - - // ... request username is null, and request password is null, - if (showPrompt) { - - nsCString username; - rv = uri->GetUsername(username); - NS_ENSURE_SUCCESS(rv, rv); - - nsCString password; - rv = uri->GetPassword(password); - NS_ENSURE_SUCCESS(rv, rv); - - if (!username.IsEmpty() || !password.IsEmpty()) { - showPrompt = false; - } - } - - // ... user agents should prompt the end user for their username and password. - if (!showPrompt) { - RefPtr prompt = new XMLHttpRequestAuthPrompt(); - if (!prompt) - return NS_ERROR_OUT_OF_MEMORY; - - return prompt->QueryInterface(aIID, aResult); - } - nsCOMPtr wwatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); @@ -3743,6 +3628,45 @@ nsXMLHttpRequest::EnsureXPCOMifier() return newRef.forget(); } +bool +nsXMLHttpRequest::ShouldBlockAuthPrompt() +{ + // Verify that it's ok to prompt for credentials here, per spec + // http://xhr.spec.whatwg.org/#the-send%28%29-method + + for (uint32_t i = 0, len = mModifiedRequestHeaders.Length(); i < len; ++i) { + if (mModifiedRequestHeaders[i].header. + LowerCaseEqualsLiteral("authorization")) { + return true; + } + } + + nsCOMPtr uri; + nsresult rv = mChannel->GetURI(getter_AddRefs(uri)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + + // Also skip if a username and/or password is provided in the URI. + nsCString username; + rv = uri->GetUsername(username); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + + nsCString password; + rv = uri->GetPassword(password); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + + if (!username.IsEmpty() || !password.IsEmpty()) { + return true; + } + + return false; +} + NS_IMPL_ISUPPORTS(nsXMLHttpRequest::nsHeaderVisitor, nsIHttpHeaderVisitor) NS_IMETHODIMP nsXMLHttpRequest:: diff --git a/dom/base/nsXMLHttpRequest.h b/dom/base/nsXMLHttpRequest.h index 20624828e7..e7712bbaaa 100644 --- a/dom/base/nsXMLHttpRequest.h +++ b/dom/base/nsXMLHttpRequest.h @@ -799,6 +799,8 @@ protected: void ResetResponse(); + bool ShouldBlockAuthPrompt(); + struct RequestHeader { nsCString header; diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index bf9f91bdee..f0fc26ee4b 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -400,7 +400,6 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # b2g(clipboard unde [test_bug276037-1.html] [test_bug276037-2.xhtml] [test_bug282547.html] -skip-if = e10s [test_bug28293.html] [test_bug28293.xhtml] [test_bug298064.html] diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 4b46a89bc4..8e82ca7961 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1405,6 +1405,11 @@ DOMInterfaces = { 'headerFile': 'WebGLExtensions.h' }, +'WEBGL_compressed_texture_es3': { + 'nativeType': 'mozilla::WebGLExtensionCompressedTextureES3', + 'headerFile': 'WebGLExtensions.h' +}, + 'WEBGL_compressed_texture_pvrtc': { 'nativeType': 'mozilla::WebGLExtensionCompressedTexturePVRTC', 'headerFile': 'WebGLExtensions.h' diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index f07be02c22..3810bf1a49 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -189,6 +189,7 @@ class WebGLContext friend class WebGL2Context; friend class WebGLContextUserData; friend class WebGLExtensionCompressedTextureATC; + friend class WebGLExtensionCompressedTextureES3; friend class WebGLExtensionCompressedTextureETC1; friend class WebGLExtensionCompressedTexturePVRTC; friend class WebGLExtensionCompressedTextureS3TC; diff --git a/dom/canvas/WebGLContextExtensions.cpp b/dom/canvas/WebGLContextExtensions.cpp index 86708995b0..9e89c3c5e8 100644 --- a/dom/canvas/WebGLContextExtensions.cpp +++ b/dom/canvas/WebGLContextExtensions.cpp @@ -47,6 +47,7 @@ WebGLContext::GetExtensionString(WebGLExtensionID ext) WEBGL_EXTENSION_IDENTIFIER(OES_vertex_array_object) WEBGL_EXTENSION_IDENTIFIER(WEBGL_color_buffer_float) WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_atc) + WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_es3) WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc1) WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_pvrtc) WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_s3tc) @@ -199,6 +200,8 @@ WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const switch (ext) { case WebGLExtensionID::EXT_disjoint_timer_query: return WebGLExtensionDisjointTimerQuery::IsSupported(this); + case WebGLExtensionID::WEBGL_compressed_texture_es3: + return gl->IsExtensionSupported(gl::GLContext::ARB_ES3_compatibility); default: // For warnings-as-errors. @@ -377,6 +380,9 @@ WebGLContext::EnableExtension(WebGLExtensionID ext) case WebGLExtensionID::WEBGL_compressed_texture_atc: obj = new WebGLExtensionCompressedTextureATC(this); break; + case WebGLExtensionID::WEBGL_compressed_texture_es3: + obj = new WebGLExtensionCompressedTextureES3(this); + break; case WebGLExtensionID::WEBGL_compressed_texture_etc1: obj = new WebGLExtensionCompressedTextureETC1(this); break; diff --git a/dom/canvas/WebGLExtensionCompressedTextureES3.cpp b/dom/canvas/WebGLExtensionCompressedTextureES3.cpp new file mode 100644 index 0000000000..f5c10aa5c4 --- /dev/null +++ b/dom/canvas/WebGLExtensionCompressedTextureES3.cpp @@ -0,0 +1,55 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLExtensions.h" + +#include "mozilla/dom/WebGLRenderingContextBinding.h" +#include "WebGLContext.h" + +#ifdef FOO +#error FOO is already defined! We use FOO() macros to keep things succinct in this file. +#endif + +namespace mozilla { + +WebGLExtensionCompressedTextureES3::WebGLExtensionCompressedTextureES3(WebGLContext* webgl) + : WebGLExtensionBase(webgl) +{ + RefPtr webgl_ = webgl; // Bug 1201275 + const auto fnAdd = [&webgl_](GLenum sizedFormat, webgl::EffectiveFormat effFormat) { + auto& fua = webgl_->mFormatUsage; + + auto usage = fua->EditUsage(effFormat); + usage->isFilterable = true; + fua->AllowSizedTexFormat(sizedFormat, usage); + + webgl_->mCompressedTextureFormats.AppendElement(sizedFormat); + }; + +#define FOO(x) LOCAL_GL_ ## x, webgl::EffectiveFormat::x + + fnAdd(FOO(COMPRESSED_R11_EAC)); + fnAdd(FOO(COMPRESSED_SIGNED_R11_EAC)); + fnAdd(FOO(COMPRESSED_RG11_EAC)); + fnAdd(FOO(COMPRESSED_SIGNED_RG11_EAC)); + fnAdd(FOO(COMPRESSED_RGB8_ETC2)); + fnAdd(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2)); + fnAdd(FOO(COMPRESSED_RGBA8_ETC2_EAC)); + + // sRGB support is manadatory in GL 4.3 and GL ES 3.0, which are the only + // versions to support ETC2. + fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)); + fnAdd(FOO(COMPRESSED_SRGB8_ETC2)); + fnAdd(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2)); + +#undef FOO +} + +WebGLExtensionCompressedTextureES3::~WebGLExtensionCompressedTextureES3() +{ +} + +IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureES3, WEBGL_compressed_texture_es3) + +} // namespace mozilla diff --git a/dom/canvas/WebGLExtensions.h b/dom/canvas/WebGLExtensions.h index 77d0e98e3f..39436025d3 100644 --- a/dom/canvas/WebGLExtensions.h +++ b/dom/canvas/WebGLExtensions.h @@ -71,6 +71,16 @@ public: DECL_WEBGL_EXTENSION_GOOP }; +class WebGLExtensionCompressedTextureES3 + : public WebGLExtensionBase +{ +public: + explicit WebGLExtensionCompressedTextureES3(WebGLContext*); + virtual ~WebGLExtensionCompressedTextureES3(); + + DECL_WEBGL_EXTENSION_GOOP +}; + class WebGLExtensionCompressedTextureETC1 : public WebGLExtensionBase { diff --git a/dom/canvas/WebGLProgram.h b/dom/canvas/WebGLProgram.h index 403d9210b4..b0b611c74a 100644 --- a/dom/canvas/WebGLProgram.h +++ b/dom/canvas/WebGLProgram.h @@ -8,6 +8,7 @@ #include #include +#include #include #include "mozilla/LinkedList.h" diff --git a/dom/canvas/WebGLTypes.h b/dom/canvas/WebGLTypes.h index 424697e74e..d082587c79 100644 --- a/dom/canvas/WebGLTypes.h +++ b/dom/canvas/WebGLTypes.h @@ -149,6 +149,7 @@ enum class WebGLExtensionID : uint8_t { OES_vertex_array_object, WEBGL_color_buffer_float, WEBGL_compressed_texture_atc, + WEBGL_compressed_texture_es3, WEBGL_compressed_texture_etc1, WEBGL_compressed_texture_pvrtc, WEBGL_compressed_texture_s3tc, diff --git a/dom/canvas/moz.build b/dom/canvas/moz.build index 7ffa9393dc..9a8b6104d0 100644 --- a/dom/canvas/moz.build +++ b/dom/canvas/moz.build @@ -101,6 +101,7 @@ UNIFIED_SOURCES += [ 'WebGLExtensionColorBufferFloat.cpp', 'WebGLExtensionColorBufferHalfFloat.cpp', 'WebGLExtensionCompressedTextureATC.cpp', + 'WebGLExtensionCompressedTextureES3.cpp', 'WebGLExtensionCompressedTextureETC1.cpp', 'WebGLExtensionCompressedTexturePVRTC.cpp', 'WebGLExtensionCompressedTextureS3TC.cpp', diff --git a/dom/canvas/test/webgl-mochitest.ini b/dom/canvas/test/webgl-mochitest.ini index 1f53bc772f..f371fa212a 100644 --- a/dom/canvas/test/webgl-mochitest.ini +++ b/dom/canvas/test/webgl-mochitest.ini @@ -4,6 +4,7 @@ skip-if = ((os == 'linux') && (buildapp == 'b2g')) support-files = webgl-mochitest/driver-info.js + webgl-mochitest/es3-data.js webgl-mochitest/webgl-util.js [webgl-mochitest/test_backbuffer_channels.html] @@ -33,6 +34,7 @@ skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests # We haven't cleaned up the Try results yet, but let's get this on the books first. [webgl-mochitest/test_webgl_conformance.html] skip-if = buildapp == 'mulet' || toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests +[webgl-mochitest/test_webgl_compressed_texture_es3.html] [webgl-mochitest/test_webgl_disjoint_timer_query.html] [webgl-mochitest/test_webgl_request_context.html] skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests diff --git a/dom/canvas/test/webgl-mochitest/es3-data.js b/dom/canvas/test/webgl-mochitest/es3-data.js new file mode 100644 index 0000000000..ec00cf82ee --- /dev/null +++ b/dom/canvas/test/webgl-mochitest/es3-data.js @@ -0,0 +1,4719 @@ +// The compressed data are created by Mali GPU Texture Compression Tool +// (http://malideveloper.arm.com/resources/tools/mali-gpu-texture-compression-tool/). +// Simply convert image to ktx format then strip the ktx header to +// get compressed data. +// +// The decompressed data are create by Khronos KTX library and tools +// (https://github.com/KhronosGroup/KTX) +// Calling _ktxUnpackETC with previous generated compressed data to +// get decompressed data. + +var img_4x4_r11_eac = { + compressed: new Uint8Array([ + 0x0f, 0xf9, 0xbe, 0xff, 0xef, 0xb6, 0xff, 0xff, + ]), + decompressed: new Uint8Array([ + 0x4b, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x4b, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + ]) +} + +var img_4x4_signed_r11_eac = { + compressed: new Uint8Array([ + 0x90, 0xf9, 0xbe, 0xff, 0xef, 0xb6, 0xff, 0xff, + ]), + decompressed: new Uint8Array([ + 0x4c, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x4c, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + ]) +} + +var img_4x4_rg11_eac = { + compressed: new Uint8Array([ + 0x2e, 0xf0, 0xe7, 0x92, 0x79, 0xff, 0x92, 0x49, + 0x2e, 0xf0, 0x3c, 0xff, 0xcf, 0x24, 0xff, 0xff, + ]), + decompressed: new Uint8Array([ + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + ]) +} + +var img_4x4_signed_rg11_eac = { + compressed: new Uint8Array([ + 0xae, 0xf0, 0xe7, 0x92, 0x79, 0xff, 0x92, 0x49, + 0xae, 0xf0, 0x3c, 0xff, 0xcf, 0x24, 0xff, 0xff, + ]), + decompressed: new Uint8Array([ + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + ]) +} + +var img_4x4_rgb_etc2 = { + compressed: new Uint8Array([ + 0x04, 0xf0, 0xf0, 0x02, 0x07, 0x45, 0x00, 0x00 + ]), + decompressed: new Uint8Array([ + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + ]) +} + +var img_4x4_rgb_punchthrough_etc2 = { + compressed: new Uint8Array([ + 0x04, 0xf0, 0xf0, 0x00, 0xbf, 0x5f, 0x02, 0x05, + ]), + decompressed: new Uint8Array([ + 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, + 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]) +} + +var img_4x4_rgba_etc2 = { + compressed: new Uint8Array([ + 0x44, 0x89, 0x69, 0x24, 0x41, 0x43, 0x04, 0x41, + 0x04, 0xf0, 0xf0, 0x02, 0x07, 0x45, 0x00, 0x00, + ]), + decompressed: new Uint8Array([ + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, + 0xff, 0x00, 0x00, 0x04, 0x00, 0xff, 0x00, 0x04, + 0x00, 0xff, 0x00, 0x04, 0x00, 0xff, 0x00, 0x1c, + 0xff, 0x00, 0x00, 0x34, 0x00, 0xff, 0x00, 0x1c, + 0xff, 0x00, 0x00, 0x04, 0xff, 0x00, 0x00, 0x34, + 0xff, 0x00, 0x00, 0x7c, 0x00, 0xff, 0x00, 0x34, + 0x00, 0xff, 0x00, 0x04, 0x00, 0xff, 0x00, 0x1c, + 0x00, 0xff, 0x00, 0x34, 0x00, 0xff, 0x00, 0x1c, + ]) +} + +var img_8x8_r11_eac = { + compressed: new Uint8Array([ + 0x0f, 0xf9, 0xbe, 0xff, 0xef, 0xb6, 0xff, 0xff, + 0x5e, 0xb3, 0xeb, 0xa4, 0xba, 0xff, 0xa4, 0x92, + 0x00, 0xf6, 0xfb, 0xed, 0xbe, 0xff, 0xed, 0xb6, + 0x2c, 0xfd, 0x1c, 0x7f, 0xc7, 0x00, 0x7f, 0xff, + ]), + decompressed: new Uint8Array([ + 0x4b, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0xe2, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0xe2, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0xe2, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x4b, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0xe2, 0x00, 0x00, 0xff, 0xe2, 0x00, 0x00, 0xff, + 0xe2, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0xb3, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0xb3, 0x00, 0x00, 0xff, + 0x69, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0xb3, 0x00, 0x00, 0xff, 0xb3, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0xb3, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0xb3, 0x00, 0x00, 0xff, + 0x69, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x69, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0xb3, 0x00, 0x00, 0xff, 0xb3, 0x00, 0x00, 0xff, + 0xb3, 0x00, 0x00, 0xff, 0xb3, 0x00, 0x00, 0xff, + ]) +} + +var img_8x8_signed_r11_eac = { + compressed: new Uint8Array([ + 0x90, 0xf9, 0xbe, 0xff, 0xef, 0xb6, 0xff, 0xff, + 0xdf, 0xb3, 0xeb, 0xa4, 0xba, 0xff, 0xa4, 0x92, + 0xfb, 0x20, 0xeb, 0xa4, 0xba, 0xff, 0xa4, 0x92, + 0xac, 0xfd, 0x1c, 0x7f, 0xc7, 0x00, 0x7f, 0xff, + ]), + decompressed: new Uint8Array([ + 0x4c, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0xe2, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0xe2, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0xe2, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x4c, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0xe2, 0x00, 0x00, 0xff, 0xe2, 0x00, 0x00, 0xff, + 0xe2, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0xb2, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0xb2, 0x00, 0x00, 0xff, + 0x69, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0xb2, 0x00, 0x00, 0xff, 0xb2, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0xb2, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x96, 0x00, 0x00, 0xff, + 0x96, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0xb2, 0x00, 0x00, 0xff, + 0x69, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x69, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0xb2, 0x00, 0x00, 0xff, 0xb2, 0x00, 0x00, 0xff, + 0xb2, 0x00, 0x00, 0xff, 0xb2, 0x00, 0x00, 0xff, + ]) +} + +var img_8x8_rg11_eac = { + compressed: new Uint8Array([ + 0x2e, 0xf0, 0xe7, 0x92, 0x79, 0xff, 0x92, 0x49, + 0x2e, 0xf0, 0x3c, 0xff, 0xcf, 0x24, 0xff, 0xff, + 0x2e, 0xf0, 0xe7, 0x92, 0x79, 0xff, 0x92, 0x49, + 0x2e, 0xf0, 0xe7, 0x92, 0x79, 0xff, 0x92, 0x49, + 0x2e, 0xf0, 0x3c, 0xff, 0xcf, 0x24, 0xff, 0xff, + 0x2e, 0xf0, 0xe7, 0x92, 0x79, 0xff, 0x92, 0x49, + 0x00, 0x00, 0x24, 0x92, 0x49, 0x24, 0x92, 0x49, + 0x2e, 0xf0, 0x3c, 0xff, 0xcf, 0x24, 0xff, 0xff, + ]), + decompressed: new Uint8Array([ + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + ]) +} + +var img_8x8_signed_rg11_eac = { + compressed: new Uint8Array([ + 0xae, 0xf0, 0xe7, 0x92, 0x79, 0xff, 0x92, 0x49, + 0xae, 0xf0, 0x3c, 0xff, 0xcf, 0x24, 0xff, 0xff, + 0xae, 0xf0, 0xe7, 0x92, 0x79, 0xff, 0x92, 0x49, + 0xae, 0xf0, 0xe7, 0x92, 0x79, 0xff, 0x92, 0x49, + 0xae, 0xf0, 0x3c, 0xff, 0xcf, 0x24, 0xff, 0xff, + 0xae, 0xf0, 0xe7, 0x92, 0x79, 0xff, 0x92, 0x49, + 0x80, 0x00, 0x49, 0x24, 0x92, 0x49, 0x24, 0x92, + 0xae, 0xf0, 0x3c, 0xff, 0xcf, 0x24, 0xff, 0xff, + ]), + decompressed: new Uint8Array([ + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + ]) +} + +var img_8x8_rgb_etc2 = { + compressed: new Uint8Array([ + 0x04, 0xf0, 0xf0, 0x02, 0x07, 0x45, 0x00, 0x00, + 0x04, 0x0f, 0xff, 0x02, 0x07, 0x45, 0x00, 0x00, + 0x04, 0xf0, 0xf0, 0xf2, 0xf8, 0xba, 0x00, 0x00, + 0x04, 0x0f, 0x0f, 0xf2, 0xf8, 0xba, 0x00, 0x00 + ]), + decompressed: new Uint8Array([ + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, + 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, + 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, + 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, + 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, + ]) +} + +var img_8x8_rgb_punchthrough_etc2 = { + compressed: new Uint8Array([ + 0x04, 0xf0, 0xf0, 0x00, 0x5f, 0xef, 0x01, 0x44, + 0xfb, 0xf0, 0x00, 0xf0, 0xfd, 0xfa, 0x10, 0x80, + 0xfb, 0x0f, 0x0f, 0x00, 0x7f, 0x6f, 0x02, 0x40, + 0x04, 0xff, 0x00, 0xf0, 0xf7, 0x6d, 0x05, 0x04, + ]), + decompressed: new Uint8Array([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, + 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + ]) +} + +var img_8x8_rgba_etc2 = { + compressed: new Uint8Array([ + 0x35, 0x83, 0x6d, 0x26, 0x88, 0x46, 0x64, 0x37, + 0x04, 0xf0, 0xf0, 0x02, 0x07, 0x45, 0x00, 0x00, + 0x69, 0xa8, 0x66, 0x76, 0x45, 0x68, 0x86, 0xd1, + 0x04, 0x0f, 0xff, 0x02, 0x07, 0x45, 0x00, 0x00, + 0x69, 0xa8, 0x6d, 0xb2, 0x53, 0x80, 0xaf, 0x41, + 0x04, 0xf0, 0xf0, 0xf2, 0xf8, 0xba, 0x00, 0x00, + 0x8c, 0xca, 0xf4, 0x2b, 0x0a, 0x05, 0x34, 0x9b, + 0x04, 0x0f, 0x0f, 0xf2, 0xf8, 0xba, 0x00, 0x00, + ]), + decompressed: new Uint8Array([ + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x05, 0x00, 0xff, 0x00, 0x05, + 0xff, 0xff, 0x00, 0x05, 0x00, 0x00, 0xff, 0x05, + 0xff, 0xff, 0x00, 0x05, 0x00, 0x00, 0xff, 0x05, + 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, + 0xff, 0x00, 0x00, 0x15, 0x00, 0xff, 0x00, 0x25, + 0x00, 0x00, 0xff, 0x2d, 0x00, 0x00, 0xff, 0x2d, + 0xff, 0xff, 0x00, 0x19, 0x00, 0x00, 0xff, 0x05, + 0xff, 0x00, 0x00, 0x05, 0xff, 0x00, 0x00, 0x15, + 0xff, 0x00, 0x00, 0x3d, 0x00, 0xff, 0x00, 0x5d, + 0xff, 0xff, 0x00, 0x73, 0xff, 0xff, 0x00, 0x55, + 0xff, 0xff, 0x00, 0x2d, 0x00, 0x00, 0xff, 0x19, + 0x00, 0xff, 0x00, 0x05, 0x00, 0xff, 0x00, 0x25, + 0x00, 0xff, 0x00, 0x5d, 0x00, 0xff, 0x00, 0x95, + 0x00, 0x00, 0xff, 0xc3, 0x00, 0x00, 0xff, 0x9b, + 0x00, 0x00, 0xff, 0x55, 0x00, 0x00, 0xff, 0x2d, + 0x00, 0xff, 0x00, 0x05, 0xff, 0x00, 0xff, 0x2d, + 0x00, 0xff, 0x00, 0x73, 0xff, 0x00, 0xff, 0xc3, + 0x00, 0x00, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xb0, + 0x00, 0x00, 0xff, 0x74, 0x00, 0xff, 0xff, 0x2c, + 0xff, 0x00, 0xff, 0x05, 0xff, 0x00, 0xff, 0x2d, + 0x00, 0xff, 0x00, 0x55, 0xff, 0x00, 0xff, 0x9b, + 0x00, 0xff, 0xff, 0xb0, 0x00, 0xff, 0xff, 0x98, + 0x00, 0x00, 0xff, 0x5c, 0x00, 0xff, 0xff, 0x2c, + 0x00, 0xff, 0x00, 0x05, 0x00, 0xff, 0x00, 0x19, + 0x00, 0xff, 0x00, 0x2d, 0xff, 0x00, 0xff, 0x55, + 0x00, 0x00, 0xff, 0x74, 0x00, 0x00, 0xff, 0x5c, + 0x00, 0x00, 0xff, 0x2c, 0x00, 0xff, 0xff, 0x14, + 0xff, 0x00, 0xff, 0x05, 0xff, 0x00, 0xff, 0x05, + 0xff, 0x00, 0xff, 0x19, 0xff, 0x00, 0xff, 0x2d, + 0x00, 0xff, 0xff, 0x2c, 0x00, 0xff, 0xff, 0x2c, + 0x00, 0xff, 0xff, 0x14, 0x00, 0xff, 0xff, 0x14, + ]) +} + +/* This image exercises every ETC2 block type */ +var img_32x32_r11_eac = { + compressed: new Uint8Array([ + 0x6e, 0x61, 0x92, 0x08, 0x02, 0x01, 0x12, 0x53, + 0x21, 0x32, 0xf2, 0x8d, 0x01, 0xf0, 0x9f, 0x02, + 0x2b, 0x4b, 0xd0, 0x9d, 0x41, 0xf0, 0x29, 0x12, + 0x1f, 0x30, 0xc0, 0x2e, 0x0a, 0xf0, 0xad, 0x02, + 0x20, 0x34, 0xf0, 0x1b, 0x42, 0xb6, 0x1a, 0x02, + 0x1e, 0x34, 0xb0, 0x8d, 0x0a, 0xb0, 0x3f, 0x0a, + 0x2a, 0x21, 0xf1, 0xbf, 0x1a, 0xf1, 0x3e, 0x0b, + 0x47, 0x32, 0x29, 0xb0, 0x52, 0xb0, 0x1f, 0xac, + 0x31, 0x4f, 0x9f, 0xc0, 0x49, 0x49, 0xb0, 0xdb, + 0x0a, 0x23, 0xda, 0x1c, 0x08, 0x18, 0x90, 0x21, + 0x08, 0x2d, 0x08, 0x0c, 0x92, 0x91, 0x22, 0x4a, + 0x04, 0x00, 0x40, 0x70, 0x87, 0x40, 0x30, 0x9f, + 0x0c, 0x1c, 0x61, 0x30, 0xd2, 0x61, 0x3a, 0x83, + 0x12, 0x14, 0x81, 0x9c, 0x8b, 0x50, 0xb4, 0x39, + 0x1a, 0x28, 0x66, 0x00, 0x64, 0xa0, 0x51, 0x45, + 0x2e, 0x33, 0x42, 0x02, 0x64, 0xb6, 0xdf, 0xff, + 0x34, 0x31, 0x82, 0x62, 0x08, 0x48, 0xb6, 0x9b, + 0x07, 0x2d, 0xa3, 0x45, 0x60, 0x2b, 0x10, 0x44, + 0x08, 0x18, 0x67, 0x12, 0x86, 0x24, 0x92, 0x5b, + 0x02, 0x00, 0xe0, 0x3e, 0x10, 0xe9, 0x74, 0xd5, + 0x08, 0x1c, 0x09, 0x44, 0x88, 0x84, 0xe9, 0xa4, + 0x16, 0x19, 0x4a, 0xdf, 0x6d, 0xbe, 0xd7, 0x6d, + 0x20, 0x11, 0x4f, 0xe6, 0xb6, 0xef, 0x6f, 0xf6, + 0x2f, 0x44, 0xb2, 0xc9, 0x24, 0xbb, 0x6f, 0xff, + 0x2c, 0x41, 0xdb, 0xf9, 0x65, 0x12, 0x44, 0x8c, + 0x07, 0x13, 0x09, 0x54, 0xdb, 0x29, 0xb4, 0x9a, + 0x01, 0x02, 0x6c, 0xf2, 0xd9, 0xb5, 0xbb, 0x6d, + 0x0e, 0x15, 0x64, 0x96, 0x40, 0x28, 0x41, 0x24, + 0x14, 0x13, 0x6a, 0x48, 0xe7, 0x5e, 0x7f, 0xbe, + 0x1e, 0x19, 0x92, 0x69, 0xa6, 0x87, 0x4f, 0xff, + 0x36, 0x14, 0x6d, 0x14, 0x40, 0x12, 0x5b, 0xb7, + 0x54, 0x2b, 0x6d, 0xa4, 0x91, 0x00, 0x0b, 0x6d, + 0x19, 0x43, 0xfe, 0xdf, 0xa4, 0xd8, 0x0d, 0x09, + 0x10, 0x21, 0xf0, 0x10, 0x00, 0x44, 0x04, 0x91, + 0x01, 0x23, 0x92, 0x49, 0x34, 0x9b, 0x69, 0x37, + 0x11, 0x18, 0x6c, 0x00, 0x07, 0xe2, 0xdf, 0xed, + 0x21, 0x23, 0x40, 0x28, 0x84, 0xd0, 0x49, 0xb0, + 0x13, 0x36, 0x9b, 0x6d, 0x36, 0xdf, 0xff, 0xff, + 0x38, 0x17, 0x26, 0x49, 0xb6, 0xda, 0xdf, 0xfe, + 0x60, 0x44, 0x49, 0x22, 0x49, 0x00, 0x09, 0x24, + 0x2c, 0x53, 0x9b, 0x62, 0x44, 0x29, 0x14, 0x89, + 0x0b, 0x1c, 0x93, 0xf0, 0x3f, 0x82, 0xd9, 0xfd, + 0x0f, 0x13, 0x3f, 0xf5, 0xbf, 0x3b, 0x6f, 0xf6, + 0x1e, 0x10, 0xb7, 0x27, 0x74, 0xa4, 0x43, 0x62, + 0x21, 0x1a, 0x00, 0x50, 0x07, 0x17, 0xfb, 0x6f, + 0x36, 0x11, 0x6c, 0x0c, 0x00, 0x96, 0xcd, 0x6c, + 0x3f, 0x1d, 0x80, 0xab, 0x01, 0xd6, 0x0d, 0xac, + 0x4c, 0x23, 0x49, 0x20, 0x00, 0xb6, 0xdf, 0xff, + 0x35, 0x20, 0xdb, 0xfd, 0xed, 0x36, 0xd6, 0x49, + 0x1e, 0x19, 0x22, 0xf4, 0x2f, 0x66, 0x66, 0x66, + 0x19, 0x13, 0x3b, 0x69, 0xb7, 0x9f, 0xfd, 0xbf, + 0x2b, 0x16, 0x4e, 0x76, 0x25, 0x02, 0x72, 0xaf, + 0x35, 0x10, 0x68, 0x54, 0x85, 0x03, 0x61, 0x26, + 0x39, 0x1d, 0x44, 0x42, 0x25, 0x12, 0xeb, 0x76, + 0x3d, 0x1d, 0x29, 0x20, 0x09, 0xb2, 0x4d, 0xb6, + 0x65, 0x37, 0x6d, 0xb4, 0x91, 0x20, 0x49, 0x77, + 0x68, 0x42, 0x17, 0xf4, 0x2f, 0x68, 0x56, 0xd5, + 0x49, 0x54, 0x02, 0x60, 0x26, 0x22, 0x62, 0x26, + 0x5a, 0x4c, 0x68, 0x56, 0x84, 0x68, 0x46, 0x84, + 0x4a, 0x27, 0x66, 0x74, 0x67, 0x46, 0x74, 0x2f, + 0x53, 0x2b, 0x68, 0x66, 0x85, 0x68, 0x56, 0x85, + 0x51, 0x2b, 0x68, 0x66, 0x86, 0x68, 0x66, 0x86, + 0x52, 0x25, 0x68, 0x46, 0x45, 0x66, 0x64, 0x27, + 0x77, 0x32, 0x6d, 0x16, 0x8c, 0x46, 0x61, 0x37, + ]), + decompressed: new Uint8Array([ + 0x7a, 0x00, 0x00, 0xff, 0x7a, 0x00, 0x00, 0xff, + 0x5c, 0x00, 0x00, 0xff, 0x44, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x36, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x45, 0x00, 0x00, 0xff, + 0x43, 0x00, 0x00, 0xff, 0x43, 0x00, 0x00, 0xff, + 0x4f, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x37, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x49, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x2d, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x2d, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x42, 0x00, 0x00, 0xff, 0x42, 0x00, 0x00, 0xff, + 0x42, 0x00, 0x00, 0xff, 0x42, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x41, 0x00, 0x00, 0xff, + 0x53, 0x00, 0x00, 0xff, 0x6b, 0x00, 0x00, 0xff, + 0x7a, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x5c, 0x00, 0x00, 0xff, 0x44, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x26, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x2e, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0x38, 0x00, 0x00, 0xff, + 0x4a, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x7a, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x32, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x2d, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x12, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x17, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x17, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x26, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x0c, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x10, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x53, 0x00, 0x00, 0xff, + 0x5c, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x1b, 0x00, 0x00, 0xff, 0x12, 0x00, 0x00, 0xff, + 0x12, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x17, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x08, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x08, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x10, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x10, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x4a, 0x00, 0x00, 0xff, + 0x39, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x08, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x19, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x22, 0x00, 0x00, 0xff, + 0x37, 0x00, 0x00, 0xff, 0x52, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x08, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x09, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x09, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x22, 0x00, 0x00, 0xff, + 0x37, 0x00, 0x00, 0xff, 0x52, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x0c, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x0c, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x31, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x37, 0x00, 0x00, 0xff, 0x52, 0x00, 0x00, 0xff, + 0x39, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x0c, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x37, 0x00, 0x00, 0xff, 0x52, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x09, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x13, 0x00, 0x00, 0xff, + 0x2c, 0x00, 0x00, 0xff, 0x2c, 0x00, 0x00, 0xff, + 0x43, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x43, 0x00, 0x00, 0xff, 0x5b, 0x00, 0x00, 0xff, + 0x2b, 0x00, 0x00, 0xff, 0x2b, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x13, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x13, 0x00, 0x00, 0xff, 0x2c, 0x00, 0x00, 0xff, + 0x37, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x5b, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x2c, 0x00, 0x00, 0xff, 0x29, 0x00, 0x00, 0xff, + 0x29, 0x00, 0x00, 0xff, 0x29, 0x00, 0x00, 0xff, + 0x43, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x5b, 0x00, 0x00, 0xff, + 0x4f, 0x00, 0x00, 0xff, 0x2b, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x29, 0x00, 0x00, 0xff, 0x29, 0x00, 0x00, 0xff, + 0x29, 0x00, 0x00, 0xff, 0x29, 0x00, 0x00, 0xff, + 0x37, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x5b, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x34, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x15, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x27, 0x00, 0x00, 0xff, + 0x2a, 0x00, 0x00, 0xff, 0x2e, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x44, 0x00, 0x00, 0xff, + 0x34, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x19, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x19, 0x00, 0x00, 0xff, 0x27, 0x00, 0x00, 0xff, + 0x2a, 0x00, 0x00, 0xff, 0x30, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x3d, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x5c, 0x00, 0x00, 0xff, 0x34, 0x00, 0x00, 0xff, + 0x34, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x15, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x27, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x3d, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x5c, 0x00, 0x00, 0xff, 0x44, 0x00, 0x00, 0xff, + 0x34, 0x00, 0x00, 0xff, 0x34, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x10, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x19, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x27, 0x00, 0x00, 0xff, + 0x30, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x3b, 0x00, 0x00, 0xff, 0x41, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x4a, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x49, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x2d, 0x00, 0x00, 0xff, 0x2d, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x2b, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x42, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x54, 0x00, 0x00, 0xff, 0x68, 0x00, 0x00, 0xff, + 0x49, 0x00, 0x00, 0xff, 0x2d, 0x00, 0x00, 0xff, + 0x2d, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x15, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x2b, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x31, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x42, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x54, 0x00, 0x00, 0xff, 0x68, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x11, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x2b, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x31, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x3c, 0x00, 0x00, 0xff, 0x42, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x54, 0x00, 0x00, 0xff, 0x68, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x11, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x19, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x31, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x3c, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x54, 0x00, 0x00, 0xff, 0x68, 0x00, 0x00, 0xff, + 0x31, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x18, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x08, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x29, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x41, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x52, 0x00, 0x00, 0xff, 0x64, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x08, 0x00, 0x00, 0xff, + 0x08, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x1b, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x18, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x29, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x3c, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x41, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x52, 0x00, 0x00, 0xff, 0x64, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x22, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x1b, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x26, 0x00, 0x00, 0xff, 0x26, 0x00, 0x00, 0xff, + 0x1b, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x2a, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x3c, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3e, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x52, 0x00, 0x00, 0xff, 0x64, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x18, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x1b, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x15, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x2a, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x38, 0x00, 0x00, 0xff, + 0x3c, 0x00, 0x00, 0xff, 0x3d, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x52, 0x00, 0x00, 0xff, 0x64, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x45, 0x00, 0x00, 0xff, + 0x29, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x19, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x27, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x26, 0x00, 0x00, 0xff, 0x2c, 0x00, 0x00, 0xff, + 0x32, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x36, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3b, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x4d, 0x00, 0x00, 0xff, + 0x56, 0x00, 0x00, 0xff, 0x6b, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x51, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x29, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x19, 0x00, 0x00, 0xff, 0x19, 0x00, 0x00, 0xff, + 0x1e, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x27, 0x00, 0x00, 0xff, + 0x27, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x2c, 0x00, 0x00, 0xff, 0x2c, 0x00, 0x00, 0xff, + 0x32, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x37, 0x00, 0x00, 0xff, 0x38, 0x00, 0x00, 0xff, + 0x39, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x4d, 0x00, 0x00, 0xff, + 0x5c, 0x00, 0x00, 0xff, 0x71, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x29, 0x00, 0x00, 0xff, + 0x22, 0x00, 0x00, 0xff, 0x22, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x1e, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x2e, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x32, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x39, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x4d, 0x00, 0x00, 0xff, + 0x5c, 0x00, 0x00, 0xff, 0x7a, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x29, 0x00, 0x00, 0xff, + 0x27, 0x00, 0x00, 0xff, 0x27, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x1e, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x35, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x35, 0x00, 0x00, 0xff, 0x35, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3d, 0x00, 0x00, 0xff, + 0x39, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3b, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x56, 0x00, 0x00, 0xff, + 0x6b, 0x00, 0x00, 0xff, 0x83, 0x00, 0x00, 0xff, + 0x60, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x34, 0x00, 0x00, 0xff, 0x34, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x2b, 0x00, 0x00, 0xff, 0x2b, 0x00, 0x00, 0xff, + 0x32, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x32, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x34, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3d, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3d, 0x00, 0x00, 0xff, + 0x3c, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x3c, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x50, 0x00, 0x00, 0xff, + 0x5f, 0x00, 0x00, 0xff, 0x71, 0x00, 0x00, 0xff, + 0x78, 0x00, 0x00, 0xff, 0x60, 0x00, 0x00, 0xff, + 0x48, 0x00, 0x00, 0xff, 0x34, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3e, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3e, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x44, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x45, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x45, 0x00, 0x00, 0xff, + 0x43, 0x00, 0x00, 0xff, 0x43, 0x00, 0x00, 0xff, + 0x43, 0x00, 0x00, 0xff, 0x43, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x44, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x4c, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x5f, 0x00, 0x00, 0xff, + 0x68, 0x00, 0x00, 0xff, 0x7a, 0x00, 0x00, 0xff, + 0x98, 0x00, 0x00, 0xff, 0x78, 0x00, 0x00, 0xff, + 0x60, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x53, 0x00, 0x00, 0xff, 0x53, 0x00, 0x00, 0xff, + 0x53, 0x00, 0x00, 0xff, 0x53, 0x00, 0x00, 0xff, + 0x4e, 0x00, 0x00, 0xff, 0x4e, 0x00, 0x00, 0xff, + 0x4e, 0x00, 0x00, 0xff, 0x4e, 0x00, 0x00, 0xff, + 0x4e, 0x00, 0x00, 0xff, 0x4e, 0x00, 0x00, 0xff, + 0x4e, 0x00, 0x00, 0xff, 0x52, 0x00, 0x00, 0xff, + 0x4f, 0x00, 0x00, 0xff, 0x4f, 0x00, 0x00, 0xff, + 0x4f, 0x00, 0x00, 0xff, 0x4f, 0x00, 0x00, 0xff, + 0x4d, 0x00, 0x00, 0xff, 0x4d, 0x00, 0x00, 0xff, + 0x4d, 0x00, 0x00, 0xff, 0x4d, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x4c, 0x00, 0x00, 0xff, + 0x56, 0x00, 0x00, 0xff, 0x56, 0x00, 0x00, 0xff, + 0x5f, 0x00, 0x00, 0xff, 0x68, 0x00, 0x00, 0xff, + 0x7a, 0x00, 0x00, 0xff, 0x8c, 0x00, 0x00, 0xff, + 0x98, 0x00, 0x00, 0xff, 0x98, 0x00, 0x00, 0xff, + 0x78, 0x00, 0x00, 0xff, 0x78, 0x00, 0x00, 0xff, + 0x6c, 0x00, 0x00, 0xff, 0x6c, 0x00, 0x00, 0xff, + 0x6c, 0x00, 0x00, 0xff, 0x6c, 0x00, 0x00, 0xff, + 0x66, 0x00, 0x00, 0xff, 0x62, 0x00, 0x00, 0xff, + 0x62, 0x00, 0x00, 0xff, 0x62, 0x00, 0x00, 0xff, + 0x5e, 0x00, 0x00, 0xff, 0x5e, 0x00, 0x00, 0xff, + 0x5e, 0x00, 0x00, 0xff, 0x5e, 0x00, 0x00, 0xff, + 0x5f, 0x00, 0x00, 0xff, 0x5b, 0x00, 0x00, 0xff, + 0x5b, 0x00, 0x00, 0xff, 0x5b, 0x00, 0x00, 0xff, + 0x5d, 0x00, 0x00, 0xff, 0x5d, 0x00, 0x00, 0xff, + 0x5d, 0x00, 0x00, 0xff, 0x5d, 0x00, 0x00, 0xff, + 0x56, 0x00, 0x00, 0xff, 0x5e, 0x00, 0x00, 0xff, + 0x62, 0x00, 0x00, 0xff, 0x66, 0x00, 0x00, 0xff, + 0x68, 0x00, 0x00, 0xff, 0x7a, 0x00, 0x00, 0xff, + 0x8c, 0x00, 0x00, 0xff, 0x9b, 0x00, 0x00, 0xff, + ]) +} + +var img_32x32_signed_r11_eac = { + compressed: new Uint8Array([ + 0xef, 0x61, 0x92, 0x08, 0x02, 0x01, 0x12, 0x53, + 0xa2, 0x32, 0xf2, 0x8d, 0x01, 0xf0, 0x9f, 0x02, + 0xab, 0x4b, 0xd0, 0x9d, 0x41, 0xf0, 0x29, 0x12, + 0xa0, 0x30, 0xc0, 0x2e, 0x0a, 0xf0, 0xad, 0x02, + 0xa1, 0x34, 0xf0, 0x1b, 0x42, 0xb6, 0x1a, 0x02, + 0x9f, 0x34, 0xb0, 0x8d, 0x0a, 0xb0, 0x3f, 0x0a, + 0xaa, 0x21, 0xf1, 0xbf, 0x1a, 0xf1, 0x3e, 0x0b, + 0xc8, 0x32, 0x29, 0xb0, 0x52, 0xb0, 0x1f, 0xac, + 0xb2, 0x4f, 0x9f, 0xc0, 0x49, 0x49, 0xb0, 0xdb, + 0x8a, 0x16, 0xfe, 0x1e, 0x08, 0x1d, 0x20, 0x22, + 0x88, 0x2d, 0x08, 0x0c, 0x92, 0x91, 0x10, 0x02, + 0x85, 0x1d, 0x20, 0x60, 0x46, 0x20, 0x20, 0x56, + 0x8c, 0x1c, 0x61, 0x30, 0xd2, 0x61, 0x3a, 0x83, + 0x93, 0x11, 0x81, 0x9c, 0x8b, 0x50, 0xb4, 0x39, + 0x94, 0x2f, 0x42, 0xc8, 0x2d, 0xf2, 0x79, 0xe7, + 0xaf, 0x33, 0x42, 0x02, 0x64, 0xb6, 0xdf, 0xff, + 0xb5, 0x31, 0x82, 0x62, 0x08, 0x48, 0xb6, 0x9b, + 0x84, 0x1a, 0xd7, 0x51, 0xac, 0x83, 0x0b, 0x25, + 0x8a, 0x16, 0x66, 0xa4, 0x85, 0x49, 0x22, 0x5b, + 0x83, 0x1d, 0xa0, 0x2a, 0x08, 0xc4, 0xe2, 0x8c, + 0x8d, 0x15, 0x2d, 0x86, 0xd1, 0x09, 0x41, 0x00, + 0x96, 0x19, 0x4a, 0xdf, 0x6d, 0xbe, 0xd7, 0x6d, + 0xa1, 0x11, 0x4f, 0xe6, 0xb6, 0xef, 0x6f, 0xf6, + 0xb0, 0x44, 0xb2, 0xc9, 0x24, 0xbb, 0x6f, 0xff, + 0xad, 0x41, 0xdb, 0xf9, 0x65, 0x12, 0x44, 0x8c, + 0x82, 0x1d, 0xd2, 0x78, 0x49, 0xa0, 0x90, 0x08, + 0x82, 0x00, 0x6c, 0xe2, 0xd9, 0x91, 0xb9, 0x24, + 0x8e, 0x15, 0x64, 0x96, 0x40, 0x28, 0x41, 0x24, + 0x95, 0x13, 0x6a, 0x48, 0xe7, 0x5c, 0x7f, 0xbe, + 0xa1, 0x18, 0x00, 0x51, 0x45, 0x0a, 0x8d, 0xb6, + 0xb7, 0x14, 0x6d, 0x14, 0x40, 0x12, 0x5b, 0xb7, + 0xcf, 0x10, 0x6d, 0xa4, 0x89, 0x92, 0x4f, 0xff, + 0x99, 0x43, 0xfe, 0xdf, 0xa4, 0xd8, 0x0d, 0x09, + 0x90, 0x21, 0xf0, 0x10, 0x00, 0x44, 0x02, 0x89, + 0x89, 0x2d, 0x49, 0x24, 0xaa, 0x56, 0xd4, 0xaf, + 0x91, 0x18, 0x6c, 0x00, 0x07, 0xe2, 0xdf, 0xed, + 0xa1, 0x23, 0x40, 0x28, 0x84, 0xd0, 0x49, 0xb0, + 0x93, 0x36, 0x9b, 0x6d, 0x36, 0xdf, 0xff, 0xff, + 0xbc, 0x12, 0x48, 0x01, 0x6d, 0xb6, 0x4d, 0xb5, + 0xe1, 0x44, 0x49, 0x22, 0x49, 0x00, 0x09, 0x24, + 0xad, 0x53, 0x9b, 0x62, 0x44, 0x29, 0x14, 0x89, + 0x8b, 0x1c, 0x93, 0xf0, 0x3f, 0x82, 0xd9, 0xfd, + 0x91, 0x16, 0x1f, 0xf3, 0x3f, 0x12, 0x4f, 0xe4, + 0x9e, 0x10, 0xb7, 0x27, 0x74, 0xa4, 0x43, 0x62, + 0xa1, 0x1a, 0x00, 0x50, 0x07, 0x17, 0xfb, 0x6f, + 0xb6, 0x11, 0x6c, 0x0c, 0x00, 0x96, 0xcd, 0x6c, + 0xc0, 0x1d, 0x05, 0x28, 0x0a, 0xb0, 0x1d, 0x60, + 0xcd, 0x23, 0x49, 0x20, 0x00, 0xb6, 0xdf, 0xff, + 0xb6, 0x20, 0xdb, 0xfd, 0xed, 0x36, 0xd6, 0x49, + 0x9f, 0x19, 0x22, 0xf4, 0x67, 0x66, 0x66, 0x66, + 0x99, 0x13, 0x3b, 0x6b, 0xb7, 0xbf, 0xfd, 0xbf, + 0xab, 0x17, 0x4e, 0xf6, 0x2e, 0x02, 0xf2, 0xb7, + 0xb1, 0x11, 0x42, 0x60, 0x26, 0x93, 0xf9, 0x6f, + 0xba, 0x1d, 0x48, 0x84, 0x44, 0x22, 0x59, 0x2e, + 0xbd, 0x1d, 0x29, 0x20, 0x09, 0xb2, 0x4d, 0xb6, + 0xe6, 0x37, 0x6d, 0xb4, 0x91, 0x20, 0x49, 0x77, + 0xe8, 0x42, 0x17, 0xf4, 0x2f, 0x68, 0x56, 0xd5, + 0xc9, 0x54, 0x02, 0x60, 0x26, 0x22, 0x62, 0x26, + 0xcc, 0x21, 0x66, 0x76, 0x67, 0x66, 0x76, 0x67, + 0xcb, 0x27, 0x66, 0x74, 0x67, 0x46, 0x74, 0x2f, + 0xd4, 0x2b, 0x68, 0x66, 0x85, 0x68, 0x56, 0x85, + 0xd2, 0x2b, 0x68, 0x66, 0x86, 0x68, 0x66, 0x86, + 0xd3, 0x25, 0x68, 0x46, 0x45, 0x66, 0x64, 0x27, + 0xf8, 0x32, 0x6d, 0x16, 0x8c, 0x46, 0x61, 0x37, + ]), + decompressed: new Uint8Array([ + 0x7b, 0x00, 0x00, 0xff, 0x7b, 0x00, 0x00, 0xff, + 0x5d, 0x00, 0x00, 0xff, 0x45, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0xff, + 0x43, 0x00, 0x00, 0xff, 0x43, 0x00, 0x00, 0xff, + 0x4f, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x4a, 0x00, 0x00, 0xff, + 0x4a, 0x00, 0x00, 0xff, 0x38, 0x00, 0x00, 0xff, + 0x42, 0x00, 0x00, 0xff, 0x30, 0x00, 0x00, 0xff, + 0x30, 0x00, 0x00, 0xff, 0x30, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x34, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x42, 0x00, 0x00, 0xff, 0x42, 0x00, 0x00, 0xff, + 0x42, 0x00, 0x00, 0xff, 0x42, 0x00, 0x00, 0xff, + 0x39, 0x00, 0x00, 0xff, 0x42, 0x00, 0x00, 0xff, + 0x54, 0x00, 0x00, 0xff, 0x6c, 0x00, 0x00, 0xff, + 0x7b, 0x00, 0x00, 0xff, 0x5d, 0x00, 0x00, 0xff, + 0x5d, 0x00, 0x00, 0xff, 0x45, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x17, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x26, 0x00, 0x00, 0xff, 0x26, 0x00, 0x00, 0xff, + 0x27, 0x00, 0x00, 0xff, 0x30, 0x00, 0x00, 0xff, + 0x30, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x2e, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x30, 0x00, 0x00, 0xff, 0x39, 0x00, 0x00, 0xff, + 0x4b, 0x00, 0x00, 0xff, 0x5d, 0x00, 0x00, 0xff, + 0x7b, 0x00, 0x00, 0xff, 0x5d, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x13, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x17, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x17, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x18, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x27, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x10, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x21, 0x00, 0x00, 0xff, 0x30, 0x00, 0x00, 0xff, + 0x42, 0x00, 0x00, 0xff, 0x54, 0x00, 0x00, 0xff, + 0x5d, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x21, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x13, 0x00, 0x00, 0xff, + 0x13, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x17, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x10, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x10, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x21, 0x00, 0x00, 0xff, 0x30, 0x00, 0x00, 0xff, + 0x39, 0x00, 0x00, 0xff, 0x4b, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x26, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x26, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x08, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x09, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x53, 0x00, 0x00, 0xff, + 0x52, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x08, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x09, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x09, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x10, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x18, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x29, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x53, 0x00, 0x00, 0xff, + 0x52, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x0c, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x18, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x32, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x53, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x0c, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x18, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x29, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x53, 0x00, 0x00, 0xff, + 0x3b, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x17, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0xff, + 0x17, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x2d, 0x00, 0x00, 0xff, 0x2d, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x38, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x2c, 0x00, 0x00, 0xff, 0x2c, 0x00, 0x00, 0xff, + 0x17, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x2d, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x38, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x3b, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x10, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x2d, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x2a, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x38, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x2c, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x2a, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x2a, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x38, 0x00, 0x00, 0xff, + 0x4c, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x35, 0x00, 0x00, 0xff, + 0x21, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x04, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x08, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x21, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x2b, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x34, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x5d, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x45, 0x00, 0x00, 0xff, + 0x35, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x05, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x08, 0x00, 0x00, 0xff, + 0x21, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x26, 0x00, 0x00, 0xff, + 0x19, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x2b, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x39, 0x00, 0x00, 0xff, 0x3e, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x5d, 0x00, 0x00, 0xff, + 0x5d, 0x00, 0x00, 0xff, 0x35, 0x00, 0x00, 0xff, + 0x35, 0x00, 0x00, 0xff, 0x11, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x13, 0x00, 0x00, 0xff, 0x21, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x26, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0x34, 0x00, 0x00, 0xff, + 0x39, 0x00, 0x00, 0xff, 0x3e, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x5d, 0x00, 0x00, 0xff, + 0x5d, 0x00, 0x00, 0xff, 0x45, 0x00, 0x00, 0xff, + 0x35, 0x00, 0x00, 0xff, 0x35, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x10, 0x00, 0x00, 0xff, 0x10, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x21, 0x00, 0x00, 0xff, + 0x21, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x26, 0x00, 0x00, 0xff, 0x26, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x31, 0x00, 0x00, 0xff, 0x34, 0x00, 0x00, 0xff, + 0x3c, 0x00, 0x00, 0xff, 0x42, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x5d, 0x00, 0x00, 0xff, + 0x49, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x2d, 0x00, 0x00, 0xff, 0x2d, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x2b, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x34, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x43, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x55, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x49, 0x00, 0x00, 0xff, 0x2d, 0x00, 0x00, 0xff, + 0x2d, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x07, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x15, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x2b, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x31, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x34, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x43, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x55, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x11, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x2b, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x31, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x43, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x55, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x11, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xff, + 0x02, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, + 0x0b, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xff, 0x16, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x31, 0x00, 0x00, 0xff, 0x31, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x55, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x32, 0x00, 0x00, 0xff, 0x19, 0x00, 0x00, 0xff, + 0x19, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x08, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x29, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x42, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x53, 0x00, 0x00, 0xff, 0x65, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x19, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0x08, 0x00, 0x00, 0xff, + 0x08, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x1b, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x18, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x29, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x3c, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x41, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x53, 0x00, 0x00, 0xff, 0x65, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0x19, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x1b, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x26, 0x00, 0x00, 0xff, 0x26, 0x00, 0x00, 0xff, + 0x1b, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x1f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0x2a, 0x00, 0x00, 0xff, 0x24, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x3c, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3e, 0x00, 0x00, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x53, 0x00, 0x00, 0xff, 0x65, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x19, 0x00, 0x00, 0xff, 0x19, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x0e, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0x1b, 0x00, 0x00, 0xff, 0x1b, 0x00, 0x00, 0xff, + 0x14, 0x00, 0x00, 0xff, 0x14, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x15, 0x00, 0x00, 0xff, + 0x24, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x2a, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x38, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3d, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x49, 0x00, 0x00, 0xff, + 0x53, 0x00, 0x00, 0xff, 0x65, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0xff, + 0x2a, 0x00, 0x00, 0xff, 0x18, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x15, 0x00, 0x00, 0xff, + 0x15, 0x00, 0x00, 0xff, 0x1c, 0x00, 0x00, 0xff, + 0x1c, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x26, 0x00, 0x00, 0xff, + 0x27, 0x00, 0x00, 0xff, 0x2e, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x37, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3b, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x4e, 0x00, 0x00, 0xff, + 0x57, 0x00, 0x00, 0xff, 0x6c, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x52, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x1d, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1a, 0x00, 0x00, 0xff, 0x1a, 0x00, 0x00, 0xff, + 0x1e, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x23, 0x00, 0x00, 0xff, + 0x2e, 0x00, 0x00, 0xff, 0x2e, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x37, 0x00, 0x00, 0xff, 0x38, 0x00, 0x00, 0xff, + 0x39, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x4e, 0x00, 0x00, 0xff, + 0x5d, 0x00, 0x00, 0xff, 0x72, 0x00, 0x00, 0xff, + 0x52, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x23, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x20, 0x00, 0x00, 0xff, 0x20, 0x00, 0x00, 0xff, + 0x1e, 0x00, 0x00, 0xff, 0x1e, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0x2f, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x37, 0x00, 0x00, 0xff, + 0x38, 0x00, 0x00, 0xff, 0x39, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x4e, 0x00, 0x00, 0xff, + 0x5d, 0x00, 0x00, 0xff, 0x7b, 0x00, 0x00, 0xff, + 0x52, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x2a, 0x00, 0x00, 0xff, + 0x28, 0x00, 0x00, 0xff, 0x28, 0x00, 0x00, 0xff, + 0x26, 0x00, 0x00, 0xff, 0x26, 0x00, 0x00, 0xff, + 0x1e, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x25, 0x00, 0x00, 0xff, 0x25, 0x00, 0x00, 0xff, + 0x35, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x35, 0x00, 0x00, 0xff, 0x35, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3d, 0x00, 0x00, 0xff, + 0x39, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3b, 0x00, 0x00, 0xff, 0x3c, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x57, 0x00, 0x00, 0xff, + 0x6c, 0x00, 0x00, 0xff, 0x83, 0x00, 0x00, 0xff, + 0x60, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x34, 0x00, 0x00, 0xff, 0x34, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x2b, 0x00, 0x00, 0xff, 0x2b, 0x00, 0x00, 0xff, + 0x32, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x32, 0x00, 0x00, 0xff, 0x32, 0x00, 0x00, 0xff, + 0x35, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x3b, 0x00, 0x00, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x40, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3e, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3e, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x3d, 0x00, 0x00, 0xff, + 0x3d, 0x00, 0x00, 0xff, 0x41, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x51, 0x00, 0x00, 0xff, + 0x60, 0x00, 0x00, 0xff, 0x72, 0x00, 0x00, 0xff, + 0x78, 0x00, 0x00, 0xff, 0x60, 0x00, 0x00, 0xff, + 0x48, 0x00, 0x00, 0xff, 0x34, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3e, 0x00, 0x00, 0xff, + 0x3e, 0x00, 0x00, 0xff, 0x3e, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x41, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x45, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0xff, + 0x46, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x44, 0x00, 0x00, 0xff, + 0x44, 0x00, 0x00, 0xff, 0x44, 0x00, 0x00, 0xff, + 0x41, 0x00, 0x00, 0xff, 0x45, 0x00, 0x00, 0xff, + 0x45, 0x00, 0x00, 0xff, 0x4d, 0x00, 0x00, 0xff, + 0x51, 0x00, 0x00, 0xff, 0x60, 0x00, 0x00, 0xff, + 0x69, 0x00, 0x00, 0xff, 0x7b, 0x00, 0x00, 0xff, + 0x97, 0x00, 0x00, 0xff, 0x78, 0x00, 0x00, 0xff, + 0x60, 0x00, 0x00, 0xff, 0x48, 0x00, 0x00, 0xff, + 0x53, 0x00, 0x00, 0xff, 0x53, 0x00, 0x00, 0xff, + 0x53, 0x00, 0x00, 0xff, 0x53, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x50, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x50, 0x00, 0x00, 0xff, + 0x4f, 0x00, 0x00, 0xff, 0x4f, 0x00, 0x00, 0xff, + 0x4f, 0x00, 0x00, 0xff, 0x53, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x50, 0x00, 0x00, 0xff, + 0x50, 0x00, 0x00, 0xff, 0x50, 0x00, 0x00, 0xff, + 0x4e, 0x00, 0x00, 0xff, 0x4e, 0x00, 0x00, 0xff, + 0x4e, 0x00, 0x00, 0xff, 0x4e, 0x00, 0x00, 0xff, + 0x4d, 0x00, 0x00, 0xff, 0x4d, 0x00, 0x00, 0xff, + 0x57, 0x00, 0x00, 0xff, 0x57, 0x00, 0x00, 0xff, + 0x60, 0x00, 0x00, 0xff, 0x69, 0x00, 0x00, 0xff, + 0x7b, 0x00, 0x00, 0xff, 0x8c, 0x00, 0x00, 0xff, + 0x97, 0x00, 0x00, 0xff, 0x97, 0x00, 0x00, 0xff, + 0x78, 0x00, 0x00, 0xff, 0x78, 0x00, 0x00, 0xff, + 0x6c, 0x00, 0x00, 0xff, 0x6c, 0x00, 0x00, 0xff, + 0x6c, 0x00, 0x00, 0xff, 0x6c, 0x00, 0x00, 0xff, + 0x64, 0x00, 0x00, 0xff, 0x64, 0x00, 0x00, 0xff, + 0x64, 0x00, 0x00, 0xff, 0x64, 0x00, 0x00, 0xff, + 0x5f, 0x00, 0x00, 0xff, 0x5f, 0x00, 0x00, 0xff, + 0x5f, 0x00, 0x00, 0xff, 0x5f, 0x00, 0x00, 0xff, + 0x60, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x5c, 0x00, 0x00, 0xff, 0x5c, 0x00, 0x00, 0xff, + 0x5e, 0x00, 0x00, 0xff, 0x5e, 0x00, 0x00, 0xff, + 0x5e, 0x00, 0x00, 0xff, 0x5e, 0x00, 0x00, 0xff, + 0x57, 0x00, 0x00, 0xff, 0x5f, 0x00, 0x00, 0xff, + 0x63, 0x00, 0x00, 0xff, 0x67, 0x00, 0x00, 0xff, + 0x69, 0x00, 0x00, 0xff, 0x7b, 0x00, 0x00, 0xff, + 0x8c, 0x00, 0x00, 0xff, 0x9b, 0x00, 0x00, 0xff, + ]) +} + +var img_32x32_rg11_eac = { + compressed: new Uint8Array([ + 0xa3, 0x8b, 0x92, 0x08, 0x02, 0x01, 0x12, 0x53, + 0x88, 0x72, 0xdb, 0x5d, 0x68, 0xb4, 0x49, 0x01, + 0x54, 0x30, 0xf2, 0x8d, 0x02, 0xf1, 0x2f, 0x03, + 0x64, 0x30, 0xf2, 0x8d, 0x02, 0xf1, 0x2f, 0x03, + 0x5f, 0x47, 0xd1, 0x1d, 0x42, 0xf0, 0x39, 0x1b, + 0x70, 0x47, 0xd1, 0x1d, 0x42, 0xf0, 0x39, 0x1b, + 0x57, 0x62, 0xa0, 0x2c, 0x0a, 0xd0, 0xab, 0x02, + 0x69, 0x67, 0xa0, 0xbc, 0x13, 0xd1, 0x3b, 0x0b, + 0x54, 0x30, 0xf0, 0x2d, 0x83, 0xda, 0xac, 0x43, + 0x64, 0x30, 0xf0, 0x2d, 0x83, 0xda, 0xac, 0x43, + 0x4a, 0x7b, 0xd4, 0x4d, 0x41, 0xd6, 0x2f, 0x41, + 0x4a, 0x7b, 0xd4, 0x4d, 0x41, 0xd6, 0x2f, 0x41, + 0x71, 0xbd, 0xd1, 0x2d, 0x11, 0xd0, 0xac, 0x02, + 0x5e, 0x44, 0xf5, 0x2f, 0x51, 0xf4, 0xaf, 0x02, + 0x9f, 0x49, 0x48, 0x92, 0x04, 0x92, 0xdb, 0xb7, + 0x85, 0x6b, 0x05, 0x38, 0x0a, 0xb0, 0x1d, 0x60, + 0x69, 0x69, 0xbb, 0x58, 0x00, 0x25, 0x20, 0x9a, + 0x69, 0x69, 0xbb, 0x58, 0x00, 0x25, 0x20, 0x9a, + 0x1c, 0x32, 0xfe, 0xae, 0x10, 0x9c, 0x99, 0x31, + 0x33, 0x44, 0xda, 0x2c, 0x10, 0x19, 0x20, 0x22, + 0x17, 0x22, 0x8a, 0x4e, 0x92, 0xb5, 0x90, 0x03, + 0x24, 0x20, 0x86, 0x4e, 0x49, 0x91, 0xa0, 0x03, + 0x13, 0x3d, 0x18, 0xea, 0x0e, 0x14, 0xbc, 0x1e, + 0x0c, 0x20, 0x9b, 0x7b, 0x37, 0x97, 0x0d, 0x07, + 0x01, 0x8f, 0x96, 0x4b, 0x24, 0x96, 0x4d, 0x2c, + 0x29, 0x3a, 0x54, 0x2a, 0x80, 0x54, 0x2e, 0x2a, + 0x5c, 0x47, 0x29, 0x00, 0xc2, 0x64, 0x26, 0xb0, + 0x41, 0x34, 0xb1, 0x9c, 0x0b, 0x14, 0xb1, 0x31, + 0x6a, 0x44, 0x6a, 0xc0, 0xad, 0x82, 0x61, 0x26, + 0x45, 0x20, 0x66, 0x0a, 0x64, 0xf4, 0x6b, 0xc6, + 0xb4, 0x4b, 0x64, 0x14, 0x80, 0x92, 0x4f, 0xff, + 0x64, 0x47, 0x64, 0x14, 0x80, 0x00, 0x0b, 0x6d, + 0x5d, 0x62, 0xb2, 0xe1, 0x04, 0x24, 0x24, 0x52, + 0x6d, 0x62, 0xb2, 0xe1, 0x04, 0x24, 0x24, 0x52, + 0x17, 0x2a, 0xf7, 0xd5, 0xe8, 0x0b, 0xaa, 0x05, + 0x20, 0x2a, 0xf7, 0xd5, 0xe8, 0x0b, 0xaa, 0x05, + 0x0e, 0x3d, 0x77, 0xb4, 0xe7, 0x49, 0xbb, 0x5b, + 0x1f, 0x30, 0x63, 0x82, 0xaf, 0x24, 0x00, 0x1b, + 0x0d, 0x42, 0x80, 0x18, 0x08, 0xd2, 0x68, 0x25, + 0x0f, 0x2a, 0xf6, 0xaf, 0x45, 0xe0, 0x70, 0x85, + 0x3f, 0x42, 0x09, 0x44, 0x88, 0xa0, 0x6b, 0xad, + 0x17, 0x2a, 0xa9, 0x74, 0x85, 0xa9, 0x7b, 0xed, + 0x6f, 0x23, 0x6f, 0xfb, 0xff, 0xf7, 0xf3, 0xff, + 0x06, 0xb2, 0xb6, 0xdd, 0x6d, 0xba, 0xd9, 0x6d, + 0xa3, 0x37, 0x2e, 0xf6, 0x7f, 0xaf, 0xfb, 0x7f, + 0x1c, 0x5d, 0x73, 0x88, 0xc0, 0xf0, 0x0f, 0xc0, + 0x7a, 0xb5, 0xdb, 0x6d, 0xb6, 0xdf, 0xff, 0xff, + 0x5a, 0xbd, 0x8a, 0x24, 0x92, 0x80, 0x0d, 0xb6, + 0x63, 0x50, 0xb7, 0x69, 0x24, 0x12, 0x46, 0xd4, + 0x71, 0x67, 0xdb, 0xfb, 0xae, 0x12, 0x46, 0xd4, + 0x1a, 0x3c, 0x84, 0xf2, 0xdb, 0x2d, 0xb6, 0xdb, + 0x1a, 0x3c, 0x84, 0xf2, 0xdb, 0x2d, 0xb6, 0xdb, + 0x01, 0x2f, 0x02, 0x78, 0x04, 0xb4, 0x0b, 0x6d, + 0x01, 0x20, 0x02, 0x68, 0x04, 0xd8, 0x0d, 0xb6, + 0x2e, 0x42, 0x40, 0x04, 0x24, 0x82, 0xeb, 0xb6, + 0x28, 0x2a, 0x56, 0xd5, 0x7f, 0x0a, 0xfb, 0xff, + 0x64, 0x47, 0x42, 0x48, 0xa6, 0x9e, 0xff, 0xbe, + 0x31, 0x20, 0x66, 0xda, 0xef, 0x58, 0x6d, 0x34, + 0xab, 0x20, 0x49, 0x04, 0x10, 0x4c, 0x2d, 0xb6, + 0x2e, 0x20, 0x92, 0x69, 0xa6, 0x83, 0x46, 0xdb, + 0xd9, 0x2b, 0x6d, 0x12, 0x44, 0x12, 0xeb, 0xbf, + 0x0a, 0x19, 0x25, 0x28, 0x01, 0xb6, 0x4f, 0xb5, + 0xe5, 0x1f, 0x97, 0x79, 0x77, 0x97, 0x79, 0x77, + 0x4c, 0x4c, 0x6d, 0xb0, 0x49, 0xb6, 0xcf, 0xff, + 0x55, 0x47, 0xff, 0x6f, 0x24, 0x90, 0x08, 0x52, + 0x4d, 0x62, 0xfe, 0xdf, 0xa4, 0xd8, 0x0d, 0x49, + 0x2f, 0x5a, 0xf4, 0x20, 0x00, 0x66, 0xd4, 0xd1, + 0x32, 0x52, 0xfa, 0x19, 0x24, 0x68, 0x06, 0xda, + 0x03, 0x85, 0x92, 0xd9, 0x2d, 0x96, 0xdb, 0x2f, + 0x03, 0x85, 0x90, 0x09, 0x28, 0x96, 0xd1, 0x2f, + 0x5b, 0x20, 0x6c, 0x00, 0x06, 0xc3, 0xfd, 0xbf, + 0x39, 0x20, 0x6c, 0x00, 0x06, 0xc0, 0x0d, 0x80, + 0x89, 0x42, 0x46, 0x00, 0xa5, 0x82, 0x51, 0x34, + 0x47, 0x42, 0x10, 0xaa, 0x08, 0xd4, 0x8b, 0xa1, + 0xc1, 0x36, 0x60, 0x00, 0xc0, 0x16, 0xdb, 0x6d, + 0x15, 0x22, 0x9f, 0xff, 0x3f, 0xe9, 0x24, 0x92, + 0xe4, 0x11, 0x6c, 0x01, 0xb6, 0xb6, 0x4f, 0xfd, + 0x07, 0x1a, 0x49, 0x24, 0x00, 0xb4, 0x0f, 0xfd, + 0xee, 0x2d, 0x48, 0x92, 0x04, 0x92, 0xdb, 0xb6, + 0x33, 0xb2, 0x00, 0x09, 0x24, 0xb6, 0xdd, 0xb6, + 0x75, 0x31, 0x9b, 0x64, 0x84, 0x2d, 0x96, 0xc9, + 0x58, 0x72, 0xbb, 0x60, 0x25, 0x04, 0x82, 0x40, + 0x4b, 0x3a, 0x02, 0xd4, 0xad, 0x0b, 0xf1, 0x6f, + 0x1b, 0x45, 0xb7, 0xf9, 0x3f, 0xb0, 0x0b, 0xf8, + 0x46, 0x8f, 0x9b, 0x6b, 0xf6, 0x9f, 0xfd, 0xbf, + 0x1f, 0x32, 0x9f, 0xf6, 0x7f, 0x84, 0x9f, 0xc9, + 0x85, 0x47, 0x93, 0xc5, 0x3e, 0x82, 0xe1, 0x34, + 0x2e, 0x4a, 0xda, 0x21, 0xa0, 0xd4, 0x8b, 0x82, + 0xa5, 0x20, 0x00, 0x60, 0x07, 0x1b, 0xfd, 0xb7, + 0x1a, 0x10, 0xff, 0xbf, 0xf8, 0xec, 0x06, 0xd8, + 0xdb, 0x24, 0x6c, 0x0c, 0x00, 0x96, 0xcd, 0x6c, + 0x02, 0xfd, 0x00, 0x0a, 0x00, 0x00, 0x08, 0x00, + 0xeb, 0x2d, 0x80, 0xab, 0x01, 0xb0, 0x1d, 0x60, + 0x09, 0x1a, 0x69, 0x22, 0x48, 0x92, 0x5d, 0xb6, + 0xed, 0x03, 0x6d, 0xb4, 0x92, 0xb6, 0xdf, 0xff, + 0x4d, 0x5c, 0x6d, 0xb0, 0x49, 0xb6, 0xdf, 0xff, + 0x9a, 0x33, 0x92, 0xd9, 0x40, 0x3b, 0x66, 0x49, + 0x65, 0x5f, 0xdb, 0xfd, 0xed, 0x12, 0x46, 0x00, + 0x94, 0x37, 0x66, 0x66, 0x66, 0x42, 0xf4, 0x2f, + 0x30, 0x29, 0xdb, 0xf9, 0x2d, 0x24, 0x06, 0xd2, + 0x94, 0x20, 0x5b, 0x61, 0xb7, 0x1f, 0xfd, 0xbf, + 0x00, 0x46, 0xdb, 0x6f, 0xb7, 0xff, 0xfd, 0xbf, + 0xc3, 0x27, 0x4e, 0xf6, 0x2e, 0x02, 0xf2, 0xb7, + 0x06, 0x2b, 0xb2, 0xf9, 0xee, 0xfe, 0xfd, 0x77, + 0xd3, 0x2b, 0x66, 0x62, 0x66, 0x93, 0xf9, 0x6f, + 0x0b, 0x10, 0x6a, 0x74, 0xa7, 0x6e, 0xd6, 0x4d, + 0xe1, 0x2d, 0x44, 0x82, 0x04, 0x12, 0x59, 0x6e, + 0x07, 0x19, 0x42, 0x64, 0x2e, 0x32, 0xf3, 0x2f, + 0xe6, 0x2d, 0x04, 0xa8, 0x01, 0xb2, 0x0d, 0x6c, + 0x11, 0x10, 0x6d, 0x14, 0x44, 0x12, 0xeb, 0xbf, + 0xed, 0x2d, 0x05, 0x28, 0x0a, 0xb0, 0x1d, 0x60, + 0x64, 0x51, 0x68, 0x92, 0x04, 0x92, 0xdb, 0xbf, + 0xdc, 0x37, 0x17, 0xf4, 0x2f, 0x66, 0x66, 0xce, + 0x87, 0x62, 0x97, 0x61, 0x2e, 0x44, 0x44, 0x8c, + 0xc7, 0x72, 0x92, 0xe9, 0x2e, 0x12, 0xe1, 0x2e, + 0x55, 0x47, 0x02, 0xf0, 0x2f, 0x42, 0xf4, 0x2f, + 0xd8, 0xdd, 0x12, 0xe1, 0x2e, 0x12, 0xe1, 0x2e, + 0x51, 0x4c, 0x62, 0xf6, 0x2f, 0x66, 0x76, 0x67, + 0xe5, 0x12, 0x68, 0x56, 0x66, 0x42, 0xf3, 0x37, + 0x03, 0xef, 0x97, 0x79, 0x77, 0x97, 0x79, 0x77, + 0xe5, 0x1f, 0x97, 0x79, 0x77, 0x97, 0x79, 0x77, + 0x4a, 0x47, 0x62, 0xf6, 0x67, 0x66, 0x76, 0x66, + 0xdf, 0x2f, 0x97, 0x79, 0x77, 0x97, 0x79, 0x77, + 0x02, 0xdf, 0x97, 0x79, 0x77, 0x97, 0x79, 0x77, + 0xe9, 0x1b, 0x64, 0x46, 0x45, 0x46, 0x54, 0x26, + 0x4d, 0x41, 0x66, 0x54, 0x26, 0x42, 0xf3, 0x2f, + 0xea, 0x2d, 0x46, 0x54, 0x26, 0x22, 0xe3, 0x2e, + 0x8c, 0x40, 0x68, 0x84, 0x44, 0x12, 0xe9, 0x77, + ]), + decompressed: new Uint8Array([ + 0xab, 0xb9, 0x00, 0xff, 0xab, 0xb9, 0x00, 0xff, + 0x93, 0xa4, 0x00, 0xff, 0x7b, 0x8f, 0x00, 0xff, + 0x7e, 0x8e, 0x00, 0xff, 0x6c, 0x7c, 0x00, 0xff, + 0x7e, 0x8e, 0x00, 0xff, 0x7e, 0x8e, 0x00, 0xff, + 0x7b, 0x8c, 0x00, 0xff, 0x7b, 0x8c, 0x00, 0xff, + 0x87, 0x98, 0x00, 0xff, 0x67, 0x78, 0x00, 0xff, + 0x6f, 0x81, 0x00, 0xff, 0x81, 0x93, 0x00, 0xff, + 0x81, 0x93, 0x00, 0xff, 0x6f, 0x81, 0x00, 0xff, + 0x7e, 0x8e, 0x00, 0xff, 0x6c, 0x7c, 0x00, 0xff, + 0x6c, 0x7c, 0x00, 0xff, 0x6c, 0x7c, 0x00, 0xff, + 0x74, 0x74, 0x00, 0xff, 0x74, 0x74, 0x00, 0xff, + 0x74, 0x74, 0x00, 0xff, 0x89, 0x89, 0x00, 0xff, + 0x87, 0x8a, 0x00, 0xff, 0x87, 0x8a, 0x00, 0xff, + 0x87, 0x8a, 0x00, 0xff, 0x87, 0x8a, 0x00, 0xff, + 0x7f, 0x79, 0x00, 0xff, 0x8b, 0x8b, 0x00, 0xff, + 0xa3, 0x9d, 0x00, 0xff, 0xaf, 0xa9, 0x00, 0xff, + 0xab, 0xb9, 0x00, 0xff, 0x93, 0xa4, 0x00, 0xff, + 0x93, 0xa4, 0x00, 0xff, 0x7b, 0x8f, 0x00, 0xff, + 0x5a, 0x6a, 0x00, 0xff, 0x5a, 0x6a, 0x00, 0xff, + 0x5a, 0x6a, 0x00, 0xff, 0x5a, 0x6a, 0x00, 0xff, + 0x67, 0x78, 0x00, 0xff, 0x6f, 0x80, 0x00, 0xff, + 0x67, 0x78, 0x00, 0xff, 0x67, 0x78, 0x00, 0xff, + 0x4b, 0x57, 0x00, 0xff, 0x4b, 0x57, 0x00, 0xff, + 0x5d, 0x75, 0x00, 0xff, 0x5d, 0x75, 0x00, 0xff, + 0x5a, 0x6a, 0x00, 0xff, 0x6c, 0x7c, 0x00, 0xff, + 0x6c, 0x7c, 0x00, 0xff, 0x42, 0x52, 0x00, 0xff, + 0x66, 0x66, 0x00, 0xff, 0x66, 0x66, 0x00, 0xff, + 0x66, 0x66, 0x00, 0xff, 0x66, 0x66, 0x00, 0xff, + 0x71, 0x72, 0x00, 0xff, 0x71, 0x72, 0x00, 0xff, + 0x71, 0x72, 0x00, 0xff, 0x66, 0x66, 0x00, 0xff, + 0x7f, 0x67, 0x00, 0xff, 0x97, 0x79, 0x00, 0xff, + 0xa3, 0x8b, 0x00, 0xff, 0xbb, 0x9d, 0x00, 0xff, + 0xab, 0xb9, 0x00, 0xff, 0x93, 0xa4, 0x00, 0xff, + 0x6b, 0x7a, 0x00, 0xff, 0x6b, 0x7a, 0x00, 0xff, + 0x63, 0x73, 0x00, 0xff, 0x4b, 0x5b, 0x00, 0xff, + 0x39, 0x49, 0x00, 0xff, 0x4b, 0x5b, 0x00, 0xff, + 0x3f, 0x50, 0x00, 0xff, 0x53, 0x64, 0x00, 0xff, + 0x53, 0x64, 0x00, 0xff, 0x33, 0x44, 0x00, 0xff, + 0x4b, 0x4b, 0x00, 0xff, 0x39, 0x39, 0x00, 0xff, + 0x39, 0x39, 0x00, 0xff, 0x4b, 0x4b, 0x00, 0xff, + 0x4b, 0x5b, 0x00, 0xff, 0x4b, 0x5b, 0x00, 0xff, + 0x63, 0x73, 0x00, 0xff, 0x4b, 0x5b, 0x00, 0xff, + 0x3c, 0x3c, 0x00, 0xff, 0x3c, 0x3c, 0x00, 0xff, + 0x51, 0x51, 0x00, 0xff, 0x3c, 0x3c, 0x00, 0xff, + 0x50, 0x3e, 0x00, 0xff, 0x50, 0x3e, 0x00, 0xff, + 0x5b, 0x46, 0x00, 0xff, 0x66, 0x52, 0x00, 0xff, + 0x8b, 0x5b, 0x00, 0xff, 0x97, 0x67, 0x00, 0xff, + 0xaf, 0x79, 0x00, 0xff, 0xbb, 0x8b, 0x00, 0xff, + 0x93, 0xa4, 0x00, 0xff, 0x6b, 0x7a, 0x00, 0xff, + 0x7b, 0x8f, 0x00, 0xff, 0x53, 0x65, 0x00, 0xff, + 0x4b, 0x5b, 0x00, 0xff, 0x39, 0x49, 0x00, 0xff, + 0x39, 0x49, 0x00, 0xff, 0x27, 0x37, 0x00, 0xff, + 0x4b, 0x5c, 0x00, 0xff, 0x3f, 0x50, 0x00, 0xff, + 0x33, 0x44, 0x00, 0xff, 0x33, 0x44, 0x00, 0xff, + 0x27, 0x27, 0x00, 0xff, 0x27, 0x27, 0x00, 0xff, + 0x27, 0x27, 0x00, 0xff, 0x27, 0x27, 0x00, 0xff, + 0x39, 0x49, 0x00, 0xff, 0x27, 0x37, 0x00, 0xff, + 0x39, 0x49, 0x00, 0xff, 0x27, 0x37, 0x00, 0xff, + 0x51, 0x51, 0x00, 0xff, 0x27, 0x27, 0x00, 0xff, + 0x19, 0x19, 0x00, 0xff, 0x27, 0x27, 0x00, 0xff, + 0x50, 0x3e, 0x00, 0xff, 0x5b, 0x46, 0x00, 0xff, + 0x50, 0x3e, 0x00, 0xff, 0x50, 0x3e, 0x00, 0xff, + 0x8b, 0x49, 0x00, 0xff, 0xa3, 0x5b, 0x00, 0xff, + 0xaf, 0x67, 0x00, 0xff, 0xc3, 0x79, 0x00, 0xff, + 0x81, 0x81, 0x00, 0xff, 0x6f, 0x6f, 0x00, 0xff, + 0x4b, 0x4b, 0x00, 0xff, 0x5d, 0x5d, 0x00, 0xff, + 0x40, 0x4f, 0x00, 0xff, 0x40, 0x4f, 0x00, 0xff, + 0x1f, 0x27, 0x00, 0xff, 0x1f, 0x27, 0x00, 0xff, + 0x19, 0x28, 0x00, 0xff, 0x2f, 0x40, 0x00, 0xff, + 0x1f, 0x28, 0x00, 0xff, 0x13, 0x1e, 0x00, 0xff, + 0x10, 0x10, 0x00, 0xff, 0x16, 0x16, 0x00, 0xff, + 0x10, 0x10, 0x00, 0xff, 0x19, 0x1c, 0x00, 0xff, + 0x11, 0x11, 0x00, 0xff, 0x21, 0x32, 0x00, 0xff, + 0x11, 0x11, 0x00, 0xff, 0x31, 0x44, 0x00, 0xff, + 0x48, 0x50, 0x00, 0xff, 0x50, 0x56, 0x00, 0xff, + 0x30, 0x38, 0x00, 0xff, 0x30, 0x38, 0x00, 0xff, + 0x3a, 0x27, 0x00, 0xff, 0x5e, 0x4f, 0x00, 0xff, + 0x72, 0x61, 0x00, 0xff, 0x5e, 0x4f, 0x00, 0xff, + 0x8c, 0x38, 0x00, 0xff, 0x98, 0x44, 0x00, 0xff, + 0xb8, 0x58, 0x00, 0xff, 0xd8, 0x74, 0x00, 0xff, + 0x93, 0x93, 0x00, 0xff, 0x5d, 0x5d, 0x00, 0xff, + 0x4b, 0x4b, 0x00, 0xff, 0x39, 0x39, 0x00, 0xff, + 0x40, 0x4f, 0x00, 0xff, 0x16, 0x27, 0x00, 0xff, + 0x40, 0x4f, 0x00, 0xff, 0x1f, 0x27, 0x00, 0xff, + 0x07, 0x18, 0x00, 0xff, 0x07, 0x18, 0x00, 0xff, + 0x1f, 0x28, 0x00, 0xff, 0x13, 0x1e, 0x00, 0xff, + 0x19, 0x1c, 0x00, 0xff, 0x10, 0x10, 0x00, 0xff, + 0x16, 0x16, 0x00, 0xff, 0x10, 0x10, 0x00, 0xff, + 0x21, 0x32, 0x00, 0xff, 0x11, 0x11, 0x00, 0xff, + 0x21, 0x32, 0x00, 0xff, 0x11, 0x23, 0x00, 0xff, + 0x3c, 0x47, 0x00, 0xff, 0x30, 0x38, 0x00, 0xff, + 0x48, 0x50, 0x00, 0xff, 0x3c, 0x47, 0x00, 0xff, + 0x4a, 0x39, 0x00, 0xff, 0x4a, 0x39, 0x00, 0xff, + 0x5e, 0x4f, 0x00, 0xff, 0x72, 0x61, 0x00, 0xff, + 0xa0, 0x50, 0x00, 0xff, 0x98, 0x44, 0x00, 0xff, + 0xb8, 0x58, 0x00, 0xff, 0xd8, 0x74, 0x00, 0xff, + 0x93, 0x93, 0x00, 0xff, 0x5d, 0x5d, 0x00, 0xff, + 0x39, 0x39, 0x00, 0xff, 0x2d, 0x2d, 0x00, 0xff, + 0x28, 0x3b, 0x00, 0xff, 0x04, 0x13, 0x00, 0xff, + 0x0d, 0x13, 0x00, 0xff, 0x31, 0x3b, 0x00, 0xff, + 0x19, 0x28, 0x00, 0xff, 0x07, 0x18, 0x00, 0xff, + 0x00, 0x06, 0x00, 0xff, 0x13, 0x1e, 0x00, 0xff, + 0x0d, 0x1c, 0x00, 0xff, 0x0d, 0x1c, 0x00, 0xff, + 0x0d, 0x1c, 0x00, 0xff, 0x00, 0x06, 0x00, 0xff, + 0x11, 0x23, 0x00, 0xff, 0x11, 0x23, 0x00, 0xff, + 0x11, 0x23, 0x00, 0xff, 0x21, 0x32, 0x00, 0xff, + 0x3c, 0x1d, 0x00, 0xff, 0x50, 0x2f, 0x00, 0xff, + 0x50, 0x2f, 0x00, 0xff, 0x78, 0x56, 0x00, 0xff, + 0x7e, 0x49, 0x00, 0xff, 0x7e, 0x49, 0x00, 0xff, + 0x72, 0x3f, 0x00, 0xff, 0x72, 0x3f, 0x00, 0xff, + 0xac, 0x58, 0x00, 0xff, 0xac, 0x58, 0x00, 0xff, + 0xb8, 0x58, 0x00, 0xff, 0xd8, 0x74, 0x00, 0xff, + 0x81, 0x81, 0x00, 0xff, 0x5d, 0x5d, 0x00, 0xff, + 0x39, 0x39, 0x00, 0xff, 0x39, 0x39, 0x00, 0xff, + 0x04, 0x13, 0x00, 0xff, 0x16, 0x27, 0x00, 0xff, + 0x0d, 0x13, 0x00, 0xff, 0x0d, 0x13, 0x00, 0xff, + 0x19, 0x28, 0x00, 0xff, 0x07, 0x18, 0x00, 0xff, + 0x0d, 0x12, 0x00, 0xff, 0x00, 0x06, 0x00, 0xff, + 0x19, 0x28, 0x00, 0xff, 0x19, 0x28, 0x00, 0xff, + 0x00, 0x06, 0x00, 0xff, 0x19, 0x28, 0x00, 0xff, + 0x11, 0x11, 0x00, 0xff, 0x11, 0x23, 0x00, 0xff, + 0x11, 0x11, 0x00, 0xff, 0x11, 0x11, 0x00, 0xff, + 0x50, 0x2f, 0x00, 0xff, 0x3c, 0x1d, 0x00, 0xff, + 0x3c, 0x1d, 0x00, 0xff, 0x50, 0x2f, 0x00, 0xff, + 0x72, 0x3f, 0x00, 0xff, 0x7e, 0x49, 0x00, 0xff, + 0x86, 0x55, 0x00, 0xff, 0x86, 0x55, 0x00, 0xff, + 0xa0, 0x50, 0x00, 0xff, 0xac, 0x58, 0x00, 0xff, + 0xb8, 0x58, 0x00, 0xff, 0xd8, 0x74, 0x00, 0xff, + 0x75, 0x85, 0x00, 0xff, 0x51, 0x61, 0x00, 0xff, + 0x3f, 0x4f, 0x00, 0xff, 0x2d, 0x3d, 0x00, 0xff, + 0x29, 0x32, 0x00, 0xff, 0x07, 0x10, 0x00, 0xff, + 0x13, 0x1c, 0x00, 0xff, 0x1d, 0x26, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x05, 0x0d, 0x00, 0xff, + 0x05, 0x0d, 0x00, 0xff, 0x11, 0x16, 0x00, 0xff, + 0x11, 0x21, 0x00, 0xff, 0x11, 0x21, 0x00, 0xff, + 0x29, 0x21, 0x00, 0xff, 0x11, 0x0b, 0x00, 0xff, + 0x37, 0x1d, 0x00, 0xff, 0x1f, 0x07, 0x00, 0xff, + 0x4f, 0x1d, 0x00, 0xff, 0x4f, 0x1d, 0x00, 0xff, + 0x55, 0x32, 0x00, 0xff, 0x75, 0x53, 0x00, 0xff, + 0x87, 0x32, 0x00, 0xff, 0x67, 0x11, 0x00, 0xff, + 0x94, 0x00, 0x00, 0xff, 0x82, 0x1c, 0x00, 0xff, + 0xaf, 0x49, 0x00, 0xff, 0xaf, 0x49, 0x00, 0xff, + 0xd2, 0x5a, 0x00, 0xff, 0xd2, 0x39, 0x00, 0xff, + 0xd2, 0x5a, 0x00, 0xff, 0xe8, 0x70, 0x00, 0xff, + 0x63, 0x73, 0x00, 0xff, 0x63, 0x73, 0x00, 0xff, + 0x3f, 0x4f, 0x00, 0xff, 0x3f, 0x4f, 0x00, 0xff, + 0x1d, 0x26, 0x00, 0xff, 0x29, 0x32, 0x00, 0xff, + 0x07, 0x10, 0x00, 0xff, 0x13, 0x1c, 0x00, 0xff, + 0x11, 0x16, 0x00, 0xff, 0x00, 0x04, 0x00, 0xff, + 0x05, 0x0d, 0x00, 0xff, 0x11, 0x16, 0x00, 0xff, + 0x05, 0x15, 0x00, 0xff, 0x05, 0x15, 0x00, 0xff, + 0x11, 0x0b, 0x00, 0xff, 0x05, 0x00, 0x00, 0xff, + 0x1f, 0x07, 0x00, 0xff, 0x1f, 0x07, 0x00, 0xff, + 0x37, 0x07, 0x00, 0xff, 0x5b, 0x29, 0x00, 0xff, + 0x55, 0x32, 0x00, 0xff, 0x87, 0x32, 0x00, 0xff, + 0x75, 0x53, 0x00, 0xff, 0x87, 0x32, 0x00, 0xff, + 0x82, 0x1c, 0x00, 0xff, 0x94, 0x00, 0x00, 0xff, + 0x82, 0x1c, 0x00, 0xff, 0xaf, 0x49, 0x00, 0xff, + 0xd2, 0x39, 0x00, 0xff, 0xd2, 0x39, 0x00, 0xff, + 0xe8, 0x4f, 0x00, 0xff, 0xe8, 0x70, 0x00, 0xff, + 0x75, 0x85, 0x00, 0xff, 0x51, 0x61, 0x00, 0xff, + 0x51, 0x61, 0x00, 0xff, 0x2d, 0x3d, 0x00, 0xff, + 0x29, 0x32, 0x00, 0xff, 0x1d, 0x26, 0x00, 0xff, + 0x29, 0x32, 0x00, 0xff, 0x13, 0x1c, 0x00, 0xff, + 0x29, 0x49, 0x00, 0xff, 0x0e, 0x2e, 0x00, 0xff, + 0x00, 0x16, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x05, 0x15, 0x00, 0xff, 0x00, 0x0b, 0x00, 0xff, + 0x11, 0x0b, 0x00, 0xff, 0x11, 0x0b, 0x00, 0xff, + 0x1f, 0x07, 0x00, 0xff, 0x2b, 0x13, 0x00, 0xff, + 0x37, 0x07, 0x00, 0xff, 0x4f, 0x1d, 0x00, 0xff, + 0x87, 0x32, 0x00, 0xff, 0x87, 0x32, 0x00, 0xff, + 0x87, 0x32, 0x00, 0xff, 0x87, 0x32, 0x00, 0xff, + 0xaf, 0x49, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xc1, 0x17, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xd2, 0x5a, 0x00, 0xff, 0xd2, 0x39, 0x00, 0xff, + 0xe8, 0x4f, 0x00, 0xff, 0xe8, 0x70, 0x00, 0xff, + 0x87, 0x97, 0x00, 0xff, 0x63, 0x73, 0x00, 0xff, + 0x2d, 0x3d, 0x00, 0xff, 0x2d, 0x3d, 0x00, 0xff, + 0x1d, 0x26, 0x00, 0xff, 0x13, 0x1c, 0x00, 0xff, + 0x07, 0x10, 0x00, 0xff, 0x1d, 0x26, 0x00, 0xff, + 0x00, 0x16, 0x00, 0xff, 0x29, 0x49, 0x00, 0xff, + 0x00, 0x16, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x05, 0x15, 0x00, 0xff, + 0x29, 0x21, 0x00, 0xff, 0x1d, 0x15, 0x00, 0xff, + 0x43, 0x29, 0x00, 0xff, 0x37, 0x1d, 0x00, 0xff, + 0x5b, 0x29, 0x00, 0xff, 0x4f, 0x1d, 0x00, 0xff, + 0x87, 0x32, 0x00, 0xff, 0x87, 0x32, 0x00, 0xff, + 0x87, 0x32, 0x00, 0xff, 0x87, 0x32, 0x00, 0xff, + 0xc1, 0x17, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xc1, 0x17, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xd2, 0x39, 0x00, 0xff, 0xd2, 0x39, 0x00, 0xff, + 0xe8, 0x4f, 0x00, 0xff, 0xe8, 0x70, 0x00, 0xff, + 0x7c, 0x9b, 0x00, 0xff, 0x6d, 0x89, 0x00, 0xff, + 0x54, 0x5f, 0x00, 0xff, 0x18, 0x2f, 0x00, 0xff, + 0x20, 0x20, 0x00, 0xff, 0x0e, 0x0e, 0x00, 0xff, + 0x0e, 0x0e, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x05, 0x05, 0x00, 0xff, + 0x09, 0x11, 0x00, 0xff, 0x09, 0x11, 0x00, 0xff, + 0x0e, 0x18, 0x00, 0xff, 0x0e, 0x18, 0x00, 0xff, + 0x32, 0x24, 0x00, 0xff, 0x3e, 0x2e, 0x00, 0xff, + 0x44, 0x13, 0x00, 0xff, 0x6c, 0x3b, 0x00, 0xff, + 0x6c, 0x1f, 0x00, 0xff, 0x8c, 0x41, 0x00, 0xff, + 0x99, 0x32, 0x00, 0xff, 0x99, 0x32, 0x00, 0xff, + 0x99, 0x32, 0x00, 0xff, 0xbb, 0x10, 0x00, 0xff, + 0xc5, 0x05, 0x00, 0xff, 0xcf, 0x0b, 0x00, 0xff, + 0xd5, 0x0e, 0x00, 0xff, 0xe1, 0x13, 0x00, 0xff, + 0xe7, 0x24, 0x00, 0xff, 0xe7, 0x40, 0x00, 0xff, + 0xe7, 0x58, 0x00, 0xff, 0xe7, 0x70, 0x00, 0xff, + 0x7c, 0x9b, 0x00, 0xff, 0x6d, 0x9b, 0x00, 0xff, + 0x6d, 0x7d, 0x00, 0xff, 0x18, 0x2f, 0x00, 0xff, + 0x0e, 0x0e, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x09, 0x11, 0x00, 0xff, 0x09, 0x11, 0x00, 0xff, + 0x26, 0x2e, 0x00, 0xff, 0x26, 0x2e, 0x00, 0xff, + 0x26, 0x18, 0x00, 0xff, 0x4a, 0x3a, 0x00, 0xff, + 0x58, 0x25, 0x00, 0xff, 0x44, 0x13, 0x00, 0xff, + 0x8c, 0x41, 0x00, 0xff, 0x80, 0x35, 0x00, 0xff, + 0x99, 0x32, 0x00, 0xff, 0xa5, 0x3e, 0x00, 0xff, + 0x8d, 0x28, 0x00, 0xff, 0xbb, 0x10, 0x00, 0xff, + 0xc5, 0x05, 0x00, 0xff, 0xcf, 0x08, 0x00, 0xff, + 0xdb, 0x0e, 0x00, 0xff, 0xe5, 0x11, 0x00, 0xff, + 0xe9, 0x24, 0x00, 0xff, 0xe9, 0x3c, 0x00, 0xff, + 0xe9, 0x58, 0x00, 0xff, 0xe9, 0x70, 0x00, 0xff, + 0x8b, 0xad, 0x00, 0xff, 0x6d, 0x89, 0x00, 0xff, + 0x6d, 0x7d, 0x00, 0xff, 0x36, 0x41, 0x00, 0xff, + 0x0e, 0x0e, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x05, 0x05, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x09, 0x11, 0x00, 0xff, + 0x26, 0x2e, 0x00, 0xff, 0x32, 0x3a, 0x00, 0xff, + 0x3e, 0x2e, 0x00, 0xff, 0x4a, 0x3a, 0x00, 0xff, + 0x6c, 0x3b, 0x00, 0xff, 0x6c, 0x3b, 0x00, 0xff, + 0x74, 0x2b, 0x00, 0xff, 0x8c, 0x41, 0x00, 0xff, + 0x99, 0x32, 0x00, 0xff, 0x99, 0x32, 0x00, 0xff, + 0xa5, 0x3e, 0x00, 0xff, 0xbb, 0x10, 0x00, 0xff, + 0xcb, 0x02, 0x00, 0xff, 0xd5, 0x08, 0x00, 0xff, + 0xe1, 0x0b, 0x00, 0xff, 0xeb, 0x11, 0x00, 0xff, + 0xeb, 0x24, 0x00, 0xff, 0xeb, 0x3c, 0x00, 0xff, + 0xeb, 0x58, 0x00, 0xff, 0xeb, 0x70, 0x00, 0xff, + 0x8b, 0xad, 0x00, 0xff, 0x6d, 0x9b, 0x00, 0xff, + 0x6d, 0x7d, 0x00, 0xff, 0x6d, 0x7d, 0x00, 0xff, + 0x35, 0x35, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x11, 0x11, 0x00, 0xff, 0x05, 0x05, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x09, 0x11, 0x00, 0xff, + 0x26, 0x2e, 0x00, 0xff, 0x32, 0x3a, 0x00, 0xff, + 0x4a, 0x3a, 0x00, 0xff, 0x4a, 0x3a, 0x00, 0xff, + 0x6c, 0x3b, 0x00, 0xff, 0x80, 0x4d, 0x00, 0xff, + 0x8c, 0x41, 0x00, 0xff, 0x80, 0x35, 0x00, 0xff, + 0xa5, 0x3e, 0x00, 0xff, 0xa5, 0x3e, 0x00, 0xff, + 0x99, 0x32, 0x00, 0xff, 0xbb, 0x10, 0x00, 0xff, + 0xcf, 0x02, 0x00, 0xff, 0xdb, 0x05, 0x00, 0xff, + 0xe5, 0x0b, 0x00, 0xff, 0xeb, 0x0e, 0x00, 0xff, + 0xed, 0x24, 0x00, 0xff, 0xed, 0x3c, 0x00, 0xff, + 0xed, 0x54, 0x00, 0xff, 0xed, 0x70, 0x00, 0xff, + 0x7d, 0x95, 0x00, 0xff, 0x7d, 0x95, 0x00, 0xff, + 0x5d, 0x77, 0x00, 0xff, 0x5d, 0x77, 0x00, 0xff, + 0x5c, 0x6e, 0x00, 0xff, 0x25, 0x37, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x13, 0x13, 0x00, 0xff, 0x13, 0x13, 0x00, 0xff, + 0x13, 0x13, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x3d, 0x1b, 0x00, 0xff, 0x55, 0x33, 0x00, 0xff, + 0x6b, 0x49, 0x00, 0xff, 0x6b, 0x49, 0x00, 0xff, + 0x69, 0x3f, 0x00, 0xff, 0x81, 0x57, 0x00, 0xff, + 0x8d, 0x63, 0x00, 0xff, 0x81, 0x57, 0x00, 0xff, + 0xa0, 0x17, 0x00, 0xff, 0xb5, 0x2d, 0x00, 0xff, + 0xb5, 0x2d, 0x00, 0xff, 0xd3, 0x05, 0x00, 0xff, + 0xd7, 0x00, 0x00, 0xff, 0xe1, 0x00, 0x00, 0xff, + 0xea, 0x0a, 0x00, 0xff, 0xf0, 0x10, 0x00, 0xff, + 0xe8, 0x1d, 0x00, 0xff, 0xea, 0x3e, 0x00, 0xff, + 0xee, 0x5f, 0x00, 0xff, 0xf0, 0x80, 0x00, 0xff, + 0x7d, 0x95, 0x00, 0xff, 0x5d, 0x77, 0x00, 0xff, + 0x5d, 0x77, 0x00, 0xff, 0x41, 0x65, 0x00, 0xff, + 0x3e, 0x55, 0x00, 0xff, 0x25, 0x37, 0x00, 0xff, + 0x1b, 0x0a, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x13, 0x13, 0x00, 0xff, 0x13, 0x13, 0x00, 0xff, + 0x33, 0x33, 0x00, 0xff, 0x13, 0x13, 0x00, 0xff, + 0x3d, 0x1b, 0x00, 0xff, 0x55, 0x33, 0x00, 0xff, + 0x55, 0x33, 0x00, 0xff, 0x6b, 0x49, 0x00, 0xff, + 0x75, 0x4b, 0x00, 0xff, 0x69, 0x3f, 0x00, 0xff, + 0x81, 0x57, 0x00, 0xff, 0x8d, 0x63, 0x00, 0xff, + 0xb5, 0x2d, 0x00, 0xff, 0xa0, 0x17, 0x00, 0xff, + 0xd3, 0x05, 0x00, 0xff, 0xd3, 0x05, 0x00, 0xff, + 0xd7, 0x00, 0x00, 0xff, 0xed, 0x05, 0x00, 0xff, + 0xea, 0x0a, 0x00, 0xff, 0xf0, 0x10, 0x00, 0xff, + 0xe8, 0x1d, 0x00, 0xff, 0xec, 0x3e, 0x00, 0xff, + 0xee, 0x5f, 0x00, 0xff, 0xf2, 0x80, 0x00, 0xff, + 0x71, 0x65, 0x00, 0xff, 0x5d, 0x53, 0x00, 0xff, + 0x49, 0x41, 0x00, 0xff, 0x35, 0x2f, 0x00, 0xff, + 0x25, 0x37, 0x00, 0xff, 0x25, 0x37, 0x00, 0xff, + 0x3e, 0x28, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x33, 0x00, 0xff, + 0x33, 0x33, 0x00, 0xff, 0x33, 0x33, 0x00, 0xff, + 0x55, 0x33, 0x00, 0xff, 0x55, 0x33, 0x00, 0xff, + 0x77, 0x33, 0x00, 0xff, 0x77, 0x33, 0x00, 0xff, + 0x8d, 0x33, 0x00, 0xff, 0x8d, 0x33, 0x00, 0xff, + 0x8d, 0x33, 0x00, 0xff, 0xa5, 0x4b, 0x00, 0xff, + 0xb5, 0x2d, 0x00, 0xff, 0xb5, 0x2d, 0x00, 0xff, + 0xd3, 0x05, 0x00, 0xff, 0xd3, 0x05, 0x00, 0xff, + 0xe1, 0x00, 0x00, 0xff, 0xed, 0x05, 0x00, 0xff, + 0xe6, 0x05, 0x00, 0xff, 0xf0, 0x10, 0x00, 0xff, + 0xea, 0x1d, 0x00, 0xff, 0xec, 0x3e, 0x00, 0xff, + 0xf0, 0x5f, 0x00, 0xff, 0xf2, 0x80, 0x00, 0xff, + 0x71, 0x65, 0x00, 0xff, 0x5d, 0x53, 0x00, 0xff, + 0x49, 0x41, 0x00, 0xff, 0x35, 0x2f, 0x00, 0xff, + 0x07, 0x19, 0x00, 0xff, 0x25, 0x37, 0x00, 0xff, + 0x3e, 0x28, 0x00, 0xff, 0x1b, 0x0a, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x33, 0x33, 0x00, 0xff, 0x53, 0x53, 0x00, 0xff, + 0x55, 0x33, 0x00, 0xff, 0x6b, 0x49, 0x00, 0xff, + 0x77, 0x33, 0x00, 0xff, 0x77, 0x33, 0x00, 0xff, + 0x81, 0x27, 0x00, 0xff, 0x99, 0x3f, 0x00, 0xff, + 0x99, 0x3f, 0x00, 0xff, 0x8d, 0x33, 0x00, 0xff, + 0xb5, 0x2d, 0x00, 0xff, 0xb5, 0x2d, 0x00, 0xff, + 0xd3, 0x05, 0x00, 0xff, 0xd3, 0x05, 0x00, 0xff, + 0xe1, 0x00, 0x00, 0xff, 0xed, 0x05, 0x00, 0xff, + 0xe6, 0x05, 0x00, 0xff, 0xea, 0x0a, 0x00, 0xff, + 0xea, 0x1d, 0x00, 0xff, 0xee, 0x3e, 0x00, 0xff, + 0xf0, 0x5f, 0x00, 0xff, 0xf2, 0x80, 0x00, 0xff, + 0x7b, 0x74, 0x00, 0xff, 0x57, 0x4a, 0x00, 0xff, + 0x60, 0x4a, 0x00, 0xff, 0x4e, 0x35, 0x00, 0xff, + 0x45, 0x33, 0x00, 0xff, 0x33, 0x23, 0x00, 0xff, + 0x45, 0x33, 0x00, 0xff, 0x45, 0x33, 0x00, 0xff, + 0x56, 0x22, 0x00, 0xff, 0x66, 0x00, 0x00, 0xff, + 0x56, 0x22, 0x00, 0xff, 0x76, 0x43, 0x00, 0xff, + 0x8d, 0x4a, 0x00, 0xff, 0x65, 0x26, 0x00, 0xff, + 0x8d, 0x4a, 0x00, 0xff, 0x79, 0x3a, 0x00, 0xff, + 0x9f, 0x28, 0x00, 0xff, 0x9f, 0x28, 0x00, 0xff, + 0x9f, 0x28, 0x00, 0xff, 0xb5, 0x0b, 0x00, 0xff, + 0xc3, 0x00, 0x00, 0xff, 0xe9, 0x11, 0x00, 0xff, + 0xdf, 0x00, 0x00, 0xff, 0xe9, 0x02, 0x00, 0xff, + 0xeb, 0x00, 0x00, 0xff, 0xed, 0x05, 0x00, 0xff, + 0xed, 0x0a, 0x00, 0xff, 0xef, 0x10, 0x00, 0xff, + 0xeb, 0x1b, 0x00, 0xff, 0xec, 0x3e, 0x00, 0xff, + 0xed, 0x5c, 0x00, 0xff, 0xef, 0x7a, 0x00, 0xff, + 0x90, 0x89, 0x00, 0xff, 0x57, 0x4a, 0x00, 0xff, + 0x4e, 0x35, 0x00, 0xff, 0x4e, 0x35, 0x00, 0xff, + 0x45, 0x33, 0x00, 0xff, 0x33, 0x23, 0x00, 0xff, + 0x33, 0x23, 0x00, 0xff, 0x54, 0x43, 0x00, 0xff, + 0x76, 0x43, 0x00, 0xff, 0x86, 0x10, 0x00, 0xff, + 0x86, 0x10, 0x00, 0xff, 0x76, 0x43, 0x00, 0xff, + 0x8d, 0x4a, 0x00, 0xff, 0x8d, 0x4a, 0x00, 0xff, + 0x79, 0x3a, 0x00, 0xff, 0x8d, 0x4a, 0x00, 0xff, + 0x9f, 0x28, 0x00, 0xff, 0x9f, 0x28, 0x00, 0xff, + 0xb5, 0x0b, 0x00, 0xff, 0xb5, 0x0b, 0x00, 0xff, + 0xc3, 0x00, 0x00, 0xff, 0xd5, 0x00, 0x00, 0xff, + 0xe5, 0x00, 0x00, 0xff, 0xe5, 0x00, 0x00, 0xff, + 0xe9, 0x01, 0x00, 0xff, 0xeb, 0x05, 0x00, 0xff, + 0xeb, 0x0a, 0x00, 0xff, 0xed, 0x10, 0x00, 0xff, + 0xeb, 0x1b, 0x00, 0xff, 0xec, 0x39, 0x00, 0xff, + 0xed, 0x5c, 0x00, 0xff, 0xef, 0x7a, 0x00, 0xff, + 0x90, 0x89, 0x00, 0xff, 0x6c, 0x5f, 0x00, 0xff, + 0x4e, 0x35, 0x00, 0xff, 0x60, 0x4a, 0x00, 0xff, + 0x54, 0x43, 0x00, 0xff, 0x54, 0x43, 0x00, 0xff, + 0x66, 0x0f, 0x00, 0xff, 0x54, 0x43, 0x00, 0xff, + 0x76, 0x43, 0x00, 0xff, 0x76, 0x43, 0x00, 0xff, + 0x86, 0x10, 0x00, 0xff, 0x86, 0x10, 0x00, 0xff, + 0xad, 0x32, 0x00, 0xff, 0xad, 0x32, 0x00, 0xff, + 0x95, 0x1e, 0x00, 0xff, 0xa1, 0x26, 0x00, 0xff, + 0x9f, 0x28, 0x00, 0xff, 0x9f, 0x28, 0x00, 0xff, + 0xc1, 0x17, 0x00, 0xff, 0xb5, 0x0b, 0x00, 0xff, + 0xd5, 0x00, 0x00, 0xff, 0xd5, 0x00, 0x00, 0xff, + 0xe5, 0x00, 0x00, 0xff, 0xe5, 0x00, 0x00, 0xff, + 0xe7, 0x01, 0x00, 0xff, 0xe9, 0x05, 0x00, 0xff, + 0xe9, 0x0a, 0x00, 0xff, 0xeb, 0x10, 0x00, 0xff, + 0xeb, 0x1b, 0x00, 0xff, 0xec, 0x39, 0x00, 0xff, + 0xed, 0x5c, 0x00, 0xff, 0xef, 0x7a, 0x00, 0xff, + 0x90, 0x89, 0x00, 0xff, 0x7b, 0x74, 0x00, 0xff, + 0x60, 0x4a, 0x00, 0xff, 0x60, 0x4a, 0x00, 0xff, + 0x54, 0x43, 0x00, 0xff, 0x54, 0x43, 0x00, 0xff, + 0x66, 0x0f, 0x00, 0xff, 0x66, 0x0f, 0x00, 0xff, + 0x76, 0x43, 0x00, 0xff, 0x76, 0x43, 0x00, 0xff, + 0x86, 0x10, 0x00, 0xff, 0x86, 0x10, 0x00, 0xff, + 0x8d, 0x0e, 0x00, 0xff, 0xa1, 0x26, 0x00, 0xff, + 0xa1, 0x26, 0x00, 0xff, 0x8d, 0x0e, 0x00, 0xff, + 0xb5, 0x0b, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xc1, 0x17, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xd5, 0x00, 0x00, 0xff, 0xd5, 0x00, 0x00, 0xff, + 0xdf, 0x00, 0x00, 0xff, 0xdf, 0x00, 0x00, 0xff, + 0xe5, 0x01, 0x00, 0xff, 0xe7, 0x07, 0x00, 0xff, + 0xe7, 0x0c, 0x00, 0xff, 0xe9, 0x10, 0x00, 0xff, + 0xeb, 0x1b, 0x00, 0xff, 0xec, 0x39, 0x00, 0xff, + 0xed, 0x5c, 0x00, 0xff, 0xef, 0x7a, 0x00, 0xff, + 0x9d, 0x83, 0x00, 0xff, 0x9d, 0x83, 0x00, 0xff, + 0x8e, 0x56, 0x00, 0xff, 0x73, 0x38, 0x00, 0xff, + 0x73, 0x3e, 0x00, 0xff, 0x73, 0x32, 0x00, 0xff, + 0x7c, 0x26, 0x00, 0xff, 0x7c, 0x1c, 0x00, 0xff, + 0x82, 0x1c, 0x00, 0xff, 0x8e, 0x28, 0x00, 0xff, + 0x8e, 0x28, 0x00, 0xff, 0xa4, 0x1c, 0x00, 0xff, + 0xb3, 0x0e, 0x00, 0xff, 0xad, 0x08, 0x00, 0xff, + 0xbd, 0x18, 0x00, 0xff, 0xb9, 0x12, 0x00, 0xff, + 0xbf, 0x00, 0x00, 0xff, 0xc9, 0x02, 0x00, 0xff, + 0xd5, 0x00, 0x00, 0xff, 0xd5, 0x00, 0x00, 0xff, + 0xdb, 0x00, 0x00, 0xff, 0xdd, 0x00, 0x00, 0xff, + 0xdf, 0x02, 0x00, 0xff, 0xe1, 0x02, 0x00, 0xff, + 0xe4, 0x02, 0x00, 0xff, 0xe6, 0x08, 0x00, 0xff, + 0xe8, 0x0e, 0x00, 0xff, 0xea, 0x16, 0x00, 0xff, + 0xeb, 0x23, 0x00, 0xff, 0xed, 0x41, 0x00, 0xff, + 0xef, 0x6e, 0x00, 0xff, 0xf1, 0x82, 0x00, 0xff, + 0x9d, 0x83, 0x00, 0xff, 0xa3, 0x8d, 0x00, 0xff, + 0xa9, 0x6f, 0x00, 0xff, 0x8e, 0x56, 0x00, 0xff, + 0x85, 0x3e, 0x00, 0xff, 0x85, 0x32, 0x00, 0xff, + 0x8b, 0x26, 0x00, 0xff, 0x8b, 0x1c, 0x00, 0xff, + 0xa4, 0x1c, 0x00, 0xff, 0xa4, 0x1c, 0x00, 0xff, + 0xb0, 0x28, 0x00, 0xff, 0xa4, 0x1c, 0x00, 0xff, + 0xad, 0x08, 0x00, 0xff, 0xbd, 0x18, 0x00, 0xff, + 0xbd, 0x18, 0x00, 0xff, 0xb3, 0x0e, 0x00, 0xff, + 0xc9, 0x02, 0x00, 0xff, 0xc9, 0x02, 0x00, 0xff, + 0xd5, 0x00, 0x00, 0xff, 0xdb, 0x05, 0x00, 0xff, + 0xdd, 0x05, 0x00, 0xff, 0xdf, 0x05, 0x00, 0xff, + 0xe1, 0x08, 0x00, 0xff, 0xe3, 0x08, 0x00, 0xff, + 0xe2, 0x02, 0x00, 0xff, 0xe4, 0x0b, 0x00, 0xff, + 0xe6, 0x13, 0x00, 0xff, 0xe8, 0x19, 0x00, 0xff, + 0xe9, 0x32, 0x00, 0xff, 0xeb, 0x55, 0x00, 0xff, + 0xed, 0x6e, 0x00, 0xff, 0xef, 0x91, 0x00, 0xff, + 0xa3, 0x8d, 0x00, 0xff, 0x94, 0x79, 0x00, 0xff, + 0xa9, 0x6f, 0x00, 0xff, 0x8e, 0x56, 0x00, 0xff, + 0x9a, 0x42, 0x00, 0xff, 0x9a, 0x38, 0x00, 0xff, + 0xa0, 0x2c, 0x00, 0xff, 0xa0, 0x20, 0x00, 0xff, + 0xa4, 0x1c, 0x00, 0xff, 0xa4, 0x1c, 0x00, 0xff, + 0xb0, 0x28, 0x00, 0xff, 0xb0, 0x28, 0x00, 0xff, + 0xcb, 0x0e, 0x00, 0xff, 0xcb, 0x0e, 0x00, 0xff, + 0xcb, 0x0e, 0x00, 0xff, 0xd1, 0x12, 0x00, 0xff, + 0xd5, 0x0d, 0x00, 0xff, 0xd5, 0x0d, 0x00, 0xff, + 0xe5, 0x10, 0x00, 0xff, 0xdb, 0x05, 0x00, 0xff, + 0xdd, 0x08, 0x00, 0xff, 0xdf, 0x0b, 0x00, 0xff, + 0xe1, 0x0b, 0x00, 0xff, 0xe3, 0x0b, 0x00, 0xff, + 0xe2, 0x08, 0x00, 0xff, 0xe4, 0x0e, 0x00, 0xff, + 0xe6, 0x16, 0x00, 0xff, 0xe8, 0x1f, 0x00, 0xff, + 0xe7, 0x41, 0x00, 0xff, 0xe9, 0x55, 0x00, 0xff, + 0xeb, 0x82, 0x00, 0xff, 0xed, 0xa0, 0x00, 0xff, + 0xa3, 0x8d, 0x00, 0xff, 0x94, 0x79, 0x00, 0xff, + 0xa9, 0x6f, 0x00, 0xff, 0x8e, 0x56, 0x00, 0xff, + 0xa9, 0x42, 0x00, 0xff, 0xa9, 0x38, 0x00, 0xff, + 0xb2, 0x2c, 0x00, 0xff, 0xb2, 0x20, 0x00, 0xff, + 0xa4, 0x1c, 0x00, 0xff, 0xb0, 0x28, 0x00, 0xff, + 0xb0, 0x28, 0x00, 0xff, 0xb0, 0x28, 0x00, 0xff, + 0xd7, 0x18, 0x00, 0xff, 0xd1, 0x12, 0x00, 0xff, + 0xd7, 0x18, 0x00, 0xff, 0xd7, 0x18, 0x00, 0xff, + 0xdf, 0x19, 0x00, 0xff, 0xdf, 0x19, 0x00, 0xff, + 0xe5, 0x10, 0x00, 0xff, 0xe5, 0x10, 0x00, 0xff, + 0xdf, 0x0e, 0x00, 0xff, 0xe1, 0x0e, 0x00, 0xff, + 0xe3, 0x10, 0x00, 0xff, 0xe5, 0x10, 0x00, 0xff, + 0xe0, 0x0b, 0x00, 0xff, 0xe2, 0x13, 0x00, 0xff, + 0xe4, 0x19, 0x00, 0xff, 0xe6, 0x1f, 0x00, 0xff, + 0xe7, 0x41, 0x00, 0xff, 0xe7, 0x6e, 0x00, 0xff, + 0xe9, 0x82, 0x00, 0xff, 0xeb, 0xa0, 0x00, 0xff, + 0xd3, 0x8d, 0x00, 0xff, 0xc4, 0x7b, 0x00, 0xff, + 0xbb, 0x57, 0x00, 0xff, 0xbb, 0x57, 0x00, 0xff, + 0xce, 0x49, 0x00, 0xff, 0xce, 0x49, 0x00, 0xff, + 0xb9, 0x35, 0x00, 0xff, 0xb9, 0x35, 0x00, 0xff, + 0xcb, 0x29, 0x00, 0xff, 0xcb, 0x29, 0x00, 0xff, + 0xcb, 0x29, 0x00, 0xff, 0xcb, 0x29, 0x00, 0xff, + 0xd8, 0x1f, 0x00, 0xff, 0xd8, 0x1f, 0x00, 0xff, + 0xdd, 0x1f, 0x00, 0xff, 0xe0, 0x1f, 0x00, 0xff, + 0xe7, 0x1e, 0x00, 0xff, 0xe7, 0x1e, 0x00, 0xff, + 0xe7, 0x1e, 0x00, 0xff, 0xe7, 0x1e, 0x00, 0xff, + 0xe3, 0x1c, 0x00, 0xff, 0xe3, 0x1c, 0x00, 0xff, + 0xe3, 0x1c, 0x00, 0xff, 0xe3, 0x1c, 0x00, 0xff, + 0xdf, 0x19, 0x00, 0xff, 0xdf, 0x25, 0x00, 0xff, + 0xe2, 0x25, 0x00, 0xff, 0xe2, 0x31, 0x00, 0xff, + 0xe4, 0x50, 0x00, 0xff, 0xe4, 0x68, 0x00, 0xff, + 0xe6, 0x80, 0x00, 0xff, 0xe6, 0x94, 0x00, 0xff, + 0xe8, 0x9f, 0x00, 0xff, 0xd3, 0x8d, 0x00, 0xff, + 0xcd, 0x69, 0x00, 0xff, 0xbb, 0x57, 0x00, 0xff, + 0xce, 0x49, 0x00, 0xff, 0xce, 0x49, 0x00, 0xff, + 0xce, 0x49, 0x00, 0xff, 0xce, 0x49, 0x00, 0xff, + 0xd8, 0x45, 0x00, 0xff, 0xd8, 0x45, 0x00, 0xff, + 0xd8, 0x41, 0x00, 0xff, 0xd8, 0x41, 0x00, 0xff, + 0xdd, 0x3b, 0x00, 0xff, 0xe0, 0x3b, 0x00, 0xff, + 0xe3, 0x3b, 0x00, 0xff, 0xe6, 0x3b, 0x00, 0xff, + 0xe9, 0x3e, 0x00, 0xff, 0xe9, 0x36, 0x00, 0xff, + 0xe9, 0x36, 0x00, 0xff, 0xe9, 0x36, 0x00, 0xff, + 0xe7, 0x36, 0x00, 0xff, 0xe7, 0x36, 0x00, 0xff, + 0xe7, 0x36, 0x00, 0xff, 0xe7, 0x36, 0x00, 0xff, + 0xe4, 0x31, 0x00, 0xff, 0xe4, 0x41, 0x00, 0xff, + 0xe4, 0x41, 0x00, 0xff, 0xe7, 0x55, 0x00, 0xff, + 0xe6, 0x68, 0x00, 0xff, 0xe8, 0x74, 0x00, 0xff, + 0xe8, 0x94, 0x00, 0xff, 0xea, 0xa0, 0x00, 0xff, + 0xfa, 0xb1, 0x00, 0xff, 0xe8, 0x9f, 0x00, 0xff, + 0xe2, 0x7b, 0x00, 0xff, 0xcd, 0x69, 0x00, 0xff, + 0xe3, 0x65, 0x00, 0xff, 0xe3, 0x65, 0x00, 0xff, + 0xe3, 0x65, 0x00, 0xff, 0xe3, 0x65, 0x00, 0xff, + 0xe5, 0x5d, 0x00, 0xff, 0xe5, 0x5d, 0x00, 0xff, + 0xe5, 0x59, 0x00, 0xff, 0xe5, 0x59, 0x00, 0xff, + 0xe3, 0x57, 0x00, 0xff, 0xe6, 0x57, 0x00, 0xff, + 0xe9, 0x57, 0x00, 0xff, 0xec, 0x57, 0x00, 0xff, + 0xeb, 0x5a, 0x00, 0xff, 0xeb, 0x52, 0x00, 0xff, + 0xeb, 0x52, 0x00, 0xff, 0xeb, 0x52, 0x00, 0xff, + 0xeb, 0x50, 0x00, 0xff, 0xeb, 0x50, 0x00, 0xff, + 0xeb, 0x50, 0x00, 0xff, 0xeb, 0x50, 0x00, 0xff, + 0xe7, 0x55, 0x00, 0xff, 0xe7, 0x55, 0x00, 0xff, + 0xea, 0x65, 0x00, 0xff, 0xea, 0x65, 0x00, 0xff, + 0xea, 0x74, 0x00, 0xff, 0xea, 0x80, 0x00, 0xff, + 0xec, 0xa0, 0x00, 0xff, 0xec, 0xac, 0x00, 0xff, + 0xfa, 0xb1, 0x00, 0xff, 0xfa, 0xb1, 0x00, 0xff, + 0xf1, 0x8d, 0x00, 0xff, 0xf1, 0x8d, 0x00, 0xff, + 0xf8, 0x7d, 0x00, 0xff, 0xf8, 0x7d, 0x00, 0xff, + 0xf8, 0x7d, 0x00, 0xff, 0xf8, 0x7d, 0x00, 0xff, + 0xf2, 0x75, 0x00, 0xff, 0xf2, 0x75, 0x00, 0xff, + 0xf2, 0x75, 0x00, 0xff, 0xf2, 0x75, 0x00, 0xff, + 0xe9, 0x73, 0x00, 0xff, 0xec, 0x73, 0x00, 0xff, + 0xf1, 0x73, 0x00, 0xff, 0xf1, 0x73, 0x00, 0xff, + 0xed, 0x72, 0x00, 0xff, 0xed, 0x72, 0x00, 0xff, + 0xed, 0x72, 0x00, 0xff, 0xed, 0x66, 0x00, 0xff, + 0xef, 0x6a, 0x00, 0xff, 0xef, 0x6a, 0x00, 0xff, + 0xef, 0x6a, 0x00, 0xff, 0xef, 0x6a, 0x00, 0xff, + 0xea, 0x65, 0x00, 0xff, 0xed, 0x71, 0x00, 0xff, + 0xed, 0x7d, 0x00, 0xff, 0xef, 0x7d, 0x00, 0xff, + 0xec, 0x80, 0x00, 0xff, 0xee, 0x94, 0x00, 0xff, + 0xee, 0xac, 0x00, 0xff, 0xee, 0xc4, 0x00, 0xff, + ]) +} + +var img_32x32_signed_rg11_eac = { + compressed: new Uint8Array([ + 0x24, 0x8b, 0x92, 0x08, 0x02, 0x01, 0x12, 0x53, + 0x09, 0x72, 0xdb, 0x5d, 0x68, 0xb4, 0x49, 0x01, + 0xd6, 0x62, 0xd2, 0x0b, 0x01, 0xd0, 0x9d, 0x02, + 0xe6, 0x62, 0xd2, 0x0b, 0x01, 0xd0, 0x9d, 0x02, + 0xe0, 0x47, 0xd1, 0x1d, 0x42, 0xf0, 0x39, 0x1b, + 0xf1, 0x47, 0xd1, 0x1d, 0x42, 0xf0, 0x39, 0x1b, + 0xd8, 0x62, 0xa0, 0x2c, 0x0a, 0xd0, 0xab, 0x02, + 0xd8, 0x69, 0xd0, 0x2f, 0x0a, 0xf4, 0xad, 0x42, + 0xd4, 0x30, 0xf0, 0x2d, 0x83, 0xda, 0xac, 0x43, + 0xe4, 0x30, 0xf0, 0x2d, 0x83, 0xda, 0xac, 0x43, + 0xcb, 0x7b, 0xd4, 0x4d, 0x41, 0xd6, 0x2f, 0x41, + 0xcb, 0x7b, 0xd4, 0x4d, 0x41, 0xd6, 0x2f, 0x41, + 0xf2, 0xbd, 0xd1, 0x2d, 0x11, 0xd0, 0xac, 0x02, + 0xe0, 0x47, 0xf5, 0x2f, 0x51, 0xf4, 0xaf, 0x02, + 0x1f, 0x49, 0x48, 0x92, 0x04, 0x92, 0xdb, 0xb7, + 0xf5, 0x6b, 0x80, 0xab, 0x01, 0xd6, 0x0f, 0xac, + 0xe9, 0x69, 0xbb, 0x58, 0x00, 0x25, 0x20, 0x9a, + 0xe9, 0x69, 0xbb, 0x58, 0x00, 0x25, 0x20, 0x9a, + 0x9d, 0x32, 0xfe, 0xae, 0x10, 0x9c, 0x99, 0x31, + 0xb2, 0x3c, 0xfe, 0xbe, 0x18, 0x1d, 0xb0, 0x2b, + 0x90, 0x3c, 0xa2, 0xde, 0x00, 0xd9, 0x09, 0x22, + 0xa5, 0x20, 0x86, 0x4e, 0x49, 0x91, 0xa0, 0x03, + 0x93, 0x3d, 0x18, 0xea, 0x0e, 0x14, 0xbc, 0x1e, + 0x98, 0x2a, 0x32, 0xf0, 0x6f, 0x22, 0xa8, 0x57, + 0x82, 0x8f, 0x96, 0x4b, 0x24, 0x96, 0x4d, 0x2c, + 0xa9, 0x3a, 0x54, 0x2a, 0x80, 0x54, 0x2e, 0x2a, + 0xdd, 0x47, 0x29, 0x00, 0xc2, 0x64, 0x26, 0xb0, + 0xb7, 0x4b, 0xd5, 0x0f, 0x02, 0x98, 0x29, 0x78, + 0xea, 0x44, 0x6a, 0xc0, 0xad, 0x82, 0x61, 0x26, + 0xc5, 0x20, 0x66, 0x0a, 0x64, 0xf4, 0x6b, 0xc6, + 0x35, 0x4b, 0x64, 0x14, 0x80, 0x92, 0x4f, 0xff, + 0xe5, 0x47, 0x64, 0x14, 0x80, 0x00, 0x0b, 0x6d, + 0xdd, 0x62, 0xb2, 0xe1, 0x04, 0x24, 0x24, 0x52, + 0xed, 0x62, 0xb2, 0xe1, 0x04, 0x24, 0x24, 0x52, + 0x97, 0x2a, 0xf7, 0xd5, 0xe8, 0x0b, 0xaa, 0x05, + 0xa0, 0x2a, 0xf7, 0xd5, 0xe8, 0x0b, 0xaa, 0x05, + 0x8e, 0x3d, 0x77, 0xb4, 0xe7, 0x49, 0xbb, 0x5b, + 0xa0, 0x30, 0x63, 0x82, 0xaf, 0x24, 0x00, 0x1b, + 0x8e, 0x42, 0x80, 0x18, 0x08, 0xd2, 0x68, 0x25, + 0x8f, 0x2a, 0xf6, 0xaf, 0x45, 0xe0, 0x70, 0x85, + 0xc0, 0x42, 0x09, 0x44, 0x88, 0xa0, 0x6b, 0xad, + 0x97, 0x2a, 0xa9, 0x74, 0x85, 0xa9, 0x7b, 0xed, + 0xf0, 0x23, 0x6f, 0xfb, 0xff, 0xf7, 0xf3, 0xff, + 0x87, 0xb2, 0xb6, 0xdd, 0x6d, 0xba, 0xd9, 0x6d, + 0x24, 0x37, 0x2e, 0xf6, 0x7f, 0xaf, 0xfb, 0x7f, + 0xa7, 0x4c, 0x63, 0x90, 0xc9, 0xe0, 0x9f, 0xc9, + 0xfb, 0xb5, 0xdb, 0x6d, 0xb6, 0xdf, 0xff, 0xff, + 0xdb, 0xbd, 0x8a, 0x24, 0x92, 0x80, 0x0d, 0xb6, + 0xe3, 0x50, 0xb7, 0x69, 0x24, 0x12, 0x46, 0xd4, + 0xf1, 0x67, 0xdb, 0xfb, 0xae, 0x12, 0x46, 0xd4, + 0x9b, 0x3c, 0x84, 0xf2, 0xdb, 0x2d, 0xb6, 0xdb, + 0x9b, 0x3c, 0x84, 0xf2, 0xdb, 0x2d, 0xb6, 0xdb, + 0x80, 0x2f, 0x02, 0x78, 0x04, 0xb4, 0x0b, 0x6d, + 0x80, 0x20, 0x02, 0x68, 0x04, 0xd8, 0x0d, 0xb6, + 0xaf, 0x42, 0x40, 0x04, 0x24, 0x82, 0xeb, 0xb6, + 0xa8, 0x2a, 0x56, 0xd5, 0x7f, 0x0a, 0xfb, 0xff, + 0xe5, 0x47, 0x42, 0x48, 0xa6, 0x9e, 0xff, 0xbe, + 0xb2, 0x20, 0x66, 0xda, 0xef, 0x58, 0x6d, 0x34, + 0x20, 0x20, 0x00, 0x41, 0x04, 0x0a, 0x0f, 0xff, + 0xaf, 0x20, 0x92, 0x69, 0xa6, 0x83, 0x46, 0xdb, + 0x5a, 0x2b, 0x6d, 0x14, 0x44, 0x12, 0xdb, 0xbf, + 0x8b, 0x19, 0x25, 0x28, 0x01, 0xb6, 0x4f, 0xb5, + 0x66, 0x1f, 0x97, 0x79, 0x77, 0x97, 0x79, 0x77, + 0xcd, 0x4c, 0x6d, 0xb0, 0x49, 0xb6, 0xcf, 0xff, + 0xd5, 0x47, 0xff, 0x6f, 0x24, 0x90, 0x08, 0x12, + 0xcd, 0x62, 0xfe, 0xdf, 0xa4, 0xd8, 0x0d, 0x49, + 0xb0, 0x5a, 0xf4, 0x20, 0x00, 0x66, 0xd4, 0xd1, + 0xb3, 0x52, 0xfa, 0x19, 0x24, 0x68, 0x06, 0xda, + 0x83, 0x85, 0x92, 0xd9, 0x2d, 0x96, 0xdb, 0x2f, + 0x83, 0x85, 0x90, 0x09, 0x28, 0x96, 0xd1, 0x2f, + 0xdc, 0x20, 0x6c, 0x00, 0x06, 0xc3, 0xfd, 0xbf, + 0xaf, 0x20, 0x4a, 0x49, 0x27, 0xf2, 0x4f, 0xe4, + 0x0a, 0x42, 0x46, 0x00, 0xa5, 0x82, 0x51, 0x34, + 0xc8, 0x42, 0x10, 0xaa, 0x08, 0xd4, 0x8b, 0xa1, + 0x41, 0x36, 0x60, 0x00, 0xc0, 0x16, 0xdb, 0x6d, + 0x92, 0x3c, 0x9f, 0xff, 0x3f, 0xe4, 0x92, 0x49, + 0x64, 0x11, 0x6c, 0x01, 0xb6, 0xb6, 0x4f, 0xfd, + 0x89, 0x1a, 0x6d, 0xb6, 0x49, 0x90, 0x0d, 0xb4, + 0x6f, 0x2d, 0x49, 0x12, 0x40, 0x12, 0x5b, 0x76, + 0xb3, 0xb2, 0x00, 0x09, 0x24, 0xb6, 0xdd, 0xb6, + 0xf6, 0x31, 0x9b, 0x64, 0x84, 0x2d, 0x96, 0xc9, + 0xd9, 0x72, 0xbb, 0x60, 0x25, 0x04, 0x82, 0x40, + 0xcb, 0x3a, 0x02, 0xd4, 0xad, 0x0b, 0xf1, 0x6f, + 0xa9, 0x3a, 0xb7, 0xf0, 0x3f, 0xa1, 0x2b, 0xfa, + 0xf0, 0x23, 0x76, 0xd3, 0xed, 0x7f, 0xfb, 0x7f, + 0x9f, 0x32, 0x9f, 0xf6, 0x7f, 0x84, 0x9f, 0xc9, + 0x06, 0x47, 0x93, 0xc5, 0x3e, 0x82, 0xe1, 0x34, + 0xb6, 0x32, 0xd8, 0x33, 0x81, 0xd1, 0x19, 0x8b, + 0x26, 0x20, 0x00, 0x60, 0x07, 0x1b, 0xfd, 0xb7, + 0x9a, 0x10, 0xff, 0xbf, 0xf8, 0xec, 0x06, 0xd8, + 0x5b, 0x24, 0x6c, 0x0c, 0x00, 0x96, 0xcd, 0x6c, + 0x82, 0xfd, 0x00, 0x0a, 0x00, 0x00, 0x08, 0x00, + 0x6b, 0x2d, 0x80, 0xab, 0x01, 0xb0, 0x1d, 0x60, + 0x89, 0x1a, 0x69, 0x22, 0x00, 0x96, 0xdd, 0xb7, + 0x6d, 0x00, 0x49, 0x20, 0x00, 0xdb, 0x6f, 0xff, + 0xce, 0x5c, 0x6d, 0xb2, 0x49, 0xb6, 0xcf, 0xff, + 0x1b, 0x33, 0x92, 0xd9, 0x40, 0x3b, 0x66, 0x49, + 0xe6, 0x5f, 0xdb, 0xfd, 0xed, 0x12, 0x46, 0x00, + 0x15, 0x37, 0x66, 0x66, 0x66, 0x42, 0xf4, 0x2f, + 0xb1, 0x29, 0xdb, 0xf9, 0x2d, 0x24, 0x06, 0xd2, + 0x15, 0x20, 0x5b, 0x61, 0xb7, 0x1f, 0xfd, 0xbf, + 0x84, 0x41, 0xb6, 0xdd, 0x6e, 0xdb, 0x6b, 0x76, + 0x43, 0x27, 0x4e, 0xf6, 0x2e, 0x02, 0xf2, 0xb7, + 0x86, 0x2b, 0xb2, 0xf9, 0xee, 0xfe, 0xfd, 0x77, + 0x54, 0x2b, 0x66, 0x62, 0x66, 0x93, 0xf9, 0x6f, + 0x8b, 0x2a, 0x46, 0x62, 0x66, 0x4a, 0xd4, 0x05, + 0x61, 0x2d, 0x44, 0x82, 0x04, 0x12, 0x59, 0x6e, + 0x88, 0x1b, 0x62, 0x64, 0x26, 0x22, 0xf3, 0x2f, + 0x66, 0x2d, 0x04, 0xa8, 0x01, 0xb2, 0x0d, 0x6c, + 0x91, 0x10, 0x6d, 0x14, 0x44, 0x12, 0xeb, 0xbf, + 0x6c, 0x2d, 0x80, 0xab, 0x01, 0xd6, 0x0d, 0xac, + 0xe7, 0x6b, 0x6d, 0x12, 0x44, 0x92, 0xed, 0xbf, + 0x5d, 0x37, 0x17, 0xf4, 0x2f, 0x66, 0x66, 0xce, + 0x07, 0x62, 0x97, 0x61, 0x2e, 0x44, 0x44, 0x8c, + 0x47, 0x72, 0x92, 0xe9, 0x2e, 0x12, 0xe1, 0x2e, + 0xd5, 0x47, 0x02, 0xf0, 0x2f, 0x42, 0xf4, 0x2f, + 0x59, 0xdd, 0x12, 0xe1, 0x2e, 0x12, 0xe1, 0x2e, + 0xd2, 0x4c, 0x62, 0xf6, 0x2f, 0x66, 0x76, 0x67, + 0x66, 0x12, 0x68, 0x56, 0x66, 0x42, 0xf3, 0x37, + 0x83, 0xef, 0x97, 0x79, 0x77, 0x97, 0x79, 0x77, + 0x66, 0x1f, 0x97, 0x79, 0x77, 0x97, 0x79, 0x77, + 0xc7, 0x47, 0x42, 0xf6, 0x2f, 0x62, 0xf6, 0x67, + 0x60, 0x2f, 0x97, 0x79, 0x77, 0x97, 0x79, 0x77, + 0x83, 0xdf, 0x97, 0x79, 0x77, 0x97, 0x79, 0x77, + 0x66, 0x1b, 0x42, 0x62, 0x2e, 0x32, 0xf1, 0x2f, + 0xcd, 0x5b, 0x66, 0x64, 0x26, 0x42, 0xf3, 0x37, + 0x6b, 0x2d, 0x44, 0x54, 0x65, 0x42, 0x62, 0x2e, + 0x0d, 0x40, 0x68, 0x84, 0x44, 0x12, 0xe9, 0x77, + ]), + decompressed: new Uint8Array([ + 0xab, 0xb9, 0x00, 0xff, 0xab, 0xb9, 0x00, 0xff, + 0x93, 0xa4, 0x00, 0xff, 0x7c, 0x8f, 0x00, 0xff, + 0x80, 0x8f, 0x00, 0xff, 0x6e, 0x7e, 0x00, 0xff, + 0x80, 0x8f, 0x00, 0xff, 0x80, 0x8f, 0x00, 0xff, + 0x7c, 0x8c, 0x00, 0xff, 0x7c, 0x8c, 0x00, 0xff, + 0x87, 0x98, 0x00, 0xff, 0x68, 0x79, 0x00, 0xff, + 0x70, 0x81, 0x00, 0xff, 0x81, 0x8d, 0x00, 0xff, + 0x81, 0x8d, 0x00, 0xff, 0x70, 0x81, 0x00, 0xff, + 0x7e, 0x8d, 0x00, 0xff, 0x6c, 0x7c, 0x00, 0xff, + 0x6c, 0x7c, 0x00, 0xff, 0x6c, 0x7c, 0x00, 0xff, + 0x75, 0x75, 0x00, 0xff, 0x75, 0x75, 0x00, 0xff, + 0x75, 0x75, 0x00, 0xff, 0x89, 0x89, 0x00, 0xff, + 0x87, 0x87, 0x00, 0xff, 0x87, 0x87, 0x00, 0xff, + 0x87, 0x87, 0x00, 0xff, 0x87, 0x87, 0x00, 0xff, + 0x7f, 0x7b, 0x00, 0xff, 0x8a, 0x8c, 0x00, 0xff, + 0xa2, 0x98, 0x00, 0xff, 0xae, 0xaa, 0x00, 0xff, + 0xab, 0xb9, 0x00, 0xff, 0x93, 0xa4, 0x00, 0xff, + 0x93, 0xa4, 0x00, 0xff, 0x7c, 0x8f, 0x00, 0xff, + 0x5c, 0x6c, 0x00, 0xff, 0x5c, 0x6c, 0x00, 0xff, + 0x5c, 0x6c, 0x00, 0xff, 0x5c, 0x6c, 0x00, 0xff, + 0x68, 0x79, 0x00, 0xff, 0x70, 0x80, 0x00, 0xff, + 0x68, 0x79, 0x00, 0xff, 0x68, 0x79, 0x00, 0xff, + 0x4c, 0x5e, 0x00, 0xff, 0x4c, 0x5e, 0x00, 0xff, + 0x5e, 0x70, 0x00, 0xff, 0x5e, 0x70, 0x00, 0xff, + 0x5a, 0x6a, 0x00, 0xff, 0x6c, 0x7c, 0x00, 0xff, + 0x6c, 0x7c, 0x00, 0xff, 0x42, 0x52, 0x00, 0xff, + 0x67, 0x67, 0x00, 0xff, 0x67, 0x67, 0x00, 0xff, + 0x67, 0x67, 0x00, 0xff, 0x67, 0x67, 0x00, 0xff, + 0x72, 0x70, 0x00, 0xff, 0x72, 0x70, 0x00, 0xff, + 0x72, 0x70, 0x00, 0xff, 0x67, 0x68, 0x00, 0xff, + 0x7f, 0x69, 0x00, 0xff, 0x96, 0x7b, 0x00, 0xff, + 0xa2, 0x8c, 0x00, 0xff, 0xba, 0x98, 0x00, 0xff, + 0xab, 0xb9, 0x00, 0xff, 0x93, 0xa4, 0x00, 0xff, + 0x6c, 0x7b, 0x00, 0xff, 0x6c, 0x7b, 0x00, 0xff, + 0x5c, 0x6c, 0x00, 0xff, 0x4a, 0x5a, 0x00, 0xff, + 0x38, 0x48, 0x00, 0xff, 0x4a, 0x5a, 0x00, 0xff, + 0x40, 0x51, 0x00, 0xff, 0x54, 0x65, 0x00, 0xff, + 0x54, 0x65, 0x00, 0xff, 0x34, 0x45, 0x00, 0xff, + 0x4c, 0x4c, 0x00, 0xff, 0x3a, 0x3a, 0x00, 0xff, + 0x3a, 0x3a, 0x00, 0xff, 0x4c, 0x4c, 0x00, 0xff, + 0x4b, 0x5b, 0x00, 0xff, 0x4b, 0x5b, 0x00, 0xff, + 0x63, 0x73, 0x00, 0xff, 0x4b, 0x5b, 0x00, 0xff, + 0x3d, 0x3d, 0x00, 0xff, 0x3d, 0x3d, 0x00, 0xff, + 0x52, 0x52, 0x00, 0xff, 0x3d, 0x3d, 0x00, 0xff, + 0x51, 0x40, 0x00, 0xff, 0x51, 0x40, 0x00, 0xff, + 0x5c, 0x4c, 0x00, 0xff, 0x67, 0x54, 0x00, 0xff, + 0x8a, 0x57, 0x00, 0xff, 0x96, 0x69, 0x00, 0xff, + 0xae, 0x7b, 0x00, 0xff, 0xba, 0x8c, 0x00, 0xff, + 0x93, 0xa4, 0x00, 0xff, 0x6c, 0x7b, 0x00, 0xff, + 0x7c, 0x8f, 0x00, 0xff, 0x54, 0x66, 0x00, 0xff, + 0x4a, 0x5a, 0x00, 0xff, 0x38, 0x48, 0x00, 0xff, + 0x38, 0x48, 0x00, 0xff, 0x26, 0x36, 0x00, 0xff, + 0x4c, 0x5d, 0x00, 0xff, 0x40, 0x51, 0x00, 0xff, + 0x34, 0x45, 0x00, 0xff, 0x34, 0x45, 0x00, 0xff, + 0x28, 0x28, 0x00, 0xff, 0x28, 0x28, 0x00, 0xff, + 0x28, 0x28, 0x00, 0xff, 0x28, 0x28, 0x00, 0xff, + 0x39, 0x49, 0x00, 0xff, 0x27, 0x37, 0x00, 0xff, + 0x39, 0x49, 0x00, 0xff, 0x27, 0x37, 0x00, 0xff, + 0x52, 0x52, 0x00, 0xff, 0x28, 0x28, 0x00, 0xff, + 0x1a, 0x1a, 0x00, 0xff, 0x28, 0x28, 0x00, 0xff, + 0x51, 0x40, 0x00, 0xff, 0x5c, 0x4c, 0x00, 0xff, + 0x51, 0x40, 0x00, 0xff, 0x51, 0x40, 0x00, 0xff, + 0x8a, 0x4b, 0x00, 0xff, 0xa2, 0x57, 0x00, 0xff, + 0xae, 0x69, 0x00, 0xff, 0xc2, 0x7b, 0x00, 0xff, + 0x80, 0x80, 0x00, 0xff, 0x6f, 0x6f, 0x00, 0xff, + 0x4b, 0x4b, 0x00, 0xff, 0x5d, 0x5d, 0x00, 0xff, + 0x41, 0x4d, 0x00, 0xff, 0x41, 0x4d, 0x00, 0xff, + 0x20, 0x29, 0x00, 0xff, 0x20, 0x29, 0x00, 0xff, + 0x19, 0x29, 0x00, 0xff, 0x2b, 0x41, 0x00, 0xff, + 0x22, 0x29, 0x00, 0xff, 0x16, 0x1f, 0x00, 0xff, + 0x10, 0x10, 0x00, 0xff, 0x16, 0x14, 0x00, 0xff, + 0x10, 0x10, 0x00, 0xff, 0x19, 0x1a, 0x00, 0xff, + 0x12, 0x11, 0x00, 0xff, 0x22, 0x32, 0x00, 0xff, + 0x12, 0x11, 0x00, 0xff, 0x32, 0x44, 0x00, 0xff, + 0x49, 0x4f, 0x00, 0xff, 0x51, 0x5b, 0x00, 0xff, + 0x31, 0x3b, 0x00, 0xff, 0x31, 0x3b, 0x00, 0xff, + 0x3a, 0x27, 0x00, 0xff, 0x5e, 0x4f, 0x00, 0xff, + 0x72, 0x61, 0x00, 0xff, 0x5e, 0x4f, 0x00, 0xff, + 0x8c, 0x39, 0x00, 0xff, 0x98, 0x45, 0x00, 0xff, + 0xb8, 0x59, 0x00, 0xff, 0xd8, 0x75, 0x00, 0xff, + 0x92, 0x92, 0x00, 0xff, 0x5d, 0x5d, 0x00, 0xff, + 0x4b, 0x4b, 0x00, 0xff, 0x39, 0x39, 0x00, 0xff, + 0x41, 0x4d, 0x00, 0xff, 0x17, 0x29, 0x00, 0xff, + 0x41, 0x4d, 0x00, 0xff, 0x20, 0x29, 0x00, 0xff, + 0x07, 0x19, 0x00, 0xff, 0x07, 0x19, 0x00, 0xff, + 0x22, 0x29, 0x00, 0xff, 0x16, 0x1f, 0x00, 0xff, + 0x19, 0x1a, 0x00, 0xff, 0x10, 0x10, 0x00, 0xff, + 0x16, 0x14, 0x00, 0xff, 0x10, 0x10, 0x00, 0xff, + 0x22, 0x32, 0x00, 0xff, 0x12, 0x11, 0x00, 0xff, + 0x22, 0x32, 0x00, 0xff, 0x12, 0x23, 0x00, 0xff, + 0x3d, 0x47, 0x00, 0xff, 0x31, 0x3b, 0x00, 0xff, + 0x49, 0x4f, 0x00, 0xff, 0x3d, 0x47, 0x00, 0xff, + 0x4a, 0x39, 0x00, 0xff, 0x4a, 0x39, 0x00, 0xff, + 0x5e, 0x4f, 0x00, 0xff, 0x72, 0x61, 0x00, 0xff, + 0xa0, 0x51, 0x00, 0xff, 0x98, 0x45, 0x00, 0xff, + 0xb8, 0x59, 0x00, 0xff, 0xd8, 0x75, 0x00, 0xff, + 0x92, 0x92, 0x00, 0xff, 0x5d, 0x5d, 0x00, 0xff, + 0x39, 0x39, 0x00, 0xff, 0x2d, 0x2d, 0x00, 0xff, + 0x29, 0x3b, 0x00, 0xff, 0x05, 0x14, 0x00, 0xff, + 0x0e, 0x14, 0x00, 0xff, 0x32, 0x3b, 0x00, 0xff, + 0x19, 0x29, 0x00, 0xff, 0x07, 0x19, 0x00, 0xff, + 0x00, 0x07, 0x00, 0xff, 0x16, 0x1f, 0x00, 0xff, + 0x0d, 0x1e, 0x00, 0xff, 0x0d, 0x1e, 0x00, 0xff, + 0x0d, 0x1e, 0x00, 0xff, 0x00, 0x08, 0x00, 0xff, + 0x12, 0x23, 0x00, 0xff, 0x12, 0x23, 0x00, 0xff, + 0x12, 0x23, 0x00, 0xff, 0x22, 0x32, 0x00, 0xff, + 0x3d, 0x1b, 0x00, 0xff, 0x51, 0x2f, 0x00, 0xff, + 0x51, 0x2f, 0x00, 0xff, 0x79, 0x5b, 0x00, 0xff, + 0x7e, 0x49, 0x00, 0xff, 0x7e, 0x49, 0x00, 0xff, + 0x72, 0x3f, 0x00, 0xff, 0x72, 0x3f, 0x00, 0xff, + 0xac, 0x59, 0x00, 0xff, 0xac, 0x59, 0x00, 0xff, + 0xb8, 0x59, 0x00, 0xff, 0xd8, 0x75, 0x00, 0xff, + 0x80, 0x80, 0x00, 0xff, 0x5d, 0x5d, 0x00, 0xff, + 0x39, 0x39, 0x00, 0xff, 0x39, 0x39, 0x00, 0xff, + 0x05, 0x14, 0x00, 0xff, 0x17, 0x29, 0x00, 0xff, + 0x0e, 0x14, 0x00, 0xff, 0x0e, 0x14, 0x00, 0xff, + 0x19, 0x29, 0x00, 0xff, 0x07, 0x19, 0x00, 0xff, + 0x07, 0x13, 0x00, 0xff, 0x00, 0x07, 0x00, 0xff, + 0x19, 0x2a, 0x00, 0xff, 0x19, 0x2a, 0x00, 0xff, + 0x00, 0x08, 0x00, 0xff, 0x19, 0x2a, 0x00, 0xff, + 0x12, 0x11, 0x00, 0xff, 0x12, 0x23, 0x00, 0xff, + 0x12, 0x11, 0x00, 0xff, 0x12, 0x11, 0x00, 0xff, + 0x51, 0x2f, 0x00, 0xff, 0x3d, 0x1b, 0x00, 0xff, + 0x3d, 0x1b, 0x00, 0xff, 0x51, 0x2f, 0x00, 0xff, + 0x72, 0x3f, 0x00, 0xff, 0x7e, 0x49, 0x00, 0xff, + 0x85, 0x55, 0x00, 0xff, 0x85, 0x55, 0x00, 0xff, + 0xa0, 0x51, 0x00, 0xff, 0xac, 0x59, 0x00, 0xff, + 0xb8, 0x59, 0x00, 0xff, 0xd8, 0x75, 0x00, 0xff, + 0x75, 0x84, 0x00, 0xff, 0x51, 0x61, 0x00, 0xff, + 0x3f, 0x4f, 0x00, 0xff, 0x2d, 0x3d, 0x00, 0xff, + 0x29, 0x32, 0x00, 0xff, 0x07, 0x10, 0x00, 0xff, + 0x13, 0x1c, 0x00, 0xff, 0x1d, 0x26, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x05, 0x0e, 0x00, 0xff, + 0x05, 0x0e, 0x00, 0xff, 0x11, 0x17, 0x00, 0xff, + 0x12, 0x21, 0x00, 0xff, 0x12, 0x21, 0x00, 0xff, + 0x2a, 0x21, 0x00, 0xff, 0x12, 0x0b, 0x00, 0xff, + 0x38, 0x1d, 0x00, 0xff, 0x20, 0x07, 0x00, 0xff, + 0x50, 0x1d, 0x00, 0xff, 0x50, 0x1d, 0x00, 0xff, + 0x56, 0x33, 0x00, 0xff, 0x76, 0x54, 0x00, 0xff, + 0x87, 0x33, 0x00, 0xff, 0x68, 0x12, 0x00, 0xff, + 0x94, 0x00, 0x00, 0xff, 0x82, 0x1b, 0x00, 0xff, + 0xaf, 0x4b, 0x00, 0xff, 0xaf, 0x4b, 0x00, 0xff, + 0xd2, 0x5b, 0x00, 0xff, 0xd2, 0x3a, 0x00, 0xff, + 0xd2, 0x5b, 0x00, 0xff, 0xe8, 0x71, 0x00, 0xff, + 0x63, 0x73, 0x00, 0xff, 0x63, 0x73, 0x00, 0xff, + 0x3f, 0x4f, 0x00, 0xff, 0x3f, 0x4f, 0x00, 0xff, + 0x1d, 0x26, 0x00, 0xff, 0x29, 0x32, 0x00, 0xff, + 0x07, 0x10, 0x00, 0xff, 0x13, 0x1c, 0x00, 0xff, + 0x11, 0x17, 0x00, 0xff, 0x00, 0x05, 0x00, 0xff, + 0x05, 0x0e, 0x00, 0xff, 0x11, 0x17, 0x00, 0xff, + 0x06, 0x15, 0x00, 0xff, 0x06, 0x15, 0x00, 0xff, + 0x12, 0x0b, 0x00, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x20, 0x07, 0x00, 0xff, 0x20, 0x07, 0x00, 0xff, + 0x38, 0x07, 0x00, 0xff, 0x5c, 0x29, 0x00, 0xff, + 0x56, 0x33, 0x00, 0xff, 0x87, 0x33, 0x00, 0xff, + 0x76, 0x54, 0x00, 0xff, 0x87, 0x33, 0x00, 0xff, + 0x82, 0x1b, 0x00, 0xff, 0x94, 0x00, 0x00, 0xff, + 0x82, 0x1b, 0x00, 0xff, 0xaf, 0x4b, 0x00, 0xff, + 0xd2, 0x3a, 0x00, 0xff, 0xd2, 0x3a, 0x00, 0xff, + 0xe8, 0x50, 0x00, 0xff, 0xe8, 0x71, 0x00, 0xff, + 0x75, 0x84, 0x00, 0xff, 0x51, 0x61, 0x00, 0xff, + 0x51, 0x61, 0x00, 0xff, 0x2d, 0x3d, 0x00, 0xff, + 0x29, 0x32, 0x00, 0xff, 0x1d, 0x26, 0x00, 0xff, + 0x29, 0x32, 0x00, 0xff, 0x13, 0x1c, 0x00, 0xff, + 0x29, 0x4a, 0x00, 0xff, 0x0e, 0x2f, 0x00, 0xff, + 0x00, 0x17, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x06, 0x15, 0x00, 0xff, 0x00, 0x0b, 0x00, 0xff, + 0x12, 0x0b, 0x00, 0xff, 0x12, 0x0b, 0x00, 0xff, + 0x20, 0x07, 0x00, 0xff, 0x2c, 0x13, 0x00, 0xff, + 0x38, 0x07, 0x00, 0xff, 0x50, 0x1d, 0x00, 0xff, + 0x87, 0x33, 0x00, 0xff, 0x87, 0x33, 0x00, 0xff, + 0x87, 0x33, 0x00, 0xff, 0x87, 0x33, 0x00, 0xff, + 0xaf, 0x4b, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xc1, 0x17, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xd2, 0x5b, 0x00, 0xff, 0xd2, 0x3a, 0x00, 0xff, + 0xe8, 0x50, 0x00, 0xff, 0xe8, 0x71, 0x00, 0xff, + 0x86, 0x96, 0x00, 0xff, 0x63, 0x73, 0x00, 0xff, + 0x2d, 0x3d, 0x00, 0xff, 0x2d, 0x3d, 0x00, 0xff, + 0x1d, 0x26, 0x00, 0xff, 0x13, 0x1c, 0x00, 0xff, + 0x07, 0x10, 0x00, 0xff, 0x1d, 0x26, 0x00, 0xff, + 0x00, 0x17, 0x00, 0xff, 0x29, 0x4a, 0x00, 0xff, + 0x00, 0x17, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x06, 0x15, 0x00, 0xff, + 0x2a, 0x21, 0x00, 0xff, 0x1e, 0x15, 0x00, 0xff, + 0x44, 0x29, 0x00, 0xff, 0x38, 0x1d, 0x00, 0xff, + 0x5c, 0x29, 0x00, 0xff, 0x50, 0x1d, 0x00, 0xff, + 0x87, 0x33, 0x00, 0xff, 0x87, 0x33, 0x00, 0xff, + 0x87, 0x33, 0x00, 0xff, 0x87, 0x33, 0x00, 0xff, + 0xc1, 0x17, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xc1, 0x17, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xd2, 0x3a, 0x00, 0xff, 0xd2, 0x3a, 0x00, 0xff, + 0xe8, 0x50, 0x00, 0xff, 0xe8, 0x71, 0x00, 0xff, + 0x7c, 0x9a, 0x00, 0xff, 0x6d, 0x88, 0x00, 0xff, + 0x54, 0x5f, 0x00, 0xff, 0x18, 0x2f, 0x00, 0xff, + 0x21, 0x21, 0x00, 0xff, 0x0f, 0x0f, 0x00, 0xff, + 0x0f, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x05, 0x05, 0x00, 0xff, + 0x09, 0x11, 0x00, 0xff, 0x09, 0x11, 0x00, 0xff, + 0x0f, 0x18, 0x00, 0xff, 0x0f, 0x18, 0x00, 0xff, + 0x33, 0x24, 0x00, 0xff, 0x3f, 0x2e, 0x00, 0xff, + 0x45, 0x14, 0x00, 0xff, 0x6d, 0x3c, 0x00, 0xff, + 0x6d, 0x20, 0x00, 0xff, 0x8c, 0x42, 0x00, 0xff, + 0x99, 0x33, 0x00, 0xff, 0x99, 0x33, 0x00, 0xff, + 0x99, 0x33, 0x00, 0xff, 0xbb, 0x11, 0x00, 0xff, + 0xc5, 0x06, 0x00, 0xff, 0xcb, 0x0c, 0x00, 0xff, + 0xd5, 0x0f, 0x00, 0xff, 0xe1, 0x14, 0x00, 0xff, + 0xe7, 0x25, 0x00, 0xff, 0xe7, 0x41, 0x00, 0xff, + 0xe7, 0x59, 0x00, 0xff, 0xe7, 0x71, 0x00, 0xff, + 0x7c, 0x9a, 0x00, 0xff, 0x6d, 0x9a, 0x00, 0xff, + 0x6d, 0x7d, 0x00, 0xff, 0x18, 0x2f, 0x00, 0xff, + 0x0f, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x09, 0x11, 0x00, 0xff, 0x09, 0x11, 0x00, 0xff, + 0x27, 0x2e, 0x00, 0xff, 0x27, 0x2e, 0x00, 0xff, + 0x27, 0x18, 0x00, 0xff, 0x4b, 0x3a, 0x00, 0xff, + 0x59, 0x26, 0x00, 0xff, 0x45, 0x14, 0x00, 0xff, + 0x8c, 0x42, 0x00, 0xff, 0x80, 0x36, 0x00, 0xff, + 0x99, 0x33, 0x00, 0xff, 0xa3, 0x3f, 0x00, 0xff, + 0x8d, 0x29, 0x00, 0xff, 0xbb, 0x11, 0x00, 0xff, + 0xc5, 0x06, 0x00, 0xff, 0xcf, 0x09, 0x00, 0xff, + 0xdb, 0x0f, 0x00, 0xff, 0xe5, 0x12, 0x00, 0xff, + 0xe9, 0x25, 0x00, 0xff, 0xe9, 0x3d, 0x00, 0xff, + 0xe9, 0x59, 0x00, 0xff, 0xe9, 0x71, 0x00, 0xff, + 0x8a, 0xac, 0x00, 0xff, 0x6d, 0x88, 0x00, 0xff, + 0x6d, 0x7d, 0x00, 0xff, 0x36, 0x41, 0x00, 0xff, + 0x0f, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x05, 0x05, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x09, 0x11, 0x00, 0xff, + 0x27, 0x2e, 0x00, 0xff, 0x33, 0x3a, 0x00, 0xff, + 0x3f, 0x2e, 0x00, 0xff, 0x4b, 0x3a, 0x00, 0xff, + 0x6d, 0x3c, 0x00, 0xff, 0x6d, 0x3c, 0x00, 0xff, + 0x75, 0x2c, 0x00, 0xff, 0x8c, 0x42, 0x00, 0xff, + 0x99, 0x33, 0x00, 0xff, 0x99, 0x33, 0x00, 0xff, + 0xa3, 0x3f, 0x00, 0xff, 0xbb, 0x11, 0x00, 0xff, + 0xcb, 0x03, 0x00, 0xff, 0xd5, 0x09, 0x00, 0xff, + 0xe1, 0x0c, 0x00, 0xff, 0xeb, 0x12, 0x00, 0xff, + 0xeb, 0x25, 0x00, 0xff, 0xeb, 0x3d, 0x00, 0xff, + 0xeb, 0x59, 0x00, 0xff, 0xeb, 0x71, 0x00, 0xff, + 0x8a, 0xac, 0x00, 0xff, 0x6d, 0x9a, 0x00, 0xff, + 0x6d, 0x7d, 0x00, 0xff, 0x6d, 0x7d, 0x00, 0xff, + 0x36, 0x36, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x11, 0x11, 0x00, 0xff, 0x05, 0x05, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x09, 0x11, 0x00, 0xff, + 0x27, 0x2e, 0x00, 0xff, 0x33, 0x3a, 0x00, 0xff, + 0x4b, 0x3a, 0x00, 0xff, 0x4b, 0x3a, 0x00, 0xff, + 0x6d, 0x3c, 0x00, 0xff, 0x80, 0x4e, 0x00, 0xff, + 0x8c, 0x42, 0x00, 0xff, 0x80, 0x36, 0x00, 0xff, + 0xa3, 0x3f, 0x00, 0xff, 0xa3, 0x3f, 0x00, 0xff, + 0x99, 0x33, 0x00, 0xff, 0xbb, 0x11, 0x00, 0xff, + 0xcf, 0x03, 0x00, 0xff, 0xdb, 0x06, 0x00, 0xff, + 0xe1, 0x0c, 0x00, 0xff, 0xeb, 0x0f, 0x00, 0xff, + 0xed, 0x25, 0x00, 0xff, 0xed, 0x3d, 0x00, 0xff, + 0xed, 0x55, 0x00, 0xff, 0xed, 0x71, 0x00, 0xff, + 0x7d, 0x94, 0x00, 0xff, 0x7d, 0x94, 0x00, 0xff, + 0x5d, 0x77, 0x00, 0xff, 0x5d, 0x77, 0x00, 0xff, + 0x5d, 0x6f, 0x00, 0xff, 0x26, 0x38, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x08, 0x00, 0x00, 0xff, + 0x13, 0x13, 0x00, 0xff, 0x13, 0x13, 0x00, 0xff, + 0x13, 0x13, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x3e, 0x1d, 0x00, 0xff, 0x56, 0x33, 0x00, 0xff, + 0x6c, 0x4b, 0x00, 0xff, 0x6c, 0x4b, 0x00, 0xff, + 0x6a, 0x40, 0x00, 0xff, 0x81, 0x58, 0x00, 0xff, + 0x8d, 0x64, 0x00, 0xff, 0x81, 0x58, 0x00, 0xff, + 0x9f, 0x18, 0x00, 0xff, 0xb4, 0x2d, 0x00, 0xff, + 0xb4, 0x2d, 0x00, 0xff, 0xd2, 0x06, 0x00, 0xff, + 0xd6, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0xff, + 0xe9, 0x0a, 0x00, 0xff, 0xef, 0x10, 0x00, 0xff, + 0xe8, 0x1d, 0x00, 0xff, 0xea, 0x3e, 0x00, 0xff, + 0xec, 0x5f, 0x00, 0xff, 0xf0, 0x80, 0x00, 0xff, + 0x7d, 0x94, 0x00, 0xff, 0x5d, 0x77, 0x00, 0xff, + 0x5d, 0x77, 0x00, 0xff, 0x49, 0x65, 0x00, 0xff, + 0x3f, 0x56, 0x00, 0xff, 0x26, 0x38, 0x00, 0xff, + 0x1c, 0x0b, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x13, 0x13, 0x00, 0xff, 0x13, 0x13, 0x00, 0xff, + 0x33, 0x33, 0x00, 0xff, 0x13, 0x13, 0x00, 0xff, + 0x3e, 0x1d, 0x00, 0xff, 0x56, 0x33, 0x00, 0xff, + 0x56, 0x33, 0x00, 0xff, 0x6c, 0x4b, 0x00, 0xff, + 0x76, 0x4c, 0x00, 0xff, 0x6a, 0x40, 0x00, 0xff, + 0x81, 0x58, 0x00, 0xff, 0x8d, 0x64, 0x00, 0xff, + 0xb4, 0x2d, 0x00, 0xff, 0x9f, 0x18, 0x00, 0xff, + 0xd2, 0x06, 0x00, 0xff, 0xd2, 0x06, 0x00, 0xff, + 0xd6, 0x00, 0x00, 0xff, 0xec, 0x05, 0x00, 0xff, + 0xe9, 0x0a, 0x00, 0xff, 0xef, 0x10, 0x00, 0xff, + 0xe8, 0x1d, 0x00, 0xff, 0xea, 0x3e, 0x00, 0xff, + 0xee, 0x5f, 0x00, 0xff, 0xf0, 0x80, 0x00, 0xff, + 0x71, 0x65, 0x00, 0xff, 0x5d, 0x53, 0x00, 0xff, + 0x49, 0x41, 0x00, 0xff, 0x35, 0x2f, 0x00, 0xff, + 0x26, 0x38, 0x00, 0xff, 0x26, 0x38, 0x00, 0xff, + 0x3f, 0x29, 0x00, 0xff, 0x08, 0x00, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x33, 0x00, 0xff, + 0x33, 0x33, 0x00, 0xff, 0x33, 0x33, 0x00, 0xff, + 0x56, 0x33, 0x00, 0xff, 0x56, 0x33, 0x00, 0xff, + 0x78, 0x33, 0x00, 0xff, 0x78, 0x33, 0x00, 0xff, + 0x8d, 0x34, 0x00, 0xff, 0x8d, 0x34, 0x00, 0xff, + 0x8d, 0x34, 0x00, 0xff, 0xa5, 0x4c, 0x00, 0xff, + 0xb4, 0x2d, 0x00, 0xff, 0xb4, 0x2d, 0x00, 0xff, + 0xd2, 0x06, 0x00, 0xff, 0xd2, 0x06, 0x00, 0xff, + 0xe0, 0x00, 0x00, 0xff, 0xec, 0x05, 0x00, 0xff, + 0xe5, 0x07, 0x00, 0xff, 0xef, 0x10, 0x00, 0xff, + 0xe8, 0x1d, 0x00, 0xff, 0xec, 0x3e, 0x00, 0xff, + 0xee, 0x5f, 0x00, 0xff, 0xf2, 0x80, 0x00, 0xff, + 0x71, 0x65, 0x00, 0xff, 0x5d, 0x53, 0x00, 0xff, + 0x49, 0x41, 0x00, 0xff, 0x35, 0x2f, 0x00, 0xff, + 0x08, 0x1a, 0x00, 0xff, 0x26, 0x38, 0x00, 0xff, + 0x3f, 0x29, 0x00, 0xff, 0x1c, 0x0b, 0x00, 0xff, + 0x33, 0x00, 0x00, 0xff, 0x33, 0x00, 0x00, 0xff, + 0x33, 0x33, 0x00, 0xff, 0x53, 0x53, 0x00, 0xff, + 0x56, 0x33, 0x00, 0xff, 0x6c, 0x4b, 0x00, 0xff, + 0x78, 0x33, 0x00, 0xff, 0x78, 0x33, 0x00, 0xff, + 0x81, 0x28, 0x00, 0xff, 0x99, 0x40, 0x00, 0xff, + 0x99, 0x40, 0x00, 0xff, 0x8d, 0x34, 0x00, 0xff, + 0xb4, 0x2d, 0x00, 0xff, 0xb4, 0x2d, 0x00, 0xff, + 0xd2, 0x06, 0x00, 0xff, 0xd2, 0x06, 0x00, 0xff, + 0xe0, 0x00, 0x00, 0xff, 0xec, 0x05, 0x00, 0xff, + 0xe5, 0x07, 0x00, 0xff, 0xe9, 0x0a, 0x00, 0xff, + 0xea, 0x1d, 0x00, 0xff, 0xec, 0x3e, 0x00, 0xff, + 0xf0, 0x5f, 0x00, 0xff, 0xf2, 0x80, 0x00, 0xff, + 0x7c, 0x75, 0x00, 0xff, 0x58, 0x4b, 0x00, 0xff, + 0x61, 0x4b, 0x00, 0xff, 0x4f, 0x36, 0x00, 0xff, + 0x45, 0x32, 0x00, 0xff, 0x33, 0x23, 0x00, 0xff, + 0x45, 0x32, 0x00, 0xff, 0x45, 0x32, 0x00, 0xff, + 0x56, 0x22, 0x00, 0xff, 0x68, 0x00, 0x00, 0xff, + 0x56, 0x22, 0x00, 0xff, 0x76, 0x43, 0x00, 0xff, + 0x8d, 0x4b, 0x00, 0xff, 0x66, 0x27, 0x00, 0xff, + 0x8d, 0x4b, 0x00, 0xff, 0x7a, 0x39, 0x00, 0xff, + 0x9f, 0x28, 0x00, 0xff, 0x9f, 0x28, 0x00, 0xff, + 0x9f, 0x28, 0x00, 0xff, 0xb5, 0x0b, 0x00, 0xff, + 0xc2, 0x00, 0x00, 0xff, 0xe8, 0x11, 0x00, 0xff, + 0xde, 0x00, 0x00, 0xff, 0xe8, 0x02, 0x00, 0xff, + 0xea, 0x00, 0x00, 0xff, 0xec, 0x05, 0x00, 0xff, + 0xec, 0x0a, 0x00, 0xff, 0xee, 0x10, 0x00, 0xff, + 0xeb, 0x1c, 0x00, 0xff, 0xec, 0x3a, 0x00, 0xff, + 0xed, 0x5d, 0x00, 0xff, 0xee, 0x7b, 0x00, 0xff, + 0x90, 0x89, 0x00, 0xff, 0x58, 0x4b, 0x00, 0xff, + 0x4f, 0x36, 0x00, 0xff, 0x4f, 0x36, 0x00, 0xff, + 0x45, 0x32, 0x00, 0xff, 0x33, 0x23, 0x00, 0xff, + 0x33, 0x23, 0x00, 0xff, 0x54, 0x44, 0x00, 0xff, + 0x76, 0x43, 0x00, 0xff, 0x87, 0x10, 0x00, 0xff, + 0x87, 0x10, 0x00, 0xff, 0x76, 0x43, 0x00, 0xff, + 0x8d, 0x4b, 0x00, 0xff, 0x8d, 0x4b, 0x00, 0xff, + 0x7a, 0x39, 0x00, 0xff, 0x8d, 0x4b, 0x00, 0xff, + 0x9f, 0x28, 0x00, 0xff, 0x9f, 0x28, 0x00, 0xff, + 0xb5, 0x0b, 0x00, 0xff, 0xb5, 0x0b, 0x00, 0xff, + 0xc2, 0x00, 0x00, 0xff, 0xd4, 0x00, 0x00, 0xff, + 0xe4, 0x00, 0x00, 0xff, 0xe4, 0x00, 0x00, 0xff, + 0xe8, 0x01, 0x00, 0xff, 0xea, 0x07, 0x00, 0xff, + 0xea, 0x0c, 0x00, 0xff, 0xec, 0x10, 0x00, 0xff, + 0xeb, 0x1c, 0x00, 0xff, 0xec, 0x3a, 0x00, 0xff, + 0xed, 0x5d, 0x00, 0xff, 0xee, 0x7b, 0x00, 0xff, + 0x90, 0x89, 0x00, 0xff, 0x6d, 0x60, 0x00, 0xff, + 0x4f, 0x36, 0x00, 0xff, 0x61, 0x4b, 0x00, 0xff, + 0x54, 0x44, 0x00, 0xff, 0x54, 0x44, 0x00, 0xff, + 0x66, 0x11, 0x00, 0xff, 0x54, 0x44, 0x00, 0xff, + 0x76, 0x43, 0x00, 0xff, 0x76, 0x43, 0x00, 0xff, + 0x87, 0x10, 0x00, 0xff, 0x87, 0x10, 0x00, 0xff, + 0xad, 0x30, 0x00, 0xff, 0xad, 0x30, 0x00, 0xff, + 0x95, 0x1e, 0x00, 0xff, 0xa1, 0x27, 0x00, 0xff, + 0x9f, 0x28, 0x00, 0xff, 0x9f, 0x28, 0x00, 0xff, + 0xc1, 0x17, 0x00, 0xff, 0xb5, 0x0b, 0x00, 0xff, + 0xd4, 0x00, 0x00, 0xff, 0xd4, 0x00, 0x00, 0xff, + 0xe4, 0x00, 0x00, 0xff, 0xe4, 0x00, 0x00, 0xff, + 0xe6, 0x01, 0x00, 0xff, 0xe8, 0x07, 0x00, 0xff, + 0xe8, 0x0c, 0x00, 0xff, 0xea, 0x10, 0x00, 0xff, + 0xeb, 0x1c, 0x00, 0xff, 0xec, 0x3a, 0x00, 0xff, + 0xed, 0x5d, 0x00, 0xff, 0xee, 0x7b, 0x00, 0xff, + 0x90, 0x89, 0x00, 0xff, 0x7c, 0x75, 0x00, 0xff, + 0x61, 0x4b, 0x00, 0xff, 0x61, 0x4b, 0x00, 0xff, + 0x54, 0x44, 0x00, 0xff, 0x54, 0x44, 0x00, 0xff, + 0x66, 0x11, 0x00, 0xff, 0x66, 0x11, 0x00, 0xff, + 0x76, 0x43, 0x00, 0xff, 0x76, 0x43, 0x00, 0xff, + 0x87, 0x10, 0x00, 0xff, 0x87, 0x10, 0x00, 0xff, + 0x8d, 0x0f, 0x00, 0xff, 0xa1, 0x27, 0x00, 0xff, + 0xa1, 0x27, 0x00, 0xff, 0x8d, 0x0f, 0x00, 0xff, + 0xb5, 0x0b, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xc1, 0x17, 0x00, 0xff, 0xc1, 0x17, 0x00, 0xff, + 0xd4, 0x00, 0x00, 0xff, 0xd4, 0x00, 0x00, 0xff, + 0xde, 0x00, 0x00, 0xff, 0xde, 0x00, 0x00, 0xff, + 0xe4, 0x01, 0x00, 0xff, 0xe6, 0x07, 0x00, 0xff, + 0xe6, 0x0c, 0x00, 0xff, 0xe8, 0x12, 0x00, 0xff, + 0xeb, 0x1c, 0x00, 0xff, 0xec, 0x3a, 0x00, 0xff, + 0xed, 0x58, 0x00, 0xff, 0xee, 0x7b, 0x00, 0xff, + 0x9d, 0x83, 0x00, 0xff, 0x9d, 0x83, 0x00, 0xff, + 0x8e, 0x57, 0x00, 0xff, 0x74, 0x39, 0x00, 0xff, + 0x74, 0x3f, 0x00, 0xff, 0x74, 0x33, 0x00, 0xff, + 0x7d, 0x27, 0x00, 0xff, 0x7d, 0x1d, 0x00, 0xff, + 0x82, 0x1c, 0x00, 0xff, 0x8e, 0x28, 0x00, 0xff, + 0x8e, 0x28, 0x00, 0xff, 0xa4, 0x1c, 0x00, 0xff, + 0xb2, 0x0e, 0x00, 0xff, 0xac, 0x08, 0x00, 0xff, + 0xbc, 0x18, 0x00, 0xff, 0xb8, 0x12, 0x00, 0xff, + 0xbf, 0x00, 0x00, 0xff, 0xc9, 0x03, 0x00, 0xff, + 0xd5, 0x00, 0x00, 0xff, 0xd5, 0x00, 0x00, 0xff, + 0xda, 0x00, 0x00, 0xff, 0xdc, 0x01, 0x00, 0xff, + 0xde, 0x03, 0x00, 0xff, 0xe0, 0x03, 0x00, 0xff, + 0xe3, 0x02, 0x00, 0xff, 0xe5, 0x08, 0x00, 0xff, + 0xe7, 0x0e, 0x00, 0xff, 0xe9, 0x16, 0x00, 0xff, + 0xeb, 0x2b, 0x00, 0xff, 0xed, 0x49, 0x00, 0xff, + 0xef, 0x6d, 0x00, 0xff, 0xef, 0x8a, 0x00, 0xff, + 0x9d, 0x83, 0x00, 0xff, 0xa3, 0x8d, 0x00, 0xff, + 0xa9, 0x70, 0x00, 0xff, 0x8e, 0x57, 0x00, 0xff, + 0x85, 0x3f, 0x00, 0xff, 0x85, 0x33, 0x00, 0xff, + 0x8b, 0x27, 0x00, 0xff, 0x8b, 0x1d, 0x00, 0xff, + 0xa4, 0x1c, 0x00, 0xff, 0xa4, 0x1c, 0x00, 0xff, + 0xb0, 0x28, 0x00, 0xff, 0xa4, 0x1c, 0x00, 0xff, + 0xac, 0x08, 0x00, 0xff, 0xbc, 0x18, 0x00, 0xff, + 0xbc, 0x18, 0x00, 0xff, 0xb2, 0x0e, 0x00, 0xff, + 0xc9, 0x03, 0x00, 0xff, 0xc9, 0x03, 0x00, 0xff, + 0xd5, 0x00, 0x00, 0xff, 0xdb, 0x07, 0x00, 0xff, + 0xdc, 0x06, 0x00, 0xff, 0xde, 0x06, 0x00, 0xff, + 0xe0, 0x06, 0x00, 0xff, 0xe2, 0x09, 0x00, 0xff, + 0xe1, 0x02, 0x00, 0xff, 0xe3, 0x0b, 0x00, 0xff, + 0xe5, 0x13, 0x00, 0xff, 0xe7, 0x19, 0x00, 0xff, + 0xe9, 0x2b, 0x00, 0xff, 0xeb, 0x49, 0x00, 0xff, + 0xed, 0x6d, 0x00, 0xff, 0xef, 0x8a, 0x00, 0xff, + 0xa3, 0x8d, 0x00, 0xff, 0x94, 0x7a, 0x00, 0xff, + 0xa9, 0x70, 0x00, 0xff, 0x8e, 0x57, 0x00, 0xff, + 0x9a, 0x43, 0x00, 0xff, 0x9a, 0x39, 0x00, 0xff, + 0xa0, 0x2d, 0x00, 0xff, 0xa0, 0x21, 0x00, 0xff, + 0xa4, 0x1c, 0x00, 0xff, 0xa4, 0x1c, 0x00, 0xff, + 0xb0, 0x28, 0x00, 0xff, 0xb0, 0x28, 0x00, 0xff, + 0xca, 0x0e, 0x00, 0xff, 0xca, 0x0e, 0x00, 0xff, + 0xca, 0x0e, 0x00, 0xff, 0xd0, 0x12, 0x00, 0xff, + 0xd5, 0x0d, 0x00, 0xff, 0xd5, 0x0d, 0x00, 0xff, + 0xe5, 0x11, 0x00, 0xff, 0xdb, 0x07, 0x00, 0xff, + 0xdc, 0x09, 0x00, 0xff, 0xde, 0x09, 0x00, 0xff, + 0xe0, 0x0c, 0x00, 0xff, 0xe2, 0x0c, 0x00, 0xff, + 0xe1, 0x08, 0x00, 0xff, 0xe3, 0x0e, 0x00, 0xff, + 0xe5, 0x16, 0x00, 0xff, 0xe7, 0x1f, 0x00, 0xff, + 0xe7, 0x3d, 0x00, 0xff, 0xe9, 0x5b, 0x00, 0xff, + 0xeb, 0x7f, 0x00, 0xff, 0xed, 0x9c, 0x00, 0xff, + 0xa3, 0x8d, 0x00, 0xff, 0x94, 0x7a, 0x00, 0xff, + 0xa9, 0x70, 0x00, 0xff, 0x8e, 0x57, 0x00, 0xff, + 0xa9, 0x43, 0x00, 0xff, 0xa9, 0x39, 0x00, 0xff, + 0xb2, 0x2d, 0x00, 0xff, 0xb2, 0x21, 0x00, 0xff, + 0xa4, 0x1c, 0x00, 0xff, 0xb0, 0x28, 0x00, 0xff, + 0xb0, 0x28, 0x00, 0xff, 0xb0, 0x28, 0x00, 0xff, + 0xd6, 0x18, 0x00, 0xff, 0xd0, 0x12, 0x00, 0xff, + 0xd6, 0x18, 0x00, 0xff, 0xd6, 0x18, 0x00, 0xff, + 0xdf, 0x19, 0x00, 0xff, 0xdf, 0x19, 0x00, 0xff, + 0xe5, 0x11, 0x00, 0xff, 0xe5, 0x11, 0x00, 0xff, + 0xde, 0x0e, 0x00, 0xff, 0xe0, 0x0e, 0x00, 0xff, + 0xe2, 0x11, 0x00, 0xff, 0xe4, 0x11, 0x00, 0xff, + 0xdf, 0x0b, 0x00, 0xff, 0xe1, 0x13, 0x00, 0xff, + 0xe3, 0x19, 0x00, 0xff, 0xe5, 0x1f, 0x00, 0xff, + 0xe5, 0x49, 0x00, 0xff, 0xe7, 0x6d, 0x00, 0xff, + 0xe9, 0x8a, 0x00, 0xff, 0xeb, 0x9c, 0x00, 0xff, + 0xd3, 0x8c, 0x00, 0xff, 0xc4, 0x7b, 0x00, 0xff, + 0xbb, 0x57, 0x00, 0xff, 0xbb, 0x57, 0x00, 0xff, + 0xcd, 0x49, 0x00, 0xff, 0xcd, 0x49, 0x00, 0xff, + 0xb8, 0x35, 0x00, 0xff, 0xb8, 0x35, 0x00, 0xff, + 0xcb, 0x2a, 0x00, 0xff, 0xcb, 0x2a, 0x00, 0xff, + 0xcb, 0x2a, 0x00, 0xff, 0xcb, 0x2a, 0x00, 0xff, + 0xd8, 0x1f, 0x00, 0xff, 0xd8, 0x1f, 0x00, 0xff, + 0xdd, 0x1f, 0x00, 0xff, 0xe0, 0x1f, 0x00, 0xff, + 0xe7, 0x27, 0x00, 0xff, 0xe7, 0x1b, 0x00, 0xff, + 0xe7, 0x1b, 0x00, 0xff, 0xe7, 0x1b, 0x00, 0xff, + 0xe3, 0x1d, 0x00, 0xff, 0xe3, 0x1d, 0x00, 0xff, + 0xe3, 0x1d, 0x00, 0xff, 0xe3, 0x1d, 0x00, 0xff, + 0xde, 0x1b, 0x00, 0xff, 0xe0, 0x2a, 0x00, 0xff, + 0xe0, 0x2a, 0x00, 0xff, 0xe3, 0x34, 0x00, 0xff, + 0xe4, 0x51, 0x00, 0xff, 0xe4, 0x69, 0x00, 0xff, + 0xe4, 0x80, 0x00, 0xff, 0xe6, 0x94, 0x00, 0xff, + 0xe8, 0x9e, 0x00, 0xff, 0xd3, 0x8c, 0x00, 0xff, + 0xcd, 0x69, 0x00, 0xff, 0xbb, 0x57, 0x00, 0xff, + 0xcd, 0x49, 0x00, 0xff, 0xcd, 0x49, 0x00, 0xff, + 0xcd, 0x49, 0x00, 0xff, 0xcd, 0x49, 0x00, 0xff, + 0xd8, 0x46, 0x00, 0xff, 0xd8, 0x46, 0x00, 0xff, + 0xd8, 0x42, 0x00, 0xff, 0xd8, 0x42, 0x00, 0xff, + 0xdd, 0x3b, 0x00, 0xff, 0xe0, 0x3b, 0x00, 0xff, + 0xe3, 0x3b, 0x00, 0xff, 0xe6, 0x3b, 0x00, 0xff, + 0xe9, 0x3b, 0x00, 0xff, 0xe9, 0x3b, 0x00, 0xff, + 0xe9, 0x3b, 0x00, 0xff, 0xe9, 0x33, 0x00, 0xff, + 0xe7, 0x37, 0x00, 0xff, 0xe7, 0x37, 0x00, 0xff, + 0xe7, 0x37, 0x00, 0xff, 0xe7, 0x37, 0x00, 0xff, + 0xe3, 0x34, 0x00, 0xff, 0xe3, 0x43, 0x00, 0xff, + 0xe6, 0x43, 0x00, 0xff, 0xe6, 0x52, 0x00, 0xff, + 0xe6, 0x69, 0x00, 0xff, 0xe6, 0x75, 0x00, 0xff, + 0xe8, 0x94, 0x00, 0xff, 0xe8, 0xa0, 0x00, 0xff, + 0xfa, 0xb0, 0x00, 0xff, 0xe8, 0x9e, 0x00, 0xff, + 0xe2, 0x7b, 0x00, 0xff, 0xcd, 0x69, 0x00, 0xff, + 0xe2, 0x65, 0x00, 0xff, 0xe2, 0x65, 0x00, 0xff, + 0xe2, 0x65, 0x00, 0xff, 0xe2, 0x65, 0x00, 0xff, + 0xe5, 0x5e, 0x00, 0xff, 0xe5, 0x5e, 0x00, 0xff, + 0xe5, 0x5a, 0x00, 0xff, 0xe5, 0x5a, 0x00, 0xff, + 0xe3, 0x57, 0x00, 0xff, 0xe6, 0x57, 0x00, 0xff, + 0xe9, 0x57, 0x00, 0xff, 0xec, 0x57, 0x00, 0xff, + 0xeb, 0x57, 0x00, 0xff, 0xeb, 0x57, 0x00, 0xff, + 0xeb, 0x57, 0x00, 0xff, 0xeb, 0x4f, 0x00, 0xff, + 0xeb, 0x51, 0x00, 0xff, 0xeb, 0x51, 0x00, 0xff, + 0xeb, 0x51, 0x00, 0xff, 0xeb, 0x51, 0x00, 0xff, + 0xe6, 0x52, 0x00, 0xff, 0xe9, 0x52, 0x00, 0xff, + 0xe9, 0x61, 0x00, 0xff, 0xe9, 0x6b, 0x00, 0xff, + 0xe8, 0x75, 0x00, 0xff, 0xea, 0x80, 0x00, 0xff, + 0xea, 0xa0, 0x00, 0xff, 0xec, 0xac, 0x00, 0xff, + 0xfa, 0xb0, 0x00, 0xff, 0xfa, 0xb0, 0x00, 0xff, + 0xf1, 0x8c, 0x00, 0xff, 0xf1, 0x8c, 0x00, 0xff, + 0xf7, 0x7d, 0x00, 0xff, 0xf7, 0x7d, 0x00, 0xff, + 0xf7, 0x7d, 0x00, 0xff, 0xf7, 0x7d, 0x00, 0xff, + 0xf2, 0x76, 0x00, 0xff, 0xf2, 0x76, 0x00, 0xff, + 0xf2, 0x76, 0x00, 0xff, 0xf2, 0x76, 0x00, 0xff, + 0xe9, 0x73, 0x00, 0xff, 0xec, 0x73, 0x00, 0xff, + 0xf1, 0x73, 0x00, 0xff, 0xf1, 0x73, 0x00, 0xff, + 0xed, 0x6f, 0x00, 0xff, 0xed, 0x6f, 0x00, 0xff, + 0xed, 0x6f, 0x00, 0xff, 0xed, 0x6f, 0x00, 0xff, + 0xef, 0x6b, 0x00, 0xff, 0xef, 0x6b, 0x00, 0xff, + 0xef, 0x6b, 0x00, 0xff, 0xef, 0x6b, 0x00, 0xff, + 0xeb, 0x6b, 0x00, 0xff, 0xeb, 0x6b, 0x00, 0xff, + 0xee, 0x7a, 0x00, 0xff, 0xee, 0x7a, 0x00, 0xff, + 0xec, 0x80, 0x00, 0xff, 0xec, 0x94, 0x00, 0xff, + 0xee, 0xac, 0x00, 0xff, 0xee, 0xc4, 0x00, 0xff, + ]) +} + +var img_32x32_rgb_etc2 = { + compressed: new Uint8Array([ + 0x8d, 0x9d, 0xb6, 0x4a, 0xc4, 0x80, 0x83, 0x97, + 0x64, 0x74, 0x95, 0x4b, 0xae, 0xa2, 0x91, 0x05, + 0x74, 0x85, 0xa7, 0x25, 0xfa, 0xa6, 0xff, 0x42, + 0x64, 0x74, 0x85, 0x49, 0xae, 0xea, 0x89, 0xba, + 0x64, 0x74, 0x7c, 0x4b, 0xa8, 0x8a, 0xa4, 0x81, + 0x73, 0x73, 0x85, 0x29, 0xab, 0xa3, 0x3e, 0x2a, + 0x75, 0x74, 0x86, 0x25, 0xaa, 0x6e, 0x71, 0x11, + 0xbe, 0x7f, 0x04, 0x62, 0xbb, 0x6c, 0x86, 0xcf, + + 0x74, 0x74, 0x97, 0x48, 0xec, 0xf0, 0x50, 0xe6, + 0x21, 0x30, 0x5f, 0x4a, 0xbd, 0xe8, 0x8e, 0x5b, + 0x10, 0x27, 0x3a, 0x46, 0x8c, 0xe2, 0x87, 0x10, + 0x1e, 0x18, 0x48, 0x07, 0x6b, 0x31, 0xe9, 0xa9, + 0x05, 0x13, 0x23, 0x57, 0x66, 0xd6, 0x34, 0xc4, + 0x43, 0x4e, 0x5c, 0x2b, 0xbd, 0xee, 0x59, 0xb4, + 0x57, 0x44, 0x55, 0x45, 0x44, 0x2b, 0xa9, 0x01, + 0x9a, 0x48, 0x41, 0x2e, 0x00, 0x31, 0xf0, 0xc5, + + 0x6c, 0x7c, 0x9e, 0x4a, 0xfb, 0xf2, 0xd8, 0x58, + 0x18, 0x20, 0x4a, 0x27, 0x6b, 0x90, 0x0e, 0x35, + 0x00, 0x0b, 0x29, 0x2f, 0xcc, 0x29, 0xf0, 0x87, + 0x03, 0x10, 0x2f, 0x26, 0x76, 0x48, 0x29, 0x19, + 0x33, 0x18, 0x40, 0x26, 0x06, 0x76, 0x2e, 0x3e, + 0xb9, 0x06, 0x32, 0x2b, 0x02, 0x13, 0x10, 0x03, + 0x49, 0x15, 0xd0, 0x06, 0xcc, 0xe9, 0x02, 0x33, + 0x6a, 0x06, 0x6b, 0x33, 0xf1, 0x05, 0x01, 0xff, + + 0x74, 0x95, 0xa6, 0x2c, 0x70, 0xf0, 0xbe, 0x5c, + 0x1d, 0x1d, 0x32, 0x4e, 0xfe, 0xf6, 0x4c, 0xe8, + 0x00, 0x01, 0x37, 0x2a, 0x0c, 0x63, 0x0c, 0x6b, + 0x23, 0x28, 0x43, 0x26, 0x03, 0x11, 0xea, 0xd1, + 0x63, 0x30, 0x66, 0x46, 0x05, 0x23, 0x5b, 0xa1, + 0xf3, 0x12, 0x93, 0x46, 0x0b, 0x57, 0x06, 0xa8, + 0x60, 0x86, 0x04, 0xf6, 0x18, 0x46, 0x80, 0x00, + 0x72, 0xa6, 0x0d, 0x73, 0x8b, 0x2f, 0x64, 0x48, + + 0x50, 0x6c, 0x85, 0x6b, 0xec, 0x00, 0xc0, 0x1f, + 0x31, 0x40, 0x63, 0x6c, 0x71, 0xfc, 0x2d, 0x09, + 0x07, 0x01, 0x33, 0x6b, 0x6f, 0x73, 0xa1, 0x33, + 0xeb, 0x35, 0x53, 0x5a, 0x02, 0x7f, 0x31, 0x83, + 0x7b, 0x55, 0x67, 0x27, 0x84, 0x6f, 0x61, 0x29, + 0x51, 0x05, 0x68, 0x8b, 0xfe, 0x00, 0xfe, 0x21, + 0xe0, 0x01, 0x09, 0x22, 0x0c, 0x1f, 0x70, 0x03, + 0x72, 0x9e, 0x0c, 0x7a, 0xa1, 0x2f, 0x43, 0x87, + + 0x77, 0x6d, 0x8f, 0x4a, 0xff, 0x70, 0x36, 0x3e, + 0x0e, 0x15, 0x43, 0x67, 0x13, 0x33, 0x62, 0xfc, + 0xb8, 0x04, 0xb1, 0xb3, 0x31, 0xcf, 0x01, 0x11, + 0x83, 0x44, 0x64, 0x47, 0x96, 0x18, 0x80, 0x5c, + 0x58, 0x14, 0xc9, 0x1a, 0x01, 0x77, 0x72, 0x08, + 0xd9, 0x0f, 0x08, 0x42, 0xef, 0xef, 0x89, 0x03, + 0x74, 0x80, 0x04, 0xf7, 0x14, 0x3f, 0x00, 0x42, + 0x74, 0x9c, 0x07, 0xf7, 0x9b, 0x2f, 0x43, 0x47, + + 0x98, 0x84, 0xa5, 0x0e, 0xf1, 0xd2, 0x10, 0xec, + 0xb8, 0xbc, 0xfa, 0xc2, 0x10, 0x85, 0xc8, 0xd2, + 0x51, 0x05, 0x41, 0x2a, 0x01, 0x11, 0x30, 0x6f, + 0xb3, 0x10, 0x10, 0x03, 0x24, 0x57, 0x8b, 0x3a, + 0xca, 0x08, 0x10, 0x22, 0x73, 0x33, 0x9f, 0x89, + 0x6c, 0x80, 0x05, 0x72, 0x04, 0x0e, 0xe2, 0x46, + 0x70, 0x80, 0x04, 0x76, 0x1c, 0x56, 0xe2, 0x03, + 0x74, 0xa6, 0x0c, 0xfa, 0xa5, 0x37, 0x0a, 0x50, + + 0xdf, 0x94, 0x8d, 0x4a, 0x73, 0x31, 0xb9, 0x9c, + 0xd2, 0x53, 0x53, 0x47, 0x77, 0x77, 0x99, 0x88, + 0x64, 0xae, 0x0d, 0xe6, 0x26, 0x5f, 0xf1, 0xe4, + 0x6a, 0xa0, 0x0c, 0xf2, 0x1e, 0x47, 0x71, 0xe3, + 0x72, 0xa2, 0x0c, 0xf3, 0x18, 0x4f, 0x71, 0xa0, + 0x70, 0x9c, 0x0c, 0x72, 0x1c, 0x47, 0x90, 0xa2, + 0x6e, 0x9a, 0x0c, 0x72, 0x3c, 0x6f, 0x70, 0x61, + 0x70, 0x54, 0x15, 0x73, 0xa7, 0x3f, 0x72, 0x22, + ]), + decompressed: new Uint8Array([ + 0xa9, 0xb9, 0xd2, 0xff, 0xa9, 0xb9, 0xd2, 0xff, + 0x90, 0xa1, 0xc2, 0xff, 0x7c, 0x8d, 0xae, 0xff, + 0x80, 0x90, 0xb1, 0xff, 0x6c, 0x7c, 0x9d, 0xff, + 0x80, 0x90, 0xb1, 0xff, 0x80, 0x90, 0xb1, 0xff, + 0x7c, 0x8d, 0xaf, 0xff, 0x7c, 0x8d, 0xaf, 0xff, + 0x88, 0x99, 0xbb, 0xff, 0x66, 0x77, 0x99, 0xff, + 0x6f, 0x80, 0x91, 0xff, 0x83, 0x94, 0xa5, 0xff, + 0x83, 0x94, 0xa5, 0xff, 0x6f, 0x80, 0x91, 0xff, + 0x80, 0x90, 0x98, 0xff, 0x6c, 0x7c, 0x84, 0xff, + 0x6c, 0x7c, 0x84, 0xff, 0x6c, 0x7c, 0x84, 0xff, + 0x72, 0x72, 0x83, 0xff, 0x7c, 0x7c, 0x8d, 0xff, + 0x72, 0x72, 0x83, 0xff, 0x88, 0x88, 0x99, 0xff, + 0x88, 0x88, 0x99, 0xff, 0x88, 0x88, 0x99, 0xff, + 0x88, 0x88, 0x99, 0xff, 0x88, 0x88, 0x99, 0xff, + 0x7d, 0x7e, 0x82, 0xff, 0x8f, 0x8d, 0x8f, 0xff, + 0xa0, 0x9d, 0x9c, 0xff, 0xb2, 0xac, 0xa9, 0xff, + 0xa9, 0xb9, 0xd2, 0xff, 0x95, 0xa5, 0xbe, 0xff, + 0x90, 0xa1, 0xc2, 0xff, 0x7c, 0x8d, 0xae, 0xff, + 0x5a, 0x6a, 0x8b, 0xff, 0x5a, 0x6a, 0x8b, 0xff, + 0x5a, 0x6a, 0x8b, 0xff, 0x5a, 0x6a, 0x8b, 0xff, + 0x66, 0x77, 0x99, 0xff, 0x72, 0x83, 0xa5, 0xff, + 0x66, 0x77, 0x99, 0xff, 0x66, 0x77, 0x99, 0xff, + 0x49, 0x5a, 0x6b, 0xff, 0x49, 0x5a, 0x6b, 0xff, + 0x5d, 0x6e, 0x7f, 0xff, 0x5d, 0x6e, 0x7f, 0xff, + 0x5a, 0x6a, 0x72, 0xff, 0x6c, 0x7c, 0x84, 0xff, + 0x6c, 0x7c, 0x84, 0xff, 0x46, 0x56, 0x5e, 0xff, + 0x66, 0x66, 0x77, 0xff, 0x66, 0x66, 0x77, 0xff, + 0x66, 0x66, 0x77, 0xff, 0x66, 0x66, 0x77, 0xff, + 0x72, 0x72, 0x83, 0xff, 0x72, 0x72, 0x83, 0xff, + 0x72, 0x72, 0x83, 0xff, 0x66, 0x66, 0x77, 0xff, + 0x82, 0x6c, 0x71, 0xff, 0x94, 0x7b, 0x7e, 0xff, + 0xa5, 0x8b, 0x8b, 0xff, 0xb7, 0x9a, 0x98, 0xff, + 0xa9, 0xb9, 0xd2, 0xff, 0x95, 0xa5, 0xbe, 0xff, + 0x6a, 0x7b, 0x9c, 0xff, 0x6a, 0x7b, 0x9c, 0xff, + 0x5f, 0x6f, 0x98, 0xff, 0x4b, 0x5b, 0x84, 0xff, + 0x39, 0x49, 0x72, 0xff, 0x4b, 0x5b, 0x84, 0xff, + 0x3f, 0x50, 0x72, 0xff, 0x55, 0x66, 0x88, 0xff, + 0x55, 0x66, 0x88, 0xff, 0x33, 0x44, 0x66, 0xff, + 0x4d, 0x4d, 0x5e, 0xff, 0x3b, 0x3b, 0x4c, 0xff, + 0x3b, 0x3b, 0x4c, 0xff, 0x4d, 0x4d, 0x5e, 0xff, + 0x4b, 0x5b, 0x63, 0xff, 0x4b, 0x5b, 0x63, 0xff, + 0x5f, 0x6f, 0x77, 0xff, 0x4b, 0x5b, 0x63, 0xff, + 0x3c, 0x3c, 0x5e, 0xff, 0x3c, 0x3c, 0x5e, 0xff, + 0x50, 0x50, 0x72, 0xff, 0x3c, 0x3c, 0x5e, 0xff, + 0x50, 0x3f, 0x61, 0xff, 0x50, 0x3f, 0x61, 0xff, + 0x5a, 0x49, 0x6b, 0xff, 0x66, 0x55, 0x77, 0xff, + 0x88, 0x5a, 0x5f, 0xff, 0x99, 0x69, 0x6c, 0xff, + 0xab, 0x79, 0x79, 0xff, 0xbc, 0x88, 0x86, 0xff, + 0x95, 0xa5, 0xbe, 0xff, 0x6f, 0x7f, 0x98, 0xff, + 0x7c, 0x8d, 0xae, 0xff, 0x56, 0x67, 0x88, 0xff, + 0x4b, 0x5b, 0x84, 0xff, 0x39, 0x49, 0x72, 0xff, + 0x39, 0x49, 0x72, 0xff, 0x25, 0x35, 0x5e, 0xff, + 0x49, 0x5a, 0x7c, 0xff, 0x3f, 0x50, 0x72, 0xff, + 0x33, 0x44, 0x66, 0xff, 0x33, 0x44, 0x66, 0xff, + 0x27, 0x27, 0x38, 0xff, 0x27, 0x27, 0x38, 0xff, + 0x27, 0x27, 0x38, 0xff, 0x27, 0x27, 0x38, 0xff, + 0x39, 0x49, 0x51, 0xff, 0x25, 0x35, 0x3d, 0xff, + 0x39, 0x49, 0x51, 0xff, 0x25, 0x35, 0x3d, 0xff, + 0x50, 0x50, 0x72, 0xff, 0x2a, 0x2a, 0x4c, 0xff, + 0x16, 0x16, 0x38, 0xff, 0x2a, 0x2a, 0x4c, 0xff, + 0x50, 0x3f, 0x61, 0xff, 0x5a, 0x49, 0x6b, 0xff, + 0x50, 0x3f, 0x61, 0xff, 0x50, 0x3f, 0x61, 0xff, + 0x8d, 0x48, 0x4e, 0xff, 0x9e, 0x57, 0x5b, 0xff, + 0xb0, 0x67, 0x68, 0xff, 0xc1, 0x76, 0x75, 0xff, + 0x80, 0x80, 0xa2, 0xff, 0x6e, 0x6e, 0x90, 0xff, + 0x4d, 0x4d, 0x80, 0xff, 0x61, 0x61, 0x94, 0xff, + 0x3e, 0x4e, 0x77, 0xff, 0x3e, 0x4e, 0x77, 0xff, + 0x20, 0x28, 0x49, 0xff, 0x20, 0x28, 0x49, 0xff, + 0x19, 0x2a, 0x42, 0xff, 0x2d, 0x3e, 0x56, 0xff, + 0x21, 0x29, 0x5b, 0xff, 0x15, 0x1d, 0x4f, 0xff, + 0x10, 0x10, 0x42, 0xff, 0x16, 0x16, 0x48, 0xff, + 0x10, 0x10, 0x42, 0xff, 0x1a, 0x1a, 0x4c, 0xff, + 0x11, 0x11, 0x33, 0xff, 0x22, 0x33, 0x55, 0xff, + 0x11, 0x11, 0x33, 0xff, 0x32, 0x43, 0x65, 0xff, + 0x47, 0x4f, 0x5f, 0xff, 0x53, 0x5b, 0x6b, 0xff, + 0x31, 0x39, 0x49, 0xff, 0x31, 0x39, 0x49, 0xff, + 0x38, 0x27, 0x38, 0xff, 0x5e, 0x4d, 0x5e, 0xff, + 0x72, 0x61, 0x72, 0xff, 0x5e, 0x4d, 0x5e, 0xff, + 0x8b, 0x39, 0x31, 0xff, 0x97, 0x45, 0x3d, 0xff, + 0xba, 0x57, 0x57, 0xff, 0xd7, 0x74, 0x74, 0xff, + 0x94, 0x94, 0xb6, 0xff, 0x5a, 0x5a, 0x7c, 0xff, + 0x4d, 0x4d, 0x80, 0xff, 0x3b, 0x3b, 0x6e, 0xff, + 0x3e, 0x4e, 0x77, 0xff, 0x18, 0x28, 0x51, 0xff, + 0x46, 0x4e, 0x6f, 0xff, 0x20, 0x28, 0x49, 0xff, + 0x07, 0x18, 0x30, 0xff, 0x07, 0x18, 0x30, 0xff, + 0x21, 0x29, 0x5b, 0xff, 0x15, 0x1d, 0x4f, 0xff, + 0x1a, 0x1a, 0x4c, 0xff, 0x10, 0x10, 0x42, 0xff, + 0x16, 0x16, 0x48, 0xff, 0x10, 0x10, 0x42, 0xff, + 0x22, 0x33, 0x55, 0xff, 0x11, 0x11, 0x33, 0xff, + 0x22, 0x33, 0x55, 0xff, 0x12, 0x23, 0x45, 0xff, + 0x3d, 0x45, 0x55, 0xff, 0x31, 0x39, 0x49, 0xff, + 0x47, 0x4f, 0x5f, 0xff, 0x3d, 0x45, 0x55, 0xff, + 0x4c, 0x3b, 0x4c, 0xff, 0x4c, 0x3b, 0x4c, 0xff, + 0x5e, 0x4d, 0x5e, 0xff, 0x72, 0x61, 0x72, 0xff, + 0xa1, 0x4f, 0x47, 0xff, 0x97, 0x45, 0x3d, 0xff, + 0xba, 0x57, 0x57, 0xff, 0xd7, 0x74, 0x74, 0xff, + 0x94, 0x94, 0xb6, 0xff, 0x5a, 0x5a, 0x7c, 0xff, + 0x3b, 0x3b, 0x6e, 0xff, 0x27, 0x27, 0x5a, 0xff, + 0x2a, 0x3a, 0x63, 0xff, 0x04, 0x14, 0x3d, 0xff, + 0x0c, 0x14, 0x35, 0xff, 0x32, 0x3a, 0x5b, 0xff, + 0x19, 0x2a, 0x42, 0xff, 0x07, 0x18, 0x30, 0xff, + 0x00, 0x07, 0x39, 0xff, 0x15, 0x1d, 0x4f, 0xff, + 0x0d, 0x1d, 0x4f, 0xff, 0x0d, 0x1d, 0x4f, 0xff, + 0x0d, 0x1d, 0x4f, 0xff, 0x00, 0x07, 0x39, 0xff, + 0x12, 0x23, 0x45, 0xff, 0x12, 0x23, 0x45, 0xff, + 0x12, 0x23, 0x45, 0xff, 0x22, 0x33, 0x55, 0xff, + 0x3d, 0x1c, 0x1c, 0xff, 0x51, 0x30, 0x30, 0xff, + 0x51, 0x30, 0x30, 0xff, 0x77, 0x56, 0x56, 0xff, + 0x7c, 0x49, 0x5a, 0xff, 0x7c, 0x49, 0x5a, 0xff, + 0x72, 0x3f, 0x50, 0xff, 0x72, 0x3f, 0x50, 0xff, + 0xad, 0x5b, 0x53, 0xff, 0xad, 0x5b, 0x53, 0xff, + 0xba, 0x57, 0x57, 0xff, 0xd7, 0x74, 0x74, 0xff, + 0x80, 0x80, 0xa2, 0xff, 0x5a, 0x5a, 0x7c, 0xff, + 0x3b, 0x3b, 0x6e, 0xff, 0x3b, 0x3b, 0x6e, 0xff, + 0x04, 0x14, 0x3d, 0xff, 0x18, 0x28, 0x51, 0xff, + 0x0c, 0x14, 0x35, 0xff, 0x0c, 0x14, 0x35, 0xff, + 0x19, 0x2a, 0x42, 0xff, 0x07, 0x18, 0x30, 0xff, + 0x0b, 0x13, 0x45, 0xff, 0x00, 0x07, 0x39, 0xff, + 0x19, 0x29, 0x5b, 0xff, 0x19, 0x29, 0x5b, 0xff, + 0x00, 0x07, 0x39, 0xff, 0x19, 0x29, 0x5b, 0xff, + 0x11, 0x11, 0x33, 0xff, 0x12, 0x23, 0x45, 0xff, + 0x11, 0x11, 0x33, 0xff, 0x11, 0x11, 0x33, 0xff, + 0x51, 0x30, 0x30, 0xff, 0x3d, 0x1c, 0x1c, 0xff, + 0x3d, 0x1c, 0x1c, 0xff, 0x51, 0x30, 0x30, 0xff, + 0x72, 0x3f, 0x50, 0xff, 0x7c, 0x49, 0x5a, 0xff, + 0x88, 0x55, 0x66, 0xff, 0x88, 0x55, 0x66, 0xff, + 0xa1, 0x4f, 0x47, 0xff, 0xad, 0x5b, 0x53, 0xff, + 0xba, 0x57, 0x57, 0xff, 0xd7, 0x74, 0x74, 0xff, + 0x74, 0x84, 0xa5, 0xff, 0x4e, 0x5e, 0x7f, 0xff, + 0x41, 0x51, 0x83, 0xff, 0x2d, 0x3d, 0x6f, 0xff, + 0x29, 0x32, 0x5b, 0xff, 0x07, 0x10, 0x39, 0xff, + 0x13, 0x1c, 0x45, 0xff, 0x1d, 0x26, 0x4f, 0xff, + 0x00, 0x00, 0x18, 0xff, 0x05, 0x0d, 0x2e, 0xff, + 0x05, 0x0d, 0x2e, 0xff, 0x11, 0x19, 0x3a, 0xff, + 0x11, 0x21, 0x3a, 0xff, 0x11, 0x21, 0x3a, 0xff, + 0x29, 0x21, 0x32, 0xff, 0x13, 0x0b, 0x1c, 0xff, + 0x36, 0x1d, 0x47, 0xff, 0x20, 0x07, 0x31, 0xff, + 0x4f, 0x1d, 0x47, 0xff, 0x4f, 0x1d, 0x47, 0xff, + 0x56, 0x34, 0x45, 0xff, 0x76, 0x54, 0x65, 0xff, + 0x87, 0x32, 0x54, 0xff, 0x67, 0x12, 0x34, 0xff, + 0x93, 0x00, 0x00, 0xff, 0x82, 0x1c, 0x1c, 0xff, + 0xb0, 0x4a, 0x4a, 0xff, 0xb0, 0x4a, 0x4a, 0xff, + 0xd2, 0x5b, 0x5b, 0xff, 0xd2, 0x39, 0x39, 0xff, + 0xd2, 0x5b, 0x5b, 0xff, 0xe8, 0x71, 0x71, 0xff, + 0x62, 0x72, 0x93, 0xff, 0x62, 0x72, 0x93, 0xff, + 0x41, 0x51, 0x83, 0xff, 0x41, 0x51, 0x83, 0xff, + 0x1d, 0x26, 0x4f, 0xff, 0x29, 0x32, 0x5b, 0xff, + 0x07, 0x10, 0x39, 0xff, 0x13, 0x1c, 0x45, 0xff, + 0x11, 0x19, 0x3a, 0xff, 0x00, 0x03, 0x24, 0xff, + 0x05, 0x0d, 0x2e, 0xff, 0x11, 0x19, 0x3a, 0xff, + 0x05, 0x15, 0x2e, 0xff, 0x05, 0x15, 0x2e, 0xff, + 0x13, 0x0b, 0x1c, 0xff, 0x07, 0x00, 0x10, 0xff, + 0x20, 0x07, 0x31, 0xff, 0x20, 0x07, 0x31, 0xff, + 0x39, 0x07, 0x31, 0xff, 0x5b, 0x29, 0x53, 0xff, + 0x56, 0x34, 0x45, 0xff, 0x87, 0x32, 0x54, 0xff, + 0x76, 0x54, 0x65, 0xff, 0x87, 0x32, 0x54, 0xff, + 0x82, 0x1c, 0x1c, 0xff, 0x93, 0x00, 0x00, 0xff, + 0x82, 0x1c, 0x1c, 0xff, 0xb0, 0x4a, 0x4a, 0xff, + 0xd2, 0x39, 0x39, 0xff, 0xd2, 0x39, 0x39, 0xff, + 0xe8, 0x4f, 0x4f, 0xff, 0xe8, 0x71, 0x71, 0xff, + 0x74, 0x84, 0xa5, 0xff, 0x4e, 0x5e, 0x7f, 0xff, + 0x53, 0x63, 0x95, 0xff, 0x2d, 0x3d, 0x6f, 0xff, + 0x29, 0x32, 0x6b, 0xff, 0x1d, 0x26, 0x5f, 0xff, + 0x29, 0x32, 0x6b, 0xff, 0x13, 0x1c, 0x55, 0xff, + 0x2a, 0x4b, 0x5b, 0xff, 0x0d, 0x2e, 0x3e, 0xff, + 0x00, 0x14, 0x24, 0xff, 0x00, 0x00, 0x07, 0xff, + 0x05, 0x15, 0x2e, 0xff, 0x00, 0x0b, 0x24, 0xff, + 0x13, 0x0b, 0x1c, 0xff, 0x13, 0x0b, 0x1c, 0xff, + 0x20, 0x07, 0x31, 0xff, 0x2c, 0x13, 0x3d, 0xff, + 0x39, 0x07, 0x31, 0xff, 0x4f, 0x1d, 0x47, 0xff, + 0x87, 0x32, 0x54, 0xff, 0x87, 0x32, 0x54, 0xff, + 0x87, 0x32, 0x54, 0xff, 0x87, 0x32, 0x54, 0xff, + 0xb0, 0x4a, 0x4a, 0xff, 0xc1, 0x17, 0x17, 0xff, + 0xc1, 0x17, 0x17, 0xff, 0xc1, 0x17, 0x17, 0xff, + 0xd2, 0x5b, 0x5b, 0xff, 0xd2, 0x39, 0x39, 0xff, + 0xe8, 0x4f, 0x4f, 0xff, 0xe8, 0x71, 0x71, 0xff, + 0x88, 0x98, 0xb9, 0xff, 0x62, 0x72, 0x93, 0xff, + 0x2d, 0x3d, 0x6f, 0xff, 0x2d, 0x3d, 0x6f, 0xff, + 0x1d, 0x26, 0x5f, 0xff, 0x13, 0x1c, 0x55, 0xff, + 0x07, 0x10, 0x49, 0xff, 0x1d, 0x26, 0x5f, 0xff, + 0x00, 0x14, 0x24, 0xff, 0x2a, 0x4b, 0x5b, 0xff, + 0x00, 0x14, 0x24, 0xff, 0x00, 0x00, 0x07, 0xff, + 0x00, 0x00, 0x18, 0xff, 0x05, 0x15, 0x2e, 0xff, + 0x29, 0x21, 0x32, 0xff, 0x1d, 0x15, 0x26, 0xff, + 0x42, 0x29, 0x53, 0xff, 0x36, 0x1d, 0x47, 0xff, + 0x5b, 0x29, 0x53, 0xff, 0x4f, 0x1d, 0x47, 0xff, + 0x87, 0x32, 0x54, 0xff, 0x87, 0x32, 0x54, 0xff, + 0x87, 0x32, 0x54, 0xff, 0x87, 0x32, 0x54, 0xff, + 0xc1, 0x17, 0x17, 0xff, 0xc1, 0x17, 0x17, 0xff, + 0xc1, 0x17, 0x17, 0xff, 0xc1, 0x17, 0x17, 0xff, + 0xd2, 0x39, 0x39, 0xff, 0xd2, 0x39, 0x39, 0xff, + 0xe8, 0x4f, 0x4f, 0xff, 0xe8, 0x71, 0x71, 0xff, + 0x7c, 0x9e, 0xaf, 0xff, 0x66, 0x88, 0x99, 0xff, + 0x51, 0x62, 0x73, 0xff, 0x1a, 0x2b, 0x3c, 0xff, + 0x21, 0x21, 0x3a, 0xff, 0x0f, 0x0f, 0x28, 0xff, + 0x0d, 0x0d, 0x4f, 0xff, 0x00, 0x00, 0x35, 0xff, + 0x00, 0x00, 0x20, 0xff, 0x05, 0x05, 0x36, 0xff, + 0x09, 0x11, 0x32, 0xff, 0x09, 0x11, 0x32, 0xff, + 0x10, 0x18, 0x31, 0xff, 0x10, 0x18, 0x31, 0xff, + 0x34, 0x24, 0x55, 0xff, 0x3e, 0x2e, 0x5f, 0xff, + 0x46, 0x14, 0x46, 0xff, 0x6c, 0x3a, 0x6c, 0xff, + 0x6a, 0x20, 0x41, 0xff, 0x8c, 0x42, 0x63, 0xff, + 0x99, 0x33, 0x44, 0xff, 0x99, 0x33, 0x44, 0xff, + 0x99, 0x33, 0x44, 0xff, 0xbb, 0x11, 0x22, 0xff, + 0xc3, 0x06, 0x04, 0xff, 0xcd, 0x0b, 0x0b, 0xff, + 0xd7, 0x0f, 0x12, 0xff, 0xe1, 0x14, 0x19, 0xff, + 0xe7, 0x26, 0x28, 0xff, 0xe7, 0x3f, 0x44, 0xff, + 0xe7, 0x59, 0x5f, 0xff, 0xe7, 0x72, 0x7b, 0xff, + 0x7c, 0x9e, 0xaf, 0xff, 0x72, 0x94, 0xa5, 0xff, + 0x6e, 0x7f, 0x90, 0xff, 0x1a, 0x2b, 0x3c, 0xff, + 0x0f, 0x0f, 0x28, 0xff, 0x00, 0x00, 0x14, 0xff, + 0x00, 0x00, 0x35, 0xff, 0x00, 0x00, 0x35, 0xff, + 0x00, 0x00, 0x20, 0xff, 0x00, 0x00, 0x20, 0xff, + 0x09, 0x11, 0x32, 0xff, 0x09, 0x11, 0x32, 0xff, + 0x26, 0x2e, 0x47, 0xff, 0x26, 0x2e, 0x47, 0xff, + 0x28, 0x18, 0x49, 0xff, 0x4a, 0x3a, 0x6b, 0xff, + 0x5a, 0x28, 0x5a, 0xff, 0x46, 0x14, 0x46, 0xff, + 0x8c, 0x42, 0x63, 0xff, 0x80, 0x36, 0x57, 0xff, + 0x99, 0x33, 0x44, 0xff, 0xa4, 0x3e, 0x4f, 0xff, + 0x8e, 0x28, 0x39, 0xff, 0xbb, 0x11, 0x22, 0xff, + 0xc7, 0x05, 0x03, 0xff, 0xd1, 0x09, 0x0a, 0xff, + 0xdb, 0x0e, 0x11, 0xff, 0xe5, 0x12, 0x18, 0xff, + 0xe9, 0x25, 0x26, 0xff, 0xe9, 0x3e, 0x42, 0xff, + 0xe9, 0x58, 0x5d, 0xff, 0xe9, 0x71, 0x79, 0xff, + 0x88, 0xaa, 0xbb, 0xff, 0x66, 0x88, 0x99, 0xff, + 0x6e, 0x7f, 0x90, 0xff, 0x37, 0x48, 0x59, 0xff, + 0x0f, 0x0f, 0x28, 0xff, 0x00, 0x00, 0x14, 0xff, + 0x00, 0x00, 0x18, 0xff, 0x00, 0x00, 0x18, 0xff, + 0x05, 0x05, 0x36, 0xff, 0x00, 0x00, 0x20, 0xff, + 0x00, 0x00, 0x0c, 0xff, 0x09, 0x11, 0x32, 0xff, + 0x26, 0x2e, 0x47, 0xff, 0x32, 0x3a, 0x53, 0xff, + 0x3e, 0x2e, 0x5f, 0xff, 0x4a, 0x3a, 0x6b, 0xff, + 0x6c, 0x3a, 0x6c, 0xff, 0x6c, 0x3a, 0x6c, 0xff, + 0x76, 0x2c, 0x4d, 0xff, 0x8c, 0x42, 0x63, 0xff, + 0x99, 0x33, 0x44, 0xff, 0x99, 0x33, 0x44, 0xff, + 0xa4, 0x3e, 0x4f, 0xff, 0xbb, 0x11, 0x22, 0xff, + 0xcb, 0x03, 0x02, 0xff, 0xd5, 0x08, 0x09, 0xff, + 0xdf, 0x0c, 0x10, 0xff, 0xe9, 0x11, 0x17, 0xff, + 0xeb, 0x24, 0x24, 0xff, 0xeb, 0x3d, 0x40, 0xff, + 0xeb, 0x57, 0x5b, 0xff, 0xeb, 0x70, 0x77, 0xff, + 0x88, 0xaa, 0xbb, 0xff, 0x72, 0x94, 0xa5, 0xff, + 0x6e, 0x7f, 0x90, 0xff, 0x6e, 0x7f, 0x90, 0xff, + 0x35, 0x35, 0x4e, 0xff, 0x00, 0x00, 0x14, 0xff, + 0x00, 0x00, 0x18, 0xff, 0x00, 0x00, 0x35, 0xff, + 0x11, 0x11, 0x42, 0xff, 0x05, 0x05, 0x36, 0xff, + 0x00, 0x00, 0x0c, 0xff, 0x09, 0x11, 0x32, 0xff, + 0x26, 0x2e, 0x47, 0xff, 0x32, 0x3a, 0x53, 0xff, + 0x4a, 0x3a, 0x6b, 0xff, 0x4a, 0x3a, 0x6b, 0xff, + 0x6c, 0x3a, 0x6c, 0xff, 0x80, 0x4e, 0x80, 0xff, + 0x8c, 0x42, 0x63, 0xff, 0x80, 0x36, 0x57, 0xff, + 0xa4, 0x3e, 0x4f, 0xff, 0xa4, 0x3e, 0x4f, 0xff, + 0x99, 0x33, 0x44, 0xff, 0xbb, 0x11, 0x22, 0xff, + 0xcf, 0x02, 0x01, 0xff, 0xd9, 0x06, 0x08, 0xff, + 0xe3, 0x0b, 0x0f, 0xff, 0xed, 0x0f, 0x16, 0xff, + 0xed, 0x23, 0x22, 0xff, 0xed, 0x3c, 0x3e, 0xff, + 0xed, 0x56, 0x59, 0xff, 0xed, 0x6f, 0x75, 0xff, + 0x7c, 0x95, 0xae, 0xff, 0x7c, 0x95, 0xae, 0xff, + 0x5f, 0x78, 0x91, 0xff, 0x5f, 0x78, 0x91, 0xff, + 0x5d, 0x6e, 0x90, 0xff, 0x26, 0x37, 0x59, 0xff, + 0x00, 0x00, 0x09, 0xff, 0x04, 0x00, 0x26, 0xff, + 0x13, 0x13, 0x46, 0xff, 0x13, 0x13, 0x46, 0xff, + 0x13, 0x13, 0x46, 0xff, 0x33, 0x00, 0x11, 0xff, + 0x3e, 0x1c, 0x3e, 0xff, 0x55, 0x33, 0x55, 0xff, + 0x6c, 0x4a, 0x6c, 0xff, 0x6c, 0x4a, 0x6c, 0xff, + 0x6a, 0x41, 0x52, 0xff, 0x80, 0x57, 0x68, 0xff, + 0x8c, 0x63, 0x74, 0xff, 0x80, 0x57, 0x68, 0xff, + 0x9f, 0x17, 0x17, 0xff, 0xb5, 0x2d, 0x2d, 0xff, + 0xb5, 0x2d, 0x2d, 0xff, 0xd2, 0x06, 0x06, 0xff, + 0xd6, 0x00, 0x00, 0xff, 0xe2, 0x00, 0x03, 0xff, + 0xe9, 0x0a, 0x12, 0xff, 0xef, 0x10, 0x18, 0xff, + 0xe7, 0x1e, 0x20, 0xff, 0xea, 0x3f, 0x3e, 0xff, + 0xed, 0x60, 0x5b, 0xff, 0xf0, 0x80, 0x79, 0xff, + 0x7c, 0x95, 0xae, 0xff, 0x5f, 0x78, 0x91, 0xff, + 0x5f, 0x78, 0x91, 0xff, 0x45, 0x5e, 0x77, 0xff, + 0x40, 0x51, 0x73, 0xff, 0x26, 0x37, 0x59, 0xff, + 0x1e, 0x0d, 0x40, 0xff, 0x00, 0x00, 0x09, 0xff, + 0x13, 0x13, 0x46, 0xff, 0x13, 0x13, 0x46, 0xff, + 0x33, 0x33, 0x66, 0xff, 0x13, 0x13, 0x46, 0xff, + 0x3e, 0x1c, 0x3e, 0xff, 0x55, 0x33, 0x55, 0xff, + 0x55, 0x33, 0x55, 0xff, 0x6c, 0x4a, 0x6c, 0xff, + 0x76, 0x4d, 0x5e, 0xff, 0x6a, 0x41, 0x52, 0xff, + 0x80, 0x57, 0x68, 0xff, 0x8c, 0x63, 0x74, 0xff, + 0xb5, 0x2d, 0x2d, 0xff, 0x9f, 0x17, 0x17, 0xff, + 0xd2, 0x06, 0x06, 0xff, 0xd2, 0x06, 0x06, 0xff, + 0xd6, 0x00, 0x00, 0xff, 0xec, 0x05, 0x0d, 0xff, + 0xe9, 0x0a, 0x12, 0xff, 0xef, 0x10, 0x18, 0xff, + 0xe8, 0x1e, 0x1f, 0xff, 0xeb, 0x3e, 0x3d, 0xff, + 0xee, 0x5f, 0x5a, 0xff, 0xf1, 0x80, 0x78, 0xff, + 0x6f, 0x67, 0x88, 0xff, 0x5b, 0x53, 0x74, 0xff, + 0x49, 0x41, 0x62, 0xff, 0x35, 0x2d, 0x4e, 0xff, + 0x26, 0x37, 0x59, 0xff, 0x26, 0x37, 0x59, 0xff, + 0x3b, 0x2a, 0x5d, 0xff, 0x04, 0x00, 0x26, 0xff, + 0x33, 0x00, 0x11, 0xff, 0x33, 0x33, 0x66, 0xff, + 0x33, 0x33, 0x66, 0xff, 0x33, 0x33, 0x66, 0xff, + 0x55, 0x33, 0x55, 0xff, 0x55, 0x33, 0x55, 0xff, + 0x77, 0x33, 0x55, 0xff, 0x77, 0x33, 0x55, 0xff, + 0x8f, 0x34, 0x55, 0xff, 0x8f, 0x34, 0x55, 0xff, + 0x8f, 0x34, 0x55, 0xff, 0xa5, 0x4a, 0x6b, 0xff, + 0xb5, 0x2d, 0x2d, 0xff, 0xb5, 0x2d, 0x2d, 0xff, + 0xd2, 0x06, 0x06, 0xff, 0xd2, 0x06, 0x06, 0xff, + 0xe2, 0x00, 0x03, 0xff, 0xec, 0x05, 0x0d, 0xff, + 0xe5, 0x06, 0x0e, 0xff, 0xef, 0x10, 0x18, 0xff, + 0xe9, 0x1d, 0x1e, 0xff, 0xec, 0x3e, 0x3c, 0xff, + 0xef, 0x5f, 0x59, 0xff, 0xf2, 0x7f, 0x77, 0xff, + 0x6f, 0x67, 0x88, 0xff, 0x5b, 0x53, 0x74, 0xff, + 0x49, 0x41, 0x62, 0xff, 0x35, 0x2d, 0x4e, 0xff, + 0x09, 0x1a, 0x3c, 0xff, 0x26, 0x37, 0x59, 0xff, + 0x3b, 0x2a, 0x5d, 0xff, 0x1e, 0x0d, 0x40, 0xff, + 0x33, 0x00, 0x11, 0xff, 0x33, 0x00, 0x11, 0xff, + 0x33, 0x33, 0x66, 0xff, 0x53, 0x53, 0x86, 0xff, + 0x55, 0x33, 0x55, 0xff, 0x6c, 0x4a, 0x6c, 0xff, + 0x77, 0x33, 0x55, 0xff, 0x77, 0x33, 0x55, 0xff, + 0x83, 0x28, 0x49, 0xff, 0x99, 0x3e, 0x5f, 0xff, + 0x99, 0x3e, 0x5f, 0xff, 0x8f, 0x34, 0x55, 0xff, + 0xb5, 0x2d, 0x2d, 0xff, 0xb5, 0x2d, 0x2d, 0xff, + 0xd2, 0x06, 0x06, 0xff, 0xd2, 0x06, 0x06, 0xff, + 0xe2, 0x00, 0x03, 0xff, 0xec, 0x05, 0x0d, 0xff, + 0xe5, 0x06, 0x0e, 0xff, 0xe9, 0x0a, 0x12, 0xff, + 0xea, 0x1d, 0x1d, 0xff, 0xed, 0x3d, 0x3b, 0xff, + 0xf0, 0x5e, 0x58, 0xff, 0xf3, 0x7f, 0x76, 0xff, + 0x7c, 0x74, 0x95, 0xff, 0x56, 0x4e, 0x6f, 0xff, + 0x62, 0x49, 0x7b, 0xff, 0x4e, 0x35, 0x67, 0xff, + 0x44, 0x33, 0x66, 0xff, 0x34, 0x23, 0x56, 0xff, + 0x44, 0x33, 0x66, 0xff, 0x44, 0x33, 0x66, 0xff, + 0x56, 0x23, 0x56, 0xff, 0x67, 0x00, 0x01, 0xff, + 0x56, 0x23, 0x56, 0xff, 0x76, 0x43, 0x76, 0xff, + 0x8d, 0x4b, 0x6c, 0xff, 0x67, 0x25, 0x46, 0xff, + 0x8d, 0x4b, 0x6c, 0xff, 0x7b, 0x39, 0x5a, 0xff, + 0x9f, 0x28, 0x39, 0xff, 0x9f, 0x28, 0x39, 0xff, + 0x9f, 0x28, 0x39, 0xff, 0xb5, 0x0b, 0x0b, 0xff, + 0xc1, 0x00, 0x00, 0xff, 0xe7, 0x11, 0x11, 0xff, + 0xdf, 0x00, 0x00, 0xff, 0xe9, 0x02, 0x0a, 0xff, + 0xeb, 0x00, 0x04, 0xff, 0xec, 0x05, 0x0a, 0xff, + 0xed, 0x0a, 0x10, 0xff, 0xee, 0x0f, 0x16, 0xff, + 0xeb, 0x1c, 0x1c, 0xff, 0xec, 0x3c, 0x3b, 0xff, + 0xed, 0x5c, 0x59, 0xff, 0xee, 0x7b, 0x78, 0xff, + 0x90, 0x88, 0xa9, 0xff, 0x56, 0x4e, 0x6f, 0xff, + 0x4e, 0x35, 0x67, 0xff, 0x4e, 0x35, 0x67, 0xff, + 0x44, 0x33, 0x66, 0xff, 0x34, 0x23, 0x56, 0xff, + 0x34, 0x23, 0x56, 0xff, 0x54, 0x43, 0x76, 0xff, + 0x76, 0x43, 0x76, 0xff, 0x87, 0x10, 0x21, 0xff, + 0x87, 0x10, 0x21, 0xff, 0x76, 0x43, 0x76, 0xff, + 0x8d, 0x4b, 0x6c, 0xff, 0x8d, 0x4b, 0x6c, 0xff, + 0x7b, 0x39, 0x5a, 0xff, 0x8d, 0x4b, 0x6c, 0xff, + 0x9f, 0x28, 0x39, 0xff, 0x9f, 0x28, 0x39, 0xff, + 0xb5, 0x0b, 0x0b, 0xff, 0xb5, 0x0b, 0x0b, 0xff, + 0xc1, 0x00, 0x00, 0xff, 0xd5, 0x00, 0x00, 0xff, + 0xe5, 0x00, 0x06, 0xff, 0xe5, 0x00, 0x06, 0xff, + 0xe9, 0x01, 0x05, 0xff, 0xea, 0x06, 0x0b, 0xff, + 0xeb, 0x0b, 0x11, 0xff, 0xec, 0x10, 0x17, 0xff, + 0xeb, 0x1c, 0x1c, 0xff, 0xec, 0x3b, 0x3b, 0xff, + 0xed, 0x5b, 0x59, 0xff, 0xee, 0x7b, 0x78, 0xff, + 0x90, 0x88, 0xa9, 0xff, 0x6a, 0x62, 0x83, 0xff, + 0x4e, 0x35, 0x67, 0xff, 0x62, 0x49, 0x7b, 0xff, + 0x54, 0x43, 0x76, 0xff, 0x54, 0x43, 0x76, 0xff, + 0x66, 0x11, 0x55, 0xff, 0x54, 0x43, 0x76, 0xff, + 0x76, 0x43, 0x76, 0xff, 0x76, 0x43, 0x76, 0xff, + 0x87, 0x10, 0x21, 0xff, 0x87, 0x10, 0x21, 0xff, + 0xad, 0x32, 0x53, 0xff, 0xad, 0x32, 0x53, 0xff, + 0x97, 0x1c, 0x3d, 0xff, 0xa1, 0x26, 0x47, 0xff, + 0x9f, 0x28, 0x39, 0xff, 0x9f, 0x28, 0x39, 0xff, + 0xc1, 0x17, 0x17, 0xff, 0xb5, 0x0b, 0x0b, 0xff, + 0xd5, 0x00, 0x00, 0xff, 0xd5, 0x00, 0x00, 0xff, + 0xe5, 0x00, 0x06, 0xff, 0xe5, 0x00, 0x06, 0xff, + 0xe7, 0x01, 0x06, 0xff, 0xe8, 0x06, 0x0c, 0xff, + 0xe9, 0x0b, 0x12, 0xff, 0xea, 0x10, 0x18, 0xff, + 0xeb, 0x1b, 0x1c, 0xff, 0xec, 0x3b, 0x3b, 0xff, + 0xed, 0x5b, 0x59, 0xff, 0xee, 0x7a, 0x78, 0xff, + 0x90, 0x88, 0xa9, 0xff, 0x7c, 0x74, 0x95, 0xff, + 0x62, 0x49, 0x7b, 0xff, 0x62, 0x49, 0x7b, 0xff, + 0x54, 0x43, 0x76, 0xff, 0x54, 0x43, 0x76, 0xff, + 0x66, 0x11, 0x55, 0xff, 0x66, 0x11, 0x55, 0xff, + 0x76, 0x43, 0x76, 0xff, 0x76, 0x43, 0x76, 0xff, + 0x87, 0x10, 0x21, 0xff, 0x87, 0x10, 0x21, 0xff, + 0x8b, 0x10, 0x31, 0xff, 0xa1, 0x26, 0x47, 0xff, + 0xa1, 0x26, 0x47, 0xff, 0x8b, 0x10, 0x31, 0xff, + 0xb5, 0x0b, 0x0b, 0xff, 0xc1, 0x17, 0x17, 0xff, + 0xc1, 0x17, 0x17, 0xff, 0xc1, 0x17, 0x17, 0xff, + 0xd5, 0x00, 0x00, 0xff, 0xd5, 0x00, 0x00, 0xff, + 0xdf, 0x00, 0x00, 0xff, 0xdf, 0x00, 0x00, 0xff, + 0xe5, 0x02, 0x07, 0xff, 0xe6, 0x07, 0x0d, 0xff, + 0xe7, 0x0c, 0x13, 0xff, 0xe8, 0x11, 0x19, 0xff, + 0xeb, 0x1b, 0x1c, 0xff, 0xec, 0x3a, 0x3b, 0xff, + 0xed, 0x5a, 0x59, 0xff, 0xee, 0x7a, 0x78, 0xff, + 0x9e, 0x86, 0xa7, 0xff, 0x9a, 0x82, 0xa3, 0xff, + 0x8f, 0x56, 0x7f, 0xff, 0x72, 0x39, 0x62, 0xff, + 0x71, 0x3c, 0x75, 0xff, 0x75, 0x31, 0x68, 0xff, + 0x7a, 0x26, 0x5b, 0xff, 0x7e, 0x1b, 0x4e, 0xff, + 0x82, 0x1c, 0x4f, 0xff, 0x8e, 0x28, 0x5b, 0xff, + 0x8e, 0x28, 0x5b, 0xff, 0xa4, 0x1c, 0x1c, 0xff, + 0xb3, 0x0e, 0x0e, 0xff, 0xad, 0x08, 0x08, 0xff, + 0xbd, 0x18, 0x18, 0xff, 0xb7, 0x12, 0x12, 0xff, + 0xbd, 0x00, 0x00, 0xff, 0xc9, 0x03, 0x0b, 0xff, + 0xd6, 0x00, 0x08, 0xff, 0xd6, 0x00, 0x08, 0xff, + 0xdb, 0x00, 0x08, 0xff, 0xdd, 0x01, 0x07, 0xff, + 0xdf, 0x02, 0x06, 0xff, 0xe1, 0x03, 0x05, 0xff, + 0xe3, 0x00, 0x00, 0xff, 0xe5, 0x07, 0x0a, 0xff, + 0xe7, 0x0e, 0x14, 0xff, 0xe9, 0x15, 0x1e, 0xff, + 0xeb, 0x26, 0x24, 0xff, 0xed, 0x46, 0x42, 0xff, + 0xef, 0x66, 0x5f, 0xff, 0xf1, 0x85, 0x7d, 0xff, + 0x9a, 0x82, 0xa3, 0xff, 0xa4, 0x8c, 0xad, 0xff, + 0xa9, 0x70, 0x99, 0xff, 0x8f, 0x56, 0x7f, 0xff, + 0x83, 0x3f, 0x6a, 0xff, 0x88, 0x34, 0x5d, 0xff, + 0x8c, 0x29, 0x50, 0xff, 0x90, 0x1e, 0x43, 0xff, + 0xa4, 0x1c, 0x1c, 0xff, 0xa4, 0x1c, 0x1c, 0xff, + 0xb0, 0x28, 0x28, 0xff, 0xa4, 0x1c, 0x1c, 0xff, + 0xad, 0x08, 0x08, 0xff, 0xbd, 0x18, 0x18, 0xff, + 0xbd, 0x18, 0x18, 0xff, 0xb3, 0x0e, 0x0e, 0xff, + 0xc9, 0x03, 0x0b, 0xff, 0xc9, 0x03, 0x0b, 0xff, + 0xd6, 0x00, 0x08, 0xff, 0xdc, 0x06, 0x0e, 0xff, + 0xdc, 0x05, 0x0c, 0xff, 0xde, 0x06, 0x0b, 0xff, + 0xe0, 0x07, 0x0a, 0xff, 0xe2, 0x08, 0x09, 0xff, + 0xe2, 0x04, 0x03, 0xff, 0xe4, 0x0b, 0x0d, 0xff, + 0xe6, 0x12, 0x17, 0xff, 0xe8, 0x19, 0x21, 0xff, + 0xe9, 0x31, 0x2b, 0xff, 0xeb, 0x51, 0x49, 0xff, + 0xed, 0x71, 0x66, 0xff, 0xef, 0x90, 0x84, 0xff, + 0xa4, 0x8c, 0xad, 0xff, 0x94, 0x7c, 0x9d, 0xff, + 0xa9, 0x70, 0x99, 0xff, 0x8f, 0x56, 0x7f, 0xff, + 0x96, 0x41, 0x5f, 0xff, 0x9a, 0x36, 0x52, 0xff, + 0x9e, 0x2b, 0x45, 0xff, 0xa2, 0x20, 0x38, 0xff, + 0xa4, 0x1c, 0x1c, 0xff, 0xa4, 0x1c, 0x1c, 0xff, + 0xb0, 0x28, 0x28, 0xff, 0xb0, 0x28, 0x28, 0xff, + 0xcc, 0x0e, 0x0e, 0xff, 0xcc, 0x0e, 0x0e, 0xff, + 0xcc, 0x0e, 0x0e, 0xff, 0xd0, 0x12, 0x12, 0xff, + 0xd3, 0x0d, 0x15, 0xff, 0xd3, 0x0d, 0x15, 0xff, + 0xe6, 0x10, 0x18, 0xff, 0xdc, 0x06, 0x0e, 0xff, + 0xdd, 0x09, 0x10, 0xff, 0xdf, 0x0a, 0x0f, 0xff, + 0xe1, 0x0b, 0x0e, 0xff, 0xe3, 0x0c, 0x0d, 0xff, + 0xe1, 0x08, 0x06, 0xff, 0xe3, 0x0f, 0x10, 0xff, + 0xe5, 0x16, 0x1a, 0xff, 0xe7, 0x1d, 0x24, 0xff, + 0xe7, 0x3c, 0x33, 0xff, 0xe9, 0x5c, 0x50, 0xff, + 0xeb, 0x7c, 0x6e, 0xff, 0xed, 0x9b, 0x8b, 0xff, + 0xa4, 0x8c, 0xad, 0xff, 0x94, 0x7c, 0x9d, 0xff, + 0xa9, 0x70, 0x99, 0xff, 0x8f, 0x56, 0x7f, 0xff, + 0xa8, 0x44, 0x54, 0xff, 0xac, 0x39, 0x47, 0xff, + 0xb0, 0x2e, 0x3a, 0xff, 0xb5, 0x23, 0x2d, 0xff, + 0xa4, 0x1c, 0x1c, 0xff, 0xb0, 0x28, 0x28, 0xff, + 0xb0, 0x28, 0x28, 0xff, 0xb0, 0x28, 0x28, 0xff, + 0xd6, 0x18, 0x18, 0xff, 0xd0, 0x12, 0x12, 0xff, + 0xd6, 0x18, 0x18, 0xff, 0xd6, 0x18, 0x18, 0xff, + 0xdf, 0x19, 0x21, 0xff, 0xdf, 0x19, 0x21, 0xff, + 0xe6, 0x10, 0x18, 0xff, 0xe6, 0x10, 0x18, 0xff, + 0xde, 0x0e, 0x14, 0xff, 0xe0, 0x0f, 0x13, 0xff, + 0xe2, 0x10, 0x12, 0xff, 0xe4, 0x11, 0x11, 0xff, + 0xe0, 0x0c, 0x09, 0xff, 0xe2, 0x13, 0x13, 0xff, + 0xe4, 0x1a, 0x1d, 0xff, 0xe6, 0x21, 0x27, 0xff, + 0xe5, 0x47, 0x3a, 0xff, 0xe7, 0x67, 0x57, 0xff, + 0xe9, 0x87, 0x75, 0xff, 0xeb, 0xa6, 0x92, 0xff, + 0xd5, 0x8b, 0x83, 0xff, 0xc1, 0x77, 0x6f, 0xff, + 0xb9, 0x56, 0x56, 0xff, 0xb9, 0x56, 0x56, 0xff, + 0xcd, 0x49, 0x49, 0xff, 0xcd, 0x49, 0x49, 0xff, + 0xb9, 0x35, 0x35, 0xff, 0xb9, 0x35, 0x35, 0xff, + 0xcb, 0x2e, 0x2c, 0xff, 0xcb, 0x2c, 0x2c, 0xff, + 0xcb, 0x2a, 0x2c, 0xff, 0xcb, 0x28, 0x2c, 0xff, + 0xd7, 0x20, 0x24, 0xff, 0xda, 0x20, 0x23, 0xff, + 0xdd, 0x1f, 0x22, 0xff, 0xe0, 0x1f, 0x21, 0xff, + 0xe7, 0x22, 0x24, 0xff, 0xe7, 0x20, 0x24, 0xff, + 0xe7, 0x1d, 0x24, 0xff, 0xe7, 0x1b, 0x24, 0xff, + 0xe3, 0x1c, 0x20, 0xff, 0xe3, 0x1c, 0x20, 0xff, + 0xe3, 0x1c, 0x20, 0xff, 0xe3, 0x1c, 0x20, 0xff, + 0xdf, 0x1a, 0x20, 0xff, 0xe0, 0x23, 0x25, 0xff, + 0xe1, 0x2b, 0x2a, 0xff, 0xe2, 0x34, 0x2f, 0xff, + 0xe3, 0x54, 0x49, 0xff, 0xe4, 0x69, 0x5e, 0xff, + 0xe5, 0x7e, 0x74, 0xff, 0xe6, 0x92, 0x89, 0xff, + 0xe7, 0x9d, 0x95, 0xff, 0xd5, 0x8b, 0x83, 0xff, + 0xcd, 0x6a, 0x6a, 0xff, 0xb9, 0x56, 0x56, 0xff, + 0xcd, 0x49, 0x49, 0xff, 0xcd, 0x49, 0x49, 0xff, + 0xcd, 0x49, 0x49, 0xff, 0xcd, 0x49, 0x49, 0xff, + 0xd8, 0x46, 0x46, 0xff, 0xd8, 0x44, 0x46, 0xff, + 0xd8, 0x42, 0x46, 0xff, 0xd8, 0x40, 0x46, 0xff, + 0xdd, 0x3c, 0x3f, 0xff, 0xe0, 0x3b, 0x3e, 0xff, + 0xe3, 0x3b, 0x3d, 0xff, 0xe6, 0x3a, 0x3c, 0xff, + 0xe9, 0x3d, 0x3c, 0xff, 0xe9, 0x3a, 0x3c, 0xff, + 0xe9, 0x38, 0x3c, 0xff, 0xe9, 0x35, 0x3c, 0xff, + 0xe7, 0x36, 0x3b, 0xff, 0xe7, 0x36, 0x3b, 0xff, + 0xe7, 0x36, 0x3b, 0xff, 0xe7, 0x36, 0x3b, 0xff, + 0xe3, 0x34, 0x3a, 0xff, 0xe4, 0x3d, 0x3f, 0xff, + 0xe5, 0x45, 0x44, 0xff, 0xe6, 0x4e, 0x49, 0xff, + 0xe6, 0x63, 0x59, 0xff, 0xe7, 0x78, 0x6f, 0xff, + 0xe8, 0x8d, 0x84, 0xff, 0xe9, 0xa2, 0x99, 0xff, + 0xfb, 0xb1, 0xa9, 0xff, 0xe7, 0x9d, 0x95, 0xff, + 0xdf, 0x7c, 0x7c, 0xff, 0xcd, 0x6a, 0x6a, 0xff, + 0xe2, 0x66, 0x66, 0xff, 0xe2, 0x66, 0x66, 0xff, + 0xe2, 0x66, 0x66, 0xff, 0xe2, 0x66, 0x66, 0xff, + 0xe5, 0x5f, 0x5f, 0xff, 0xe5, 0x5d, 0x5f, 0xff, + 0xe5, 0x5b, 0x5f, 0xff, 0xe5, 0x59, 0x5f, 0xff, + 0xe3, 0x58, 0x59, 0xff, 0xe6, 0x57, 0x58, 0xff, + 0xe9, 0x57, 0x57, 0xff, 0xec, 0x56, 0x56, 0xff, + 0xeb, 0x58, 0x53, 0xff, 0xeb, 0x55, 0x53, 0xff, + 0xeb, 0x53, 0x53, 0xff, 0xeb, 0x50, 0x53, 0xff, + 0xeb, 0x51, 0x55, 0xff, 0xeb, 0x51, 0x55, 0xff, + 0xeb, 0x51, 0x55, 0xff, 0xeb, 0x51, 0x55, 0xff, + 0xe7, 0x4f, 0x53, 0xff, 0xe8, 0x57, 0x58, 0xff, + 0xe9, 0x60, 0x5d, 0xff, 0xea, 0x68, 0x62, 0xff, + 0xe9, 0x73, 0x6a, 0xff, 0xea, 0x87, 0x7f, 0xff, + 0xeb, 0x9c, 0x94, 0xff, 0xec, 0xb1, 0xa9, 0xff, + 0xfb, 0xb1, 0xa9, 0xff, 0xfb, 0xb1, 0xa9, 0xff, + 0xf3, 0x90, 0x90, 0xff, 0xf3, 0x90, 0x90, 0xff, + 0xf8, 0x7c, 0x7c, 0xff, 0xf8, 0x7c, 0x7c, 0xff, + 0xf8, 0x7c, 0x7c, 0xff, 0xf8, 0x7c, 0x7c, 0xff, + 0xf2, 0x77, 0x79, 0xff, 0xf2, 0x75, 0x79, 0xff, + 0xf2, 0x73, 0x79, 0xff, 0xf2, 0x71, 0x79, 0xff, + 0xe9, 0x73, 0x74, 0xff, 0xec, 0x73, 0x73, 0xff, + 0xef, 0x72, 0x72, 0xff, 0xf2, 0x72, 0x71, 0xff, + 0xed, 0x72, 0x6b, 0xff, 0xed, 0x70, 0x6b, 0xff, + 0xed, 0x6d, 0x6b, 0xff, 0xed, 0x6b, 0x6b, 0xff, + 0xef, 0x6b, 0x70, 0xff, 0xef, 0x6b, 0x70, 0xff, + 0xef, 0x6b, 0x70, 0xff, 0xef, 0x6b, 0x70, 0xff, + 0xeb, 0x69, 0x6d, 0xff, 0xec, 0x71, 0x72, 0xff, + 0xed, 0x7a, 0x77, 0xff, 0xee, 0x82, 0x7c, 0xff, + 0xec, 0x82, 0x7a, 0xff, 0xed, 0x97, 0x8f, 0xff, + 0xee, 0xab, 0xa4, 0xff, 0xef, 0xc0, 0xba, 0xff, + ]) +} + +var img_32x32_rgb_punchthrough_etc2 = { + compressed: new Uint8Array([ + 0x84, 0x94, 0xb4, 0x05, 0xf6, 0xff, 0x99, 0x00, + 0x74, 0x84, 0xa4, 0x05, 0xff, 0xf6, 0x08, 0x91, + 0x5f, 0x6f, 0x8f, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x4b, 0x5b, 0x6b, 0x00, 0xff, 0xfd, 0x20, 0x00, + 0x56, 0x66, 0x6e, 0x00, 0xdf, 0xfd, 0x00, 0x02, + 0x0e, 0x67, 0x33, 0x54, 0xff, 0xb9, 0x00, 0xc4, + 0xeb, 0x78, 0x54, 0x61, 0xff, 0xff, 0x08, 0x00, + 0x8b, 0x4b, 0x53, 0x00, 0xff, 0xf7, 0x00, 0x00, + 0xeb, 0x79, 0x44, 0x74, 0xff, 0xff, 0x80, 0x00, + 0x01, 0x10, 0x3f, 0x00, 0xfb, 0xb7, 0x00, 0x00, + 0x10, 0x27, 0x3a, 0x00, 0xff, 0xfb, 0x00, 0xc4, + 0x05, 0x24, 0x00, 0x38, 0xff, 0xef, 0x00, 0x10, + 0x05, 0x13, 0x23, 0x50, 0xfe, 0xff, 0x00, 0x00, + 0x41, 0x4c, 0x5c, 0x25, 0xff, 0xa7, 0x00, 0xb0, + 0x61, 0x43, 0x53, 0x00, 0xfe, 0xff, 0x01, 0x00, + 0x8b, 0x3b, 0x33, 0x01, 0xff, 0x9e, 0x00, 0x60, + 0x0e, 0x79, 0x34, 0x71, 0xff, 0xff, 0x80, 0x00, + 0x18, 0x20, 0x58, 0x04, 0xbb, 0xbf, 0x04, 0x40, + 0x16, 0x25, 0x3d, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x03, 0x10, 0x2f, 0x00, 0xff, 0xdf, 0x00, 0x60, + 0x0c, 0x24, 0x21, 0x31, 0xee, 0xff, 0x00, 0x10, + 0x79, 0x3f, 0x50, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x93, 0x34, 0x34, 0x21, 0xfa, 0xf7, 0x07, 0x08, + 0xf9, 0x66, 0xc3, 0x31, 0xff, 0x3f, 0x00, 0xc0, + 0x74, 0x94, 0xa4, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x0f, 0x0f, 0x21, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x01, 0x01, 0x22, 0x0d, 0x7f, 0x70, 0x08, 0x00, + 0x23, 0x28, 0x43, 0x00, 0xff, 0xf7, 0x00, 0x08, + 0x6a, 0x3f, 0x6d, 0x04, 0xe7, 0xef, 0x19, 0x00, + 0xa6, 0x46, 0x56, 0x00, 0xf7, 0x77, 0x00, 0x00, + 0xc3, 0x08, 0x09, 0x00, 0xff, 0xfc, 0x00, 0x00, + 0xef, 0x43, 0x4b, 0x00, 0xff, 0xff, 0x00, 0x70, + 0x6c, 0x74, 0x94, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x21, 0x35, 0x57, 0x04, 0xf7, 0xcf, 0x88, 0x30, + 0x06, 0x13, 0x33, 0x65, 0x77, 0x77, 0x88, 0x00, + 0x0e, 0x35, 0x42, 0x4c, 0xea, 0x3f, 0x11, 0x80, + 0x88, 0x64, 0x74, 0x01, 0xf2, 0xbb, 0x08, 0x00, + 0x1c, 0x00, 0xa2, 0x24, 0xf0, 0xff, 0x01, 0x00, + 0xd2, 0x01, 0x01, 0x01, 0xff, 0xfc, 0x00, 0x04, + 0xe1, 0x3b, 0x3b, 0x00, 0xff, 0x1f, 0x00, 0x60, + 0x58, 0x4f, 0x70, 0x01, 0x7f, 0xff, 0x80, 0x00, + 0x3b, 0x2d, 0x5f, 0x01, 0xfa, 0xff, 0x07, 0x10, + 0x6a, 0x2e, 0x55, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x88, 0x30, 0x50, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x15, 0x23, 0xb1, 0x11, 0xf2, 0xff, 0x0e, 0x00, + 0xdf, 0x00, 0x00, 0x01, 0xfc, 0xbf, 0x02, 0x20, + 0xe0, 0x02, 0x0a, 0x00, 0x7f, 0xff, 0x00, 0x00, + 0xe0, 0x27, 0x27, 0x21, 0xff, 0xe8, 0x00, 0x10, + 0x90, 0x6e, 0x96, 0x01, 0xff, 0xff, 0xc0, 0x00, + 0x8e, 0x3c, 0x5e, 0x00, 0xef, 0xff, 0x00, 0x00, + 0xf2, 0x22, 0x82, 0x51, 0xff, 0xff, 0x00, 0x01, + 0xb2, 0x17, 0x17, 0x01, 0xaa, 0xba, 0x45, 0x54, + 0xc2, 0x0f, 0x08, 0x04, 0x7e, 0xef, 0x80, 0x01, + 0xd9, 0x09, 0x10, 0x00, 0xff, 0xb3, 0x00, 0x00, + 0xe0, 0x12, 0x1a, 0x01, 0x6c, 0xff, 0x10, 0x20, + 0xef, 0x4b, 0x43, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xb3, 0x53, 0x53, 0x01, 0xef, 0xff, 0x00, 0x00, + 0xc0, 0x40, 0x40, 0x00, 0xdd, 0xdd, 0x22, 0x22, + 0xd0, 0x40, 0x40, 0x00, 0xdd, 0xdd, 0x00, 0x00, + 0xd8, 0x38, 0x38, 0x00, 0xfd, 0xdd, 0x00, 0x00, + 0xe0, 0x33, 0x3b, 0x01, 0xdb, 0xbf, 0x04, 0x40, + 0xe0, 0x47, 0x4e, 0x00, 0xdf, 0xff, 0x00, 0x00, + 0xd8, 0x37, 0x3e, 0x00, 0xee, 0xdd, 0x10, 0x20, + 0xe0, 0x73, 0x6b, 0x00, 0xff, 0xff, 0x00, 0x00, + ]), + decompressed: new Uint8Array([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0x9c, 0xbd, 0xff, 0x7c, 0x8c, 0xad, 0xff, + 0x7b, 0x8c, 0xad, 0xff, 0x6b, 0x7c, 0x9d, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4a, 0x5a, 0x6b, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5b, 0x6b, 0x7c, 0xff, + 0x5a, 0x6b, 0x73, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x42, 0x52, 0x5a, 0xff, + 0x66, 0x66, 0x77, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3e, 0x3e, 0x60, 0xff, 0x3e, 0x3e, 0x60, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x84, 0xa5, 0xff, 0x52, 0x62, 0x83, 0xff, + 0x52, 0x63, 0x84, 0xff, 0x41, 0x52, 0x73, 0xff, + 0x41, 0x52, 0x73, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x4a, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4f, 0x3e, 0x60, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0x4a, 0x52, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x4a, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x11, 0x33, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x5b, 0x6b, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x62, 0x73, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0x39, 0x31, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x39, 0x49, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x94, 0x41, 0x39, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0xff, + 0x08, 0x10, 0x31, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x29, 0x41, 0xff, 0x08, 0x19, 0x31, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4a, 0x29, 0x39, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xad, 0x5a, 0x52, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x39, 0x39, 0x6c, 0xff, + 0x00, 0x10, 0x39, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x31, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4a, 0x29, 0x39, 0xff, 0x39, 0x18, 0x28, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0b, 0x2d, 0xff, + 0x44, 0x22, 0x44, 0xff, 0x44, 0x22, 0x44, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa5, 0x42, 0x42, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x18, 0x31, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x20, 0x20, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x29, 0x62, 0xff, + 0x29, 0x32, 0x6b, 0xff, 0x18, 0x21, 0x5a, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb5, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd2, 0x39, 0x39, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2d, 0x3e, 0x71, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb5, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd2, 0x39, 0x39, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6b, 0x39, 0x6b, 0xff, + 0x6a, 0x20, 0x41, 0xff, 0x8c, 0x42, 0x63, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc6, 0x08, 0x08, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x3a, 0x42, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x21, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc6, 0x08, 0x08, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x3a, 0x42, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x31, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x3a, 0x42, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x08, 0x31, 0xff, 0x08, 0x08, 0x31, 0xff, + 0x00, 0x00, 0x07, 0xff, 0x08, 0x08, 0x31, 0xff, + 0x29, 0x31, 0x4a, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0x42, 0x63, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xa5, 0x42, 0x52, 0xff, 0xa5, 0x42, 0x52, 0xff, + 0x94, 0x31, 0x42, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x29, 0x39, 0x5a, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6d, 0x4b, 0x6d, 0xff, 0x6d, 0x4b, 0x6d, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0x63, 0x73, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb5, 0x2d, 0x2d, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xd6, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x29, 0x39, 0x5a, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xcc, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xd6, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xef, 0x41, 0x41, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x33, 0x55, 0xff, + 0x66, 0x33, 0x55, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0x42, 0x52, 0xff, 0x8c, 0x42, 0x52, 0xff, + 0x8c, 0x42, 0x52, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xcc, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xdf, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xef, 0x41, 0x41, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3a, 0x29, 0x5b, 0xff, 0x18, 0x07, 0x39, 0xff, + 0x22, 0x11, 0x33, 0xff, 0x22, 0x11, 0x33, 0xff, + 0x43, 0x43, 0x76, 0xff, 0x43, 0x43, 0x76, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x6d, 0x4b, 0x6d, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x94, 0x4a, 0x5a, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xcc, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0x39, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x21, 0x52, 0xff, + 0x41, 0x31, 0x62, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x99, 0x22, 0x33, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x21, 0x21, 0xff, 0xf8, 0x32, 0x32, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0x21, 0x52, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb5, 0x0b, 0x0b, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0xff, + 0xe6, 0x08, 0x08, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x21, 0x21, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5a, 0x18, 0x5a, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc1, 0x17, 0x17, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x62, 0x4a, 0x7b, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc1, 0x17, 0x17, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x10, 0x18, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7b, 0x18, 0x4a, 0xff, + 0x82, 0x1c, 0x4f, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb5, 0x10, 0x10, 0xff, 0xad, 0x08, 0x08, 0xff, + 0xbd, 0x18, 0x18, 0xff, 0xb5, 0x10, 0x10, 0xff, + 0xbe, 0x00, 0x00, 0xff, 0xc6, 0x08, 0x08, 0xff, + 0xd6, 0x00, 0x08, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x10, 0x18, 0xff, 0xef, 0x18, 0x20, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xdf, 0x08, 0x10, 0xff, + 0xe7, 0x10, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x8c, 0x52, 0x7c, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xce, 0x10, 0x10, 0xff, 0xce, 0x10, 0x10, 0xff, + 0xce, 0x10, 0x10, 0xff, 0xce, 0x10, 0x10, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0x08, 0x10, 0xff, 0xde, 0x08, 0x10, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x8c, 0x52, 0x7c, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x11, 0x19, 0xff, + 0xde, 0x08, 0x10, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x21, 0x29, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb5, 0x52, 0x52, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0x29, 0x29, 0xff, 0xe6, 0x31, 0x31, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xce, 0x4a, 0x4a, 0xff, 0xce, 0x4a, 0x4a, 0xff, + 0xce, 0x4a, 0x4a, 0xff, 0xce, 0x4a, 0x4a, 0xff, + 0xd6, 0x42, 0x42, 0xff, 0xd6, 0x42, 0x42, 0xff, + 0xd6, 0x42, 0x42, 0xff, 0xd6, 0x42, 0x42, 0xff, + 0xde, 0x39, 0x39, 0xff, 0xde, 0x39, 0x39, 0xff, + 0xde, 0x39, 0x39, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x31, 0x39, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0x39, 0xff, + 0xde, 0x31, 0x39, 0xff, 0xe6, 0x39, 0x41, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xef, 0x52, 0x5a, 0xff, + 0xef, 0x52, 0x5a, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]) +} + +var img_32x32_rgba_etc2 = { + compressed: new Uint8Array([ + 0x04, 0x1d, 0x6d, 0x26, 0x91, 0x48, 0x84, 0x45, + 0x8d, 0x9d, 0xb6, 0x4a, 0xc4, 0x80, 0x83, 0x97, + 0x0b, 0x12, 0x48, 0x94, 0x88, 0x44, 0x42, 0x25, + 0x64, 0x74, 0x95, 0x4b, 0xae, 0xa2, 0x91, 0x05, + 0x15, 0x11, 0x68, 0x86, 0x84, 0x44, 0x54, 0x26, + 0x74, 0x85, 0xa7, 0x25, 0xfa, 0xa6, 0xff, 0x42, + 0x1b, 0x12, 0x68, 0x66, 0xa7, 0x66, 0xf6, 0x6f, + 0x64, 0x74, 0x85, 0x49, 0xae, 0xea, 0x89, 0xba, + 0x1d, 0x12, 0x66, 0x76, 0xa7, 0x6a, 0x76, 0x86, + 0x64, 0x74, 0x7c, 0x4b, 0xa8, 0x8a, 0xa4, 0x81, + 0x15, 0x11, 0x22, 0xf4, 0x26, 0x44, 0x56, 0x84, + 0x73, 0x73, 0x85, 0x29, 0xab, 0xa3, 0x3e, 0x2a, + 0x0b, 0x1b, 0x22, 0xf2, 0x25, 0x44, 0x44, 0x88, + 0x75, 0x74, 0x86, 0x25, 0xaa, 0x6e, 0x71, 0x11, + 0x04, 0x1d, 0x22, 0xe4, 0x45, 0x48, 0x86, 0x91, + 0xbe, 0x7f, 0x04, 0x62, 0xbb, 0x6c, 0x86, 0xcf, + 0x0b, 0x1b, 0x6d, 0x24, 0x89, 0x44, 0x02, 0x25, + 0x74, 0x74, 0x97, 0x48, 0xec, 0xf0, 0x50, 0xe6, + 0x1a, 0x10, 0x6d, 0x16, 0x88, 0x42, 0x63, 0x37, + 0x21, 0x30, 0x5f, 0x4a, 0xbd, 0xe8, 0x8e, 0x5b, + 0x37, 0x21, 0x68, 0x86, 0x44, 0x42, 0x52, 0x2f, + 0x10, 0x27, 0x3a, 0x46, 0x8c, 0xe2, 0x87, 0x10, + 0x4a, 0x3b, 0x64, 0x54, 0x66, 0x42, 0x74, 0x2f, + 0x1e, 0x18, 0x48, 0x07, 0x6b, 0x31, 0xe9, 0xa9, + 0x4b, 0x3a, 0x42, 0xf4, 0x2f, 0x46, 0x64, 0x66, + 0x05, 0x13, 0x23, 0x57, 0x66, 0xd6, 0x34, 0xc4, + 0x38, 0x22, 0x33, 0x74, 0x2f, 0x46, 0x66, 0x84, + 0x43, 0x4e, 0x5c, 0x2b, 0xbd, 0xee, 0x59, 0xb4, + 0x1f, 0x2b, 0x12, 0xf2, 0x25, 0x44, 0x46, 0x88, + 0x57, 0x44, 0x55, 0x45, 0x44, 0x2b, 0xa9, 0x01, + 0x0b, 0x1b, 0x12, 0xf2, 0x25, 0x44, 0x04, 0x89, + 0x9a, 0x48, 0x41, 0x2e, 0x00, 0x31, 0xf0, 0xc5, + 0x10, 0x19, 0x6d, 0x24, 0x48, 0x22, 0x59, 0x77, + 0x6c, 0x7c, 0x9e, 0x4a, 0xfb, 0xf2, 0xd8, 0x58, + 0x32, 0x22, 0x6d, 0x24, 0x88, 0x22, 0x51, 0x77, + 0x18, 0x20, 0x4a, 0x27, 0x6b, 0x90, 0x0e, 0x35, + 0x59, 0x42, 0x44, 0x02, 0x25, 0x12, 0xe9, 0x77, + 0x00, 0x0b, 0x29, 0x2f, 0xcc, 0x29, 0xf0, 0x87, + 0x8c, 0x32, 0x68, 0x54, 0x66, 0x42, 0xf3, 0x37, + 0x03, 0x10, 0x2f, 0x26, 0x76, 0x48, 0x29, 0x19, + 0x96, 0x4a, 0x42, 0xf4, 0x2e, 0x46, 0x66, 0x45, + 0x33, 0x18, 0x40, 0x26, 0x06, 0x76, 0x2e, 0x3e, + 0x71, 0x31, 0x12, 0xf2, 0x25, 0x44, 0x46, 0x88, + 0xb9, 0x06, 0x32, 0x2b, 0x02, 0x13, 0x10, 0x03, + 0x38, 0x22, 0x9b, 0xf1, 0x2e, 0x44, 0x46, 0x91, + 0x49, 0x15, 0xd0, 0x06, 0xcc, 0xe9, 0x02, 0x33, + 0x15, 0x11, 0x97, 0x70, 0x25, 0x44, 0x06, 0x91, + 0x6a, 0x06, 0x6b, 0x33, 0xf1, 0x05, 0x01, 0xff, + 0x15, 0x17, 0x6d, 0xb4, 0x49, 0x12, 0x4d, 0xff, + 0x74, 0x95, 0xa6, 0x2c, 0x70, 0xf0, 0xbe, 0x5c, + 0x40, 0x24, 0x6d, 0xb4, 0x49, 0x12, 0x4d, 0xbf, + 0x1d, 0x1d, 0x32, 0x4e, 0xfe, 0xf6, 0x4c, 0xe8, + 0x7f, 0x4b, 0x69, 0x22, 0x00, 0x92, 0xdb, 0xbf, + 0x00, 0x01, 0x37, 0x2a, 0x0c, 0x63, 0x0c, 0x6b, + 0xc7, 0x32, 0x68, 0x94, 0x24, 0x13, 0x69, 0xbf, + 0x23, 0x28, 0x43, 0x26, 0x03, 0x11, 0xea, 0xd1, + 0xd9, 0x32, 0x33, 0x73, 0x2e, 0x42, 0x46, 0x89, + 0x63, 0x30, 0x66, 0x46, 0x05, 0x23, 0x5b, 0xa1, + 0x95, 0x4b, 0xbb, 0xf1, 0x2d, 0x24, 0x06, 0x92, + 0xf3, 0x12, 0x93, 0x46, 0x0b, 0x57, 0x06, 0xa8, + 0x4b, 0x3a, 0xdb, 0xf9, 0x2d, 0x20, 0x04, 0x92, + 0x60, 0x86, 0x04, 0xf6, 0x18, 0x46, 0x80, 0x00, + 0x1c, 0x12, 0xdf, 0xf9, 0x2d, 0x44, 0x96, 0xdb, + 0x72, 0xa6, 0x0d, 0x73, 0x8b, 0x2f, 0x64, 0x48, + 0x15, 0x17, 0x6d, 0xb2, 0x52, 0x90, 0x0f, 0xf5, + 0x50, 0x6c, 0x85, 0x6b, 0xec, 0x00, 0xc0, 0x1f, + 0x3d, 0x21, 0x49, 0xb0, 0x09, 0x92, 0x0f, 0xb5, + 0x31, 0x40, 0x63, 0x6c, 0x71, 0xfc, 0x2d, 0x09, + 0x7d, 0x34, 0x49, 0xb0, 0x0a, 0xb2, 0x0f, 0xf4, + 0x07, 0x01, 0x33, 0x6b, 0x6f, 0x73, 0xa1, 0x33, + 0xbb, 0x5a, 0x00, 0xab, 0x01, 0xd6, 0x0f, 0xa8, + 0xeb, 0x35, 0x53, 0x5a, 0x02, 0x7f, 0x31, 0x83, + 0xc7, 0x32, 0xfa, 0x1f, 0xa1, 0xd4, 0x28, 0x13, + 0x7b, 0x55, 0x67, 0x27, 0x84, 0x6f, 0x61, 0x29, + 0x91, 0x4b, 0xfa, 0xcb, 0x20, 0x00, 0xa4, 0x9b, + 0x51, 0x05, 0x68, 0x8b, 0xfe, 0x00, 0xfe, 0x21, + 0x4a, 0x21, 0xff, 0x5b, 0x20, 0x00, 0x94, 0x9b, + 0xe0, 0x01, 0x09, 0x22, 0x0c, 0x1f, 0x70, 0x03, + 0x1b, 0x12, 0xff, 0xeb, 0x60, 0x25, 0x26, 0xdb, + 0x72, 0x9e, 0x0c, 0x7a, 0xa1, 0x2f, 0x43, 0x87, + 0x0d, 0x19, 0x29, 0x20, 0x09, 0xb0, 0x0f, 0xac, + 0x77, 0x6d, 0x8f, 0x4a, 0xff, 0x70, 0x36, 0x3e, + 0x2f, 0x21, 0x29, 0xb0, 0x4a, 0x80, 0x1d, 0x60, + 0x0e, 0x15, 0x43, 0x67, 0x13, 0x33, 0x62, 0xfc, + 0x59, 0x49, 0x05, 0x38, 0x0a, 0xb0, 0x1d, 0x60, + 0xb8, 0x04, 0xb1, 0xb3, 0x31, 0xcf, 0x01, 0x11, + 0x7d, 0x34, 0x81, 0x3d, 0x0b, 0xf4, 0x2f, 0x42, + 0x83, 0x44, 0x64, 0x47, 0x96, 0x18, 0x80, 0x5c, + 0x84, 0x37, 0xf4, 0x3f, 0x0b, 0xd0, 0xba, 0x13, + 0x58, 0x14, 0xc9, 0x1a, 0x01, 0x77, 0x72, 0x08, + 0x63, 0x4b, 0xf6, 0x0d, 0x01, 0x80, 0xa0, 0x53, + 0xd9, 0x0f, 0x08, 0x42, 0xef, 0xef, 0x89, 0x03, + 0x37, 0x22, 0xfa, 0x0b, 0x02, 0x05, 0x34, 0x9b, + 0x74, 0x80, 0x04, 0xf7, 0x14, 0x3f, 0x00, 0x42, + 0x15, 0x11, 0xd6, 0x08, 0x01, 0x05, 0x24, 0x9b, + 0x74, 0x9c, 0x07, 0xf7, 0x9b, 0x2f, 0x43, 0x47, + 0x0a, 0x12, 0x49, 0x22, 0x52, 0x04, 0xa8, 0x01, + 0x98, 0x84, 0xa5, 0x0e, 0xf1, 0xd2, 0x10, 0xec, + 0x14, 0x11, 0x05, 0x38, 0x0a, 0xb0, 0x1f, 0x60, + 0xb8, 0xbc, 0xfa, 0xc2, 0x10, 0x85, 0xc8, 0xd2, + 0x2f, 0x21, 0x05, 0x38, 0x0b, 0xa0, 0xad, 0x01, + 0x51, 0x05, 0x41, 0x2a, 0x01, 0x11, 0x30, 0x6f, + 0x39, 0x3b, 0xb0, 0xad, 0x02, 0xf4, 0x1f, 0x41, + 0xb3, 0x10, 0x10, 0x03, 0x24, 0x57, 0x8b, 0x3a, + 0x3d, 0x21, 0xf0, 0x2f, 0x02, 0xd0, 0x2d, 0x0b, + 0xca, 0x08, 0x10, 0x22, 0x73, 0x33, 0x9f, 0x89, + 0x30, 0x22, 0xf4, 0x1d, 0x02, 0xa0, 0xa8, 0x53, + 0x6c, 0x80, 0x05, 0x72, 0x04, 0x0e, 0xe2, 0x46, + 0x1f, 0x2b, 0xb0, 0x18, 0x0a, 0x05, 0x32, 0x9b, + 0x70, 0x80, 0x04, 0x76, 0x1c, 0x56, 0xe2, 0x03, + 0x0b, 0x12, 0xb0, 0x18, 0x09, 0x05, 0x22, 0x92, + 0x74, 0xa6, 0x0c, 0xfa, 0xa5, 0x37, 0x0a, 0x50, + 0x04, 0x1d, 0x4d, 0xb4, 0x9b, 0x29, 0x30, 0x52, + 0xdf, 0x94, 0x8d, 0x4a, 0x73, 0x31, 0xb9, 0x9c, + 0x0f, 0x11, 0x4d, 0xb2, 0x9b, 0x29, 0x30, 0x53, + 0xd2, 0x53, 0x53, 0x47, 0x77, 0x77, 0x99, 0x88, + 0x0d, 0x19, 0x80, 0xaa, 0x0a, 0xd0, 0x2f, 0x41, + 0x64, 0xae, 0x0d, 0xe6, 0x26, 0x5f, 0xf1, 0xe4, + 0x11, 0x12, 0xd0, 0xaf, 0x42, 0xf4, 0x2f, 0x82, + 0x6a, 0xa0, 0x0c, 0xf2, 0x1e, 0x47, 0x71, 0xe3, + 0x19, 0x10, 0xa1, 0x3a, 0x13, 0xa1, 0x38, 0x53, + 0x72, 0xa2, 0x0c, 0xf3, 0x18, 0x4f, 0x71, 0xa0, + 0x10, 0x19, 0xf0, 0x2d, 0x0a, 0xa0, 0xb8, 0x53, + 0x70, 0x9c, 0x0c, 0x72, 0x1c, 0x47, 0x90, 0xa2, + 0x0b, 0x1b, 0xa0, 0xa8, 0x0a, 0x05, 0x32, 0x93, + 0x6e, 0x9a, 0x0c, 0x72, 0x3c, 0x6f, 0x70, 0x61, + 0x04, 0x1d, 0xa0, 0xa0, 0x52, 0x29, 0x34, 0x9b, + 0x70, 0x54, 0x15, 0x73, 0xa7, 0x3f, 0x72, 0x22, + ]), + decompressed: new Uint8Array([ + 0xa9, 0xb9, 0xd2, 0x00, 0xa9, 0xb9, 0xd2, 0x00, + 0x90, 0xa1, 0xc2, 0x01, 0x7c, 0x8d, 0xae, 0x01, + 0x80, 0x90, 0xb1, 0x03, 0x6c, 0x7c, 0x9d, 0x03, + 0x80, 0x90, 0xb1, 0x03, 0x80, 0x90, 0xb1, 0x06, + 0x7c, 0x8d, 0xaf, 0x08, 0x7c, 0x8d, 0xaf, 0x08, + 0x88, 0x99, 0xbb, 0x0b, 0x66, 0x77, 0x99, 0x0b, + 0x6f, 0x80, 0x91, 0x0e, 0x83, 0x94, 0xa5, 0x0e, + 0x83, 0x94, 0xa5, 0x0e, 0x6f, 0x80, 0x91, 0x0e, + 0x80, 0x90, 0x98, 0x10, 0x6c, 0x7c, 0x84, 0x10, + 0x6c, 0x7c, 0x84, 0x10, 0x6c, 0x7c, 0x84, 0x10, + 0x72, 0x72, 0x83, 0x0e, 0x7c, 0x7c, 0x8d, 0x0b, + 0x72, 0x72, 0x83, 0x0b, 0x88, 0x88, 0x99, 0x08, + 0x88, 0x88, 0x99, 0x06, 0x88, 0x88, 0x99, 0x06, + 0x88, 0x88, 0x99, 0x04, 0x88, 0x88, 0x99, 0x04, + 0x7d, 0x7e, 0x82, 0x02, 0x8f, 0x8d, 0x8f, 0x01, + 0xa0, 0x9d, 0x9c, 0x01, 0xb2, 0xac, 0xa9, 0x00, + 0xa9, 0xb9, 0xd2, 0x00, 0x95, 0xa5, 0xbe, 0x01, + 0x90, 0xa1, 0xc2, 0x01, 0x7c, 0x8d, 0xae, 0x02, + 0x5a, 0x6a, 0x8b, 0x03, 0x5a, 0x6a, 0x8b, 0x03, + 0x5a, 0x6a, 0x8b, 0x06, 0x5a, 0x6a, 0x8b, 0x09, + 0x66, 0x77, 0x99, 0x0b, 0x72, 0x83, 0xa5, 0x0b, + 0x66, 0x77, 0x99, 0x0e, 0x66, 0x77, 0x99, 0x12, + 0x49, 0x5a, 0x6b, 0x13, 0x49, 0x5a, 0x6b, 0x13, + 0x5d, 0x6e, 0x7f, 0x16, 0x5d, 0x6e, 0x7f, 0x16, + 0x5a, 0x6a, 0x72, 0x18, 0x6c, 0x7c, 0x84, 0x15, + 0x6c, 0x7c, 0x84, 0x15, 0x46, 0x56, 0x5e, 0x15, + 0x66, 0x66, 0x77, 0x12, 0x66, 0x66, 0x77, 0x12, + 0x66, 0x66, 0x77, 0x0e, 0x66, 0x66, 0x77, 0x0b, + 0x72, 0x72, 0x83, 0x09, 0x72, 0x72, 0x83, 0x09, + 0x72, 0x72, 0x83, 0x06, 0x66, 0x66, 0x77, 0x04, + 0x82, 0x6c, 0x71, 0x03, 0x94, 0x7b, 0x7e, 0x02, + 0xa5, 0x8b, 0x8b, 0x01, 0xb7, 0x9a, 0x98, 0x01, + 0xa9, 0xb9, 0xd2, 0x01, 0x95, 0xa5, 0xbe, 0x01, + 0x6a, 0x7b, 0x9c, 0x02, 0x6a, 0x7b, 0x9c, 0x03, + 0x5f, 0x6f, 0x98, 0x06, 0x4b, 0x5b, 0x84, 0x06, + 0x39, 0x49, 0x72, 0x09, 0x4b, 0x5b, 0x84, 0x0c, + 0x3f, 0x50, 0x72, 0x0e, 0x55, 0x66, 0x88, 0x12, + 0x55, 0x66, 0x88, 0x12, 0x33, 0x44, 0x66, 0x17, + 0x4d, 0x4d, 0x5e, 0x19, 0x3b, 0x3b, 0x4c, 0x1c, + 0x3b, 0x3b, 0x4c, 0x1f, 0x4d, 0x4d, 0x5e, 0x1f, + 0x4b, 0x5b, 0x63, 0x1e, 0x4b, 0x5b, 0x63, 0x1e, + 0x5f, 0x6f, 0x77, 0x1e, 0x4b, 0x5b, 0x63, 0x1b, + 0x3c, 0x3c, 0x5e, 0x1b, 0x3c, 0x3c, 0x5e, 0x17, + 0x50, 0x50, 0x72, 0x12, 0x3c, 0x3c, 0x5e, 0x12, + 0x50, 0x3f, 0x61, 0x0f, 0x50, 0x3f, 0x61, 0x0c, + 0x5a, 0x49, 0x6b, 0x09, 0x66, 0x55, 0x77, 0x06, + 0x88, 0x5a, 0x5f, 0x05, 0x99, 0x69, 0x6c, 0x03, + 0xab, 0x79, 0x79, 0x02, 0xbc, 0x88, 0x86, 0x01, + 0x95, 0xa5, 0xbe, 0x01, 0x6f, 0x7f, 0x98, 0x02, + 0x7c, 0x8d, 0xae, 0x03, 0x56, 0x67, 0x88, 0x05, + 0x4b, 0x5b, 0x84, 0x06, 0x39, 0x49, 0x72, 0x09, + 0x39, 0x49, 0x72, 0x0c, 0x25, 0x35, 0x5e, 0x0f, + 0x49, 0x5a, 0x7c, 0x12, 0x3f, 0x50, 0x72, 0x17, + 0x33, 0x44, 0x66, 0x1b, 0x33, 0x44, 0x66, 0x1e, + 0x27, 0x27, 0x38, 0x22, 0x27, 0x27, 0x38, 0x27, + 0x27, 0x27, 0x38, 0x27, 0x27, 0x27, 0x38, 0x27, + 0x39, 0x49, 0x51, 0x29, 0x25, 0x35, 0x3d, 0x29, + 0x39, 0x49, 0x51, 0x29, 0x25, 0x35, 0x3d, 0x24, + 0x50, 0x50, 0x72, 0x21, 0x2a, 0x2a, 0x4c, 0x1e, + 0x16, 0x16, 0x38, 0x1b, 0x2a, 0x2a, 0x4c, 0x17, + 0x50, 0x3f, 0x61, 0x14, 0x5a, 0x49, 0x6b, 0x0f, + 0x50, 0x3f, 0x61, 0x0c, 0x50, 0x3f, 0x61, 0x09, + 0x8d, 0x48, 0x4e, 0x06, 0x9e, 0x57, 0x5b, 0x05, + 0xb0, 0x67, 0x68, 0x03, 0xc1, 0x76, 0x75, 0x02, + 0x80, 0x80, 0xa2, 0x01, 0x6e, 0x6e, 0x90, 0x04, + 0x4d, 0x4d, 0x80, 0x04, 0x61, 0x61, 0x94, 0x06, + 0x3e, 0x4e, 0x77, 0x0b, 0x3e, 0x4e, 0x77, 0x0b, + 0x20, 0x28, 0x49, 0x11, 0x20, 0x28, 0x49, 0x14, + 0x19, 0x2a, 0x42, 0x1d, 0x2d, 0x3e, 0x56, 0x1d, + 0x21, 0x29, 0x5b, 0x23, 0x15, 0x1d, 0x4f, 0x29, + 0x10, 0x10, 0x42, 0x2c, 0x16, 0x16, 0x48, 0x35, + 0x10, 0x10, 0x42, 0x35, 0x1a, 0x1a, 0x4c, 0x35, + 0x11, 0x11, 0x33, 0x33, 0x22, 0x33, 0x55, 0x33, + 0x11, 0x11, 0x33, 0x33, 0x32, 0x43, 0x65, 0x33, + 0x47, 0x4f, 0x5f, 0x2e, 0x53, 0x5b, 0x6b, 0x28, + 0x31, 0x39, 0x49, 0x28, 0x31, 0x39, 0x49, 0x1e, + 0x38, 0x27, 0x38, 0x1b, 0x5e, 0x4d, 0x5e, 0x15, + 0x72, 0x61, 0x72, 0x11, 0x5e, 0x4d, 0x5e, 0x0b, + 0x8b, 0x39, 0x31, 0x09, 0x97, 0x45, 0x3d, 0x06, + 0xba, 0x57, 0x57, 0x04, 0xd7, 0x74, 0x74, 0x04, + 0x94, 0x94, 0xb6, 0x01, 0x5a, 0x5a, 0x7c, 0x04, + 0x4d, 0x4d, 0x80, 0x06, 0x3b, 0x3b, 0x6e, 0x09, + 0x3e, 0x4e, 0x77, 0x0b, 0x18, 0x28, 0x51, 0x11, + 0x46, 0x4e, 0x6f, 0x17, 0x20, 0x28, 0x49, 0x1c, + 0x07, 0x18, 0x30, 0x23, 0x07, 0x18, 0x30, 0x29, + 0x21, 0x29, 0x5b, 0x31, 0x15, 0x1d, 0x4f, 0x31, + 0x1a, 0x1a, 0x4c, 0x3b, 0x10, 0x10, 0x42, 0x3b, + 0x16, 0x16, 0x48, 0x44, 0x10, 0x10, 0x42, 0x44, + 0x22, 0x33, 0x55, 0x45, 0x11, 0x11, 0x33, 0x45, + 0x22, 0x33, 0x55, 0x3f, 0x12, 0x23, 0x45, 0x3f, + 0x3d, 0x45, 0x55, 0x3a, 0x31, 0x39, 0x49, 0x34, + 0x47, 0x4f, 0x5f, 0x2e, 0x3d, 0x45, 0x55, 0x28, + 0x4c, 0x3b, 0x4c, 0x21, 0x4c, 0x3b, 0x4c, 0x1b, + 0x5e, 0x4d, 0x5e, 0x15, 0x72, 0x61, 0x72, 0x11, + 0xa1, 0x4f, 0x47, 0x0c, 0x97, 0x45, 0x3d, 0x09, + 0xba, 0x57, 0x57, 0x06, 0xd7, 0x74, 0x74, 0x04, + 0x94, 0x94, 0xb6, 0x04, 0x5a, 0x5a, 0x7c, 0x06, + 0x3b, 0x3b, 0x6e, 0x09, 0x27, 0x27, 0x5a, 0x0c, + 0x2a, 0x3a, 0x63, 0x11, 0x04, 0x14, 0x3d, 0x14, + 0x0c, 0x14, 0x35, 0x1c, 0x32, 0x3a, 0x5b, 0x22, + 0x19, 0x2a, 0x42, 0x29, 0x07, 0x18, 0x30, 0x31, + 0x00, 0x07, 0x39, 0x3b, 0x15, 0x1d, 0x4f, 0x43, + 0x0d, 0x1d, 0x4f, 0x44, 0x0d, 0x1d, 0x4f, 0x4d, + 0x0d, 0x1d, 0x4f, 0x4d, 0x00, 0x07, 0x39, 0x56, + 0x12, 0x23, 0x45, 0x54, 0x12, 0x23, 0x45, 0x54, + 0x12, 0x23, 0x45, 0x4e, 0x22, 0x33, 0x55, 0x4e, + 0x3d, 0x1c, 0x1c, 0x46, 0x51, 0x30, 0x30, 0x40, + 0x51, 0x30, 0x30, 0x3a, 0x77, 0x56, 0x56, 0x34, + 0x7c, 0x49, 0x5a, 0x27, 0x7c, 0x49, 0x5a, 0x21, + 0x72, 0x3f, 0x50, 0x1b, 0x72, 0x3f, 0x50, 0x15, + 0xad, 0x5b, 0x53, 0x0f, 0xad, 0x5b, 0x53, 0x0c, + 0xba, 0x57, 0x57, 0x09, 0xd7, 0x74, 0x74, 0x06, + 0x80, 0x80, 0xa2, 0x04, 0x5a, 0x5a, 0x7c, 0x06, + 0x3b, 0x3b, 0x6e, 0x09, 0x3b, 0x3b, 0x6e, 0x0f, + 0x04, 0x14, 0x3d, 0x14, 0x18, 0x28, 0x51, 0x17, + 0x0c, 0x14, 0x35, 0x22, 0x0c, 0x14, 0x35, 0x28, + 0x19, 0x2a, 0x42, 0x31, 0x07, 0x18, 0x30, 0x3b, + 0x0b, 0x13, 0x45, 0x43, 0x00, 0x07, 0x39, 0x4f, + 0x19, 0x29, 0x5b, 0x56, 0x19, 0x29, 0x5b, 0x5c, + 0x00, 0x07, 0x39, 0x65, 0x19, 0x29, 0x5b, 0x65, + 0x11, 0x11, 0x33, 0x66, 0x12, 0x23, 0x45, 0x66, + 0x11, 0x11, 0x33, 0x60, 0x11, 0x11, 0x33, 0x60, + 0x51, 0x30, 0x30, 0x50, 0x3d, 0x1c, 0x1c, 0x50, + 0x3d, 0x1c, 0x1c, 0x46, 0x51, 0x30, 0x30, 0x3a, + 0x72, 0x3f, 0x50, 0x31, 0x7c, 0x49, 0x5a, 0x27, + 0x88, 0x55, 0x66, 0x21, 0x88, 0x55, 0x66, 0x1b, + 0xa1, 0x4f, 0x47, 0x14, 0xad, 0x5b, 0x53, 0x0f, + 0xba, 0x57, 0x57, 0x09, 0xd7, 0x74, 0x74, 0x06, + 0x74, 0x84, 0xa5, 0x06, 0x4e, 0x5e, 0x7f, 0x08, + 0x41, 0x51, 0x83, 0x0b, 0x2d, 0x3d, 0x6f, 0x11, + 0x29, 0x32, 0x5b, 0x18, 0x07, 0x10, 0x39, 0x22, + 0x13, 0x1c, 0x45, 0x28, 0x1d, 0x26, 0x4f, 0x2e, + 0x00, 0x00, 0x18, 0x39, 0x05, 0x0d, 0x2e, 0x45, + 0x05, 0x0d, 0x2e, 0x51, 0x11, 0x19, 0x3a, 0x5d, + 0x11, 0x21, 0x3a, 0x65, 0x11, 0x21, 0x3a, 0x74, + 0x29, 0x21, 0x32, 0x74, 0x13, 0x0b, 0x1c, 0x7d, + 0x36, 0x1d, 0x47, 0x76, 0x20, 0x07, 0x31, 0x76, + 0x4f, 0x1d, 0x47, 0x76, 0x4f, 0x1d, 0x47, 0x6e, + 0x56, 0x34, 0x45, 0x68, 0x76, 0x54, 0x65, 0x5c, + 0x87, 0x32, 0x54, 0x53, 0x67, 0x12, 0x34, 0x4a, + 0x93, 0x00, 0x00, 0x3a, 0x82, 0x1c, 0x1c, 0x34, + 0xb0, 0x4a, 0x4a, 0x28, 0xb0, 0x4a, 0x4a, 0x1e, + 0xd2, 0x5b, 0x5b, 0x17, 0xd2, 0x39, 0x39, 0x12, + 0xd2, 0x5b, 0x5b, 0x0b, 0xe8, 0x71, 0x71, 0x08, + 0x62, 0x72, 0x93, 0x06, 0x62, 0x72, 0x93, 0x0b, + 0x41, 0x51, 0x83, 0x0e, 0x41, 0x51, 0x83, 0x14, + 0x1d, 0x26, 0x4f, 0x18, 0x29, 0x32, 0x5b, 0x22, + 0x07, 0x10, 0x39, 0x2e, 0x13, 0x1c, 0x45, 0x3a, + 0x11, 0x19, 0x3a, 0x45, 0x00, 0x03, 0x24, 0x51, + 0x05, 0x0d, 0x2e, 0x5d, 0x11, 0x19, 0x3a, 0x69, + 0x05, 0x15, 0x2e, 0x74, 0x05, 0x15, 0x2e, 0x7d, + 0x13, 0x0b, 0x1c, 0x86, 0x07, 0x00, 0x10, 0x8f, + 0x20, 0x07, 0x31, 0x8e, 0x20, 0x07, 0x31, 0x8e, + 0x39, 0x07, 0x31, 0x86, 0x5b, 0x29, 0x53, 0x86, + 0x56, 0x34, 0x45, 0x77, 0x87, 0x32, 0x54, 0x68, + 0x76, 0x54, 0x65, 0x5c, 0x87, 0x32, 0x54, 0x53, + 0x82, 0x1c, 0x1c, 0x46, 0x93, 0x00, 0x00, 0x3a, + 0x82, 0x1c, 0x1c, 0x2e, 0xb0, 0x4a, 0x4a, 0x28, + 0xd2, 0x39, 0x39, 0x1b, 0xd2, 0x39, 0x39, 0x12, + 0xe8, 0x4f, 0x4f, 0x0e, 0xe8, 0x71, 0x71, 0x0b, + 0x74, 0x84, 0xa5, 0x08, 0x4e, 0x5e, 0x7f, 0x0b, + 0x53, 0x63, 0x95, 0x11, 0x2d, 0x3d, 0x6f, 0x17, + 0x29, 0x32, 0x6b, 0x22, 0x1d, 0x26, 0x5f, 0x28, + 0x29, 0x32, 0x6b, 0x34, 0x13, 0x1c, 0x55, 0x40, + 0x2a, 0x4b, 0x5b, 0x51, 0x0d, 0x2e, 0x3e, 0x5d, + 0x00, 0x14, 0x24, 0x69, 0x00, 0x00, 0x07, 0x75, + 0x05, 0x15, 0x2e, 0x86, 0x00, 0x0b, 0x24, 0x8f, + 0x13, 0x0b, 0x1c, 0x98, 0x13, 0x0b, 0x1c, 0xa1, + 0x20, 0x07, 0x31, 0xa2, 0x2c, 0x13, 0x3d, 0xa2, + 0x39, 0x07, 0x31, 0x9a, 0x4f, 0x1d, 0x47, 0x8e, + 0x87, 0x32, 0x54, 0x83, 0x87, 0x32, 0x54, 0x77, + 0x87, 0x32, 0x54, 0x68, 0x87, 0x32, 0x54, 0x5c, + 0xb0, 0x4a, 0x4a, 0x50, 0xc1, 0x17, 0x17, 0x40, + 0xc1, 0x17, 0x17, 0x34, 0xc1, 0x17, 0x17, 0x28, + 0xd2, 0x5b, 0x5b, 0x1e, 0xd2, 0x39, 0x39, 0x17, + 0xe8, 0x4f, 0x4f, 0x12, 0xe8, 0x71, 0x71, 0x0b, + 0x88, 0x98, 0xb9, 0x08, 0x62, 0x72, 0x93, 0x0e, + 0x2d, 0x3d, 0x6f, 0x14, 0x2d, 0x3d, 0x6f, 0x19, + 0x1d, 0x26, 0x5f, 0x22, 0x13, 0x1c, 0x55, 0x2e, + 0x07, 0x10, 0x49, 0x3a, 0x1d, 0x26, 0x5f, 0x4a, + 0x00, 0x14, 0x24, 0x51, 0x2a, 0x4b, 0x5b, 0x69, + 0x00, 0x14, 0x24, 0x75, 0x00, 0x00, 0x07, 0x89, + 0x00, 0x00, 0x18, 0x98, 0x05, 0x15, 0x2e, 0xa1, + 0x29, 0x21, 0x32, 0xb0, 0x1d, 0x15, 0x26, 0xb0, + 0x42, 0x29, 0x53, 0xba, 0x36, 0x1d, 0x47, 0xb2, + 0x5b, 0x29, 0x53, 0xb2, 0x4f, 0x1d, 0x47, 0xa2, + 0x87, 0x32, 0x54, 0x95, 0x87, 0x32, 0x54, 0x83, + 0x87, 0x32, 0x54, 0x77, 0x87, 0x32, 0x54, 0x68, + 0xc1, 0x17, 0x17, 0x50, 0xc1, 0x17, 0x17, 0x46, + 0xc1, 0x17, 0x17, 0x3a, 0xc1, 0x17, 0x17, 0x2e, + 0xd2, 0x39, 0x39, 0x21, 0xd2, 0x39, 0x39, 0x1b, + 0xe8, 0x4f, 0x4f, 0x12, 0xe8, 0x71, 0x71, 0x0e, + 0x7c, 0x9e, 0xaf, 0x0a, 0x66, 0x88, 0x99, 0x0d, + 0x51, 0x62, 0x73, 0x12, 0x1a, 0x2b, 0x3c, 0x1c, + 0x21, 0x21, 0x3a, 0x28, 0x0f, 0x0f, 0x28, 0x30, + 0x0d, 0x0d, 0x4f, 0x3a, 0x00, 0x00, 0x35, 0x4e, + 0x00, 0x00, 0x20, 0x57, 0x05, 0x05, 0x36, 0x6b, + 0x09, 0x11, 0x32, 0x83, 0x09, 0x11, 0x32, 0x8f, + 0x10, 0x18, 0x31, 0xa0, 0x10, 0x18, 0x31, 0xaf, + 0x34, 0x24, 0x55, 0xc1, 0x3e, 0x2e, 0x5f, 0xca, + 0x46, 0x14, 0x46, 0xca, 0x6c, 0x3a, 0x6c, 0xca, + 0x6a, 0x20, 0x41, 0xc1, 0x8c, 0x42, 0x63, 0xb2, + 0x99, 0x33, 0x44, 0xa5, 0x99, 0x33, 0x44, 0x8d, + 0x99, 0x33, 0x44, 0x81, 0xbb, 0x11, 0x22, 0x6d, + 0xc3, 0x06, 0x04, 0x60, 0xcd, 0x0b, 0x0b, 0x4e, + 0xd7, 0x0f, 0x12, 0x3f, 0xe1, 0x14, 0x19, 0x33, + 0xe7, 0x26, 0x28, 0x23, 0xe7, 0x3f, 0x44, 0x1d, + 0xe7, 0x59, 0x5f, 0x14, 0xe7, 0x72, 0x7b, 0x0f, + 0x7c, 0x9e, 0xaf, 0x0a, 0x72, 0x94, 0xa5, 0x10, + 0x6e, 0x7f, 0x90, 0x17, 0x1a, 0x2b, 0x3c, 0x1f, + 0x0f, 0x0f, 0x28, 0x28, 0x00, 0x00, 0x14, 0x34, + 0x00, 0x00, 0x35, 0x44, 0x00, 0x00, 0x35, 0x4e, + 0x00, 0x00, 0x20, 0x63, 0x00, 0x00, 0x20, 0x77, + 0x09, 0x11, 0x32, 0x83, 0x09, 0x11, 0x32, 0x97, + 0x26, 0x2e, 0x47, 0xaf, 0x26, 0x2e, 0x47, 0xc1, + 0x28, 0x18, 0x49, 0xca, 0x4a, 0x3a, 0x6b, 0xdc, + 0x5a, 0x28, 0x5a, 0xdc, 0x46, 0x14, 0x46, 0xdc, + 0x8c, 0x42, 0x63, 0xd3, 0x80, 0x36, 0x57, 0xc1, + 0x99, 0x33, 0x44, 0xad, 0xa4, 0x3e, 0x4f, 0x99, + 0x8e, 0x28, 0x39, 0x81, 0xbb, 0x11, 0x22, 0x79, + 0xc7, 0x05, 0x03, 0x60, 0xd1, 0x09, 0x0a, 0x4e, + 0xdb, 0x0e, 0x11, 0x45, 0xe5, 0x12, 0x18, 0x33, + 0xe9, 0x25, 0x26, 0x28, 0xe9, 0x3e, 0x42, 0x1d, + 0xe9, 0x58, 0x5d, 0x17, 0xe9, 0x71, 0x79, 0x0f, + 0x88, 0xaa, 0xbb, 0x0a, 0x66, 0x88, 0x99, 0x10, + 0x6e, 0x7f, 0x90, 0x17, 0x37, 0x48, 0x59, 0x1f, + 0x0f, 0x0f, 0x28, 0x28, 0x00, 0x00, 0x14, 0x34, + 0x00, 0x00, 0x18, 0x44, 0x00, 0x00, 0x18, 0x56, + 0x05, 0x05, 0x36, 0x63, 0x00, 0x00, 0x20, 0x77, + 0x00, 0x00, 0x0c, 0x8f, 0x09, 0x11, 0x32, 0xa3, + 0x26, 0x2e, 0x47, 0xb8, 0x32, 0x3a, 0x53, 0xca, + 0x3e, 0x2e, 0x5f, 0xdc, 0x4a, 0x3a, 0x6b, 0xeb, + 0x6c, 0x3a, 0x6c, 0xee, 0x6c, 0x3a, 0x6c, 0xe5, + 0x76, 0x2c, 0x4d, 0xdc, 0x8c, 0x42, 0x63, 0xca, + 0x99, 0x33, 0x44, 0xb9, 0x99, 0x33, 0x44, 0xa5, + 0xa4, 0x3e, 0x4f, 0x8d, 0xbb, 0x11, 0x22, 0x79, + 0xcb, 0x03, 0x02, 0x66, 0xd5, 0x08, 0x09, 0x54, + 0xdf, 0x0c, 0x10, 0x45, 0xe9, 0x11, 0x17, 0x33, + 0xeb, 0x24, 0x24, 0x28, 0xeb, 0x3d, 0x40, 0x20, + 0xeb, 0x57, 0x5b, 0x17, 0xeb, 0x70, 0x77, 0x0f, + 0x88, 0xaa, 0xbb, 0x0a, 0x72, 0x94, 0xa5, 0x10, + 0x6e, 0x7f, 0x90, 0x17, 0x6e, 0x7f, 0x90, 0x1f, + 0x35, 0x35, 0x4e, 0x28, 0x00, 0x00, 0x14, 0x34, + 0x00, 0x00, 0x18, 0x44, 0x00, 0x00, 0x35, 0x56, + 0x11, 0x11, 0x42, 0x63, 0x05, 0x05, 0x36, 0x77, + 0x00, 0x00, 0x0c, 0x8f, 0x09, 0x11, 0x32, 0xa3, + 0x26, 0x2e, 0x47, 0xb8, 0x32, 0x3a, 0x53, 0xca, + 0x4a, 0x3a, 0x6b, 0xdc, 0x4a, 0x3a, 0x6b, 0xeb, + 0x6c, 0x3a, 0x6c, 0xfd, 0x80, 0x4e, 0x80, 0xee, + 0x8c, 0x42, 0x63, 0xdc, 0x80, 0x36, 0x57, 0xca, + 0xa4, 0x3e, 0x4f, 0xb9, 0xa4, 0x3e, 0x4f, 0xa5, + 0x99, 0x33, 0x44, 0x8d, 0xbb, 0x11, 0x22, 0x79, + 0xcf, 0x02, 0x01, 0x66, 0xd9, 0x06, 0x08, 0x54, + 0xe3, 0x0b, 0x0f, 0x45, 0xed, 0x0f, 0x16, 0x33, + 0xed, 0x23, 0x22, 0x28, 0xed, 0x3c, 0x3e, 0x20, + 0xed, 0x56, 0x59, 0x17, 0xed, 0x6f, 0x75, 0x0f, + 0x7c, 0x95, 0xae, 0x0a, 0x7c, 0x95, 0xae, 0x10, + 0x5f, 0x78, 0x91, 0x17, 0x5f, 0x78, 0x91, 0x1f, + 0x5d, 0x6e, 0x90, 0x29, 0x26, 0x37, 0x59, 0x37, + 0x00, 0x00, 0x09, 0x41, 0x04, 0x00, 0x26, 0x55, + 0x13, 0x13, 0x46, 0x65, 0x13, 0x13, 0x46, 0x74, + 0x13, 0x13, 0x46, 0x8c, 0x33, 0x00, 0x11, 0x9e, + 0x3e, 0x1c, 0x3e, 0xb1, 0x55, 0x33, 0x55, 0xca, + 0x6c, 0x4a, 0x6c, 0xde, 0x6c, 0x4a, 0x6c, 0xe8, + 0x6a, 0x41, 0x52, 0xeb, 0x80, 0x57, 0x68, 0xeb, + 0x8c, 0x63, 0x74, 0xdc, 0x80, 0x57, 0x68, 0xca, + 0x9f, 0x17, 0x17, 0xb5, 0xb5, 0x2d, 0x2d, 0xa1, + 0xb5, 0x2d, 0x2d, 0x89, 0xd2, 0x06, 0x06, 0x75, + 0xd6, 0x00, 0x00, 0x62, 0xe2, 0x00, 0x03, 0x56, + 0xe9, 0x0a, 0x12, 0x44, 0xef, 0x10, 0x18, 0x36, + 0xe7, 0x1e, 0x20, 0x27, 0xea, 0x3f, 0x3e, 0x1f, + 0xed, 0x60, 0x5b, 0x16, 0xf0, 0x80, 0x79, 0x0e, + 0x7c, 0x95, 0xae, 0x0a, 0x5f, 0x78, 0x91, 0x10, + 0x5f, 0x78, 0x91, 0x17, 0x45, 0x5e, 0x77, 0x1f, + 0x40, 0x51, 0x73, 0x29, 0x26, 0x37, 0x59, 0x37, + 0x1e, 0x0d, 0x40, 0x41, 0x00, 0x00, 0x09, 0x4f, + 0x13, 0x13, 0x46, 0x65, 0x13, 0x13, 0x46, 0x74, + 0x33, 0x33, 0x66, 0x83, 0x13, 0x13, 0x46, 0x9e, + 0x3e, 0x1c, 0x3e, 0xb1, 0x55, 0x33, 0x55, 0xc0, + 0x55, 0x33, 0x55, 0xca, 0x6c, 0x4a, 0x6c, 0xde, + 0x76, 0x4d, 0x5e, 0xdc, 0x6a, 0x41, 0x52, 0xdc, + 0x80, 0x57, 0x68, 0xd3, 0x8c, 0x63, 0x74, 0xc1, + 0xb5, 0x2d, 0x2d, 0xa9, 0x9f, 0x17, 0x17, 0x95, + 0xd2, 0x06, 0x06, 0x89, 0xd2, 0x06, 0x06, 0x75, + 0xd6, 0x00, 0x00, 0x62, 0xec, 0x05, 0x0d, 0x4e, + 0xe9, 0x0a, 0x12, 0x44, 0xef, 0x10, 0x18, 0x36, + 0xe8, 0x1e, 0x1f, 0x27, 0xeb, 0x3e, 0x3d, 0x1f, + 0xee, 0x5f, 0x5a, 0x16, 0xf1, 0x80, 0x78, 0x0e, + 0x6f, 0x67, 0x88, 0x0a, 0x5b, 0x53, 0x74, 0x0d, + 0x49, 0x41, 0x62, 0x12, 0x35, 0x2d, 0x4e, 0x1c, + 0x26, 0x37, 0x59, 0x23, 0x26, 0x37, 0x59, 0x2f, + 0x3b, 0x2a, 0x5d, 0x41, 0x04, 0x00, 0x26, 0x4f, + 0x33, 0x00, 0x11, 0x59, 0x33, 0x33, 0x66, 0x6b, + 0x33, 0x33, 0x66, 0x83, 0x33, 0x33, 0x66, 0x92, + 0x55, 0x33, 0x55, 0xa7, 0x55, 0x33, 0x55, 0xb1, + 0x77, 0x33, 0x55, 0xc0, 0x77, 0x33, 0x55, 0xca, + 0x8f, 0x34, 0x55, 0xca, 0x8f, 0x34, 0x55, 0xca, + 0x8f, 0x34, 0x55, 0xc1, 0xa5, 0x4a, 0x6b, 0xaf, + 0xb5, 0x2d, 0x2d, 0xa1, 0xb5, 0x2d, 0x2d, 0x95, + 0xd2, 0x06, 0x06, 0x7d, 0xd2, 0x06, 0x06, 0x69, + 0xe2, 0x00, 0x03, 0x5c, 0xec, 0x05, 0x0d, 0x4e, + 0xe5, 0x06, 0x0e, 0x3c, 0xef, 0x10, 0x18, 0x30, + 0xe9, 0x1d, 0x1e, 0x27, 0xec, 0x3e, 0x3c, 0x1c, + 0xef, 0x5f, 0x59, 0x13, 0xf2, 0x7f, 0x77, 0x0e, + 0x6f, 0x67, 0x88, 0x0a, 0x5b, 0x53, 0x74, 0x0d, + 0x49, 0x41, 0x62, 0x12, 0x35, 0x2d, 0x4e, 0x19, + 0x09, 0x1a, 0x3c, 0x23, 0x26, 0x37, 0x59, 0x2f, + 0x3b, 0x2a, 0x5d, 0x37, 0x1e, 0x0d, 0x40, 0x49, + 0x33, 0x00, 0x11, 0x59, 0x33, 0x00, 0x11, 0x65, + 0x33, 0x33, 0x66, 0x74, 0x53, 0x53, 0x86, 0x83, + 0x55, 0x33, 0x55, 0x93, 0x6c, 0x4a, 0x6c, 0xa7, + 0x77, 0x33, 0x55, 0xb1, 0x77, 0x33, 0x55, 0xb1, + 0x83, 0x28, 0x49, 0xb8, 0x99, 0x3e, 0x5f, 0xb8, + 0x99, 0x3e, 0x5f, 0xaf, 0x8f, 0x34, 0x55, 0xa0, + 0xb5, 0x2d, 0x2d, 0x95, 0xb5, 0x2d, 0x2d, 0x89, + 0xd2, 0x06, 0x06, 0x75, 0xd2, 0x06, 0x06, 0x69, + 0xe2, 0x00, 0x03, 0x56, 0xec, 0x05, 0x0d, 0x44, + 0xe5, 0x06, 0x0e, 0x3c, 0xe9, 0x0a, 0x12, 0x30, + 0xea, 0x1d, 0x1d, 0x22, 0xed, 0x3d, 0x3b, 0x19, + 0xf0, 0x5e, 0x58, 0x13, 0xf3, 0x7f, 0x76, 0x0e, + 0x7c, 0x74, 0x95, 0x08, 0x56, 0x4e, 0x6f, 0x0b, + 0x62, 0x49, 0x7b, 0x11, 0x4e, 0x35, 0x67, 0x16, + 0x44, 0x33, 0x66, 0x21, 0x34, 0x23, 0x56, 0x29, + 0x44, 0x33, 0x66, 0x33, 0x44, 0x33, 0x66, 0x41, + 0x56, 0x23, 0x56, 0x51, 0x67, 0x00, 0x01, 0x5d, + 0x56, 0x23, 0x56, 0x69, 0x76, 0x43, 0x76, 0x75, + 0x8d, 0x4b, 0x6c, 0x83, 0x67, 0x25, 0x46, 0x92, + 0x8d, 0x4b, 0x6c, 0x9e, 0x7b, 0x39, 0x5a, 0x9e, + 0x9f, 0x28, 0x39, 0xa2, 0x9f, 0x28, 0x39, 0xa2, + 0x9f, 0x28, 0x39, 0x99, 0xb5, 0x0b, 0x0b, 0x90, + 0xc1, 0x00, 0x00, 0x87, 0xe7, 0x11, 0x11, 0x7b, + 0xdf, 0x00, 0x00, 0x67, 0xe9, 0x02, 0x0a, 0x5b, + 0xeb, 0x00, 0x04, 0x4f, 0xec, 0x05, 0x0a, 0x3f, + 0xed, 0x0a, 0x10, 0x33, 0xee, 0x0f, 0x16, 0x27, + 0xeb, 0x1c, 0x1c, 0x1e, 0xec, 0x3c, 0x3b, 0x17, + 0xed, 0x5c, 0x59, 0x12, 0xee, 0x7b, 0x78, 0x0b, + 0x90, 0x88, 0xa9, 0x05, 0x56, 0x4e, 0x6f, 0x0b, + 0x4e, 0x35, 0x67, 0x0e, 0x4e, 0x35, 0x67, 0x14, + 0x44, 0x33, 0x66, 0x1b, 0x34, 0x23, 0x56, 0x21, + 0x34, 0x23, 0x56, 0x29, 0x54, 0x43, 0x76, 0x3b, + 0x76, 0x43, 0x76, 0x45, 0x87, 0x10, 0x21, 0x51, + 0x87, 0x10, 0x21, 0x5d, 0x76, 0x43, 0x76, 0x69, + 0x8d, 0x4b, 0x6c, 0x74, 0x8d, 0x4b, 0x6c, 0x83, + 0x7b, 0x39, 0x5a, 0x8c, 0x8d, 0x4b, 0x6c, 0x8c, + 0x9f, 0x28, 0x39, 0x90, 0x9f, 0x28, 0x39, 0x8a, + 0xb5, 0x0b, 0x0b, 0x8a, 0xb5, 0x0b, 0x0b, 0x7b, + 0xc1, 0x00, 0x00, 0x73, 0xd5, 0x00, 0x00, 0x67, + 0xe5, 0x00, 0x06, 0x5b, 0xe5, 0x00, 0x06, 0x4f, + 0xe9, 0x01, 0x05, 0x45, 0xea, 0x06, 0x0b, 0x39, + 0xeb, 0x0b, 0x11, 0x2d, 0xec, 0x10, 0x17, 0x27, + 0xeb, 0x1c, 0x1c, 0x1b, 0xec, 0x3b, 0x3b, 0x12, + 0xed, 0x5b, 0x59, 0x0e, 0xee, 0x7b, 0x78, 0x0b, + 0x90, 0x88, 0xa9, 0x05, 0x6a, 0x62, 0x83, 0x08, + 0x4e, 0x35, 0x67, 0x0b, 0x62, 0x49, 0x7b, 0x11, + 0x54, 0x43, 0x76, 0x15, 0x54, 0x43, 0x76, 0x21, + 0x66, 0x11, 0x55, 0x29, 0x54, 0x43, 0x76, 0x33, + 0x76, 0x43, 0x76, 0x39, 0x76, 0x43, 0x76, 0x45, + 0x87, 0x10, 0x21, 0x51, 0x87, 0x10, 0x21, 0x5d, + 0xad, 0x32, 0x53, 0x65, 0xad, 0x32, 0x53, 0x6b, + 0x97, 0x1c, 0x3d, 0x74, 0xa1, 0x26, 0x47, 0x74, + 0x9f, 0x28, 0x39, 0x7b, 0x9f, 0x28, 0x39, 0x75, + 0xc1, 0x17, 0x17, 0x75, 0xb5, 0x0b, 0x0b, 0x6c, + 0xd5, 0x00, 0x00, 0x67, 0xd5, 0x00, 0x00, 0x5b, + 0xe5, 0x00, 0x06, 0x4f, 0xe5, 0x00, 0x06, 0x47, + 0xe7, 0x01, 0x06, 0x39, 0xe8, 0x06, 0x0c, 0x33, + 0xe9, 0x0b, 0x12, 0x27, 0xea, 0x10, 0x18, 0x1d, + 0xeb, 0x1b, 0x1c, 0x17, 0xec, 0x3b, 0x3b, 0x12, + 0xed, 0x5b, 0x59, 0x0b, 0xee, 0x7a, 0x78, 0x08, + 0x90, 0x88, 0xa9, 0x05, 0x7c, 0x74, 0x95, 0x08, + 0x62, 0x49, 0x7b, 0x0b, 0x62, 0x49, 0x7b, 0x0e, + 0x54, 0x43, 0x76, 0x15, 0x54, 0x43, 0x76, 0x1b, + 0x66, 0x11, 0x55, 0x21, 0x66, 0x11, 0x55, 0x29, + 0x76, 0x43, 0x76, 0x31, 0x76, 0x43, 0x76, 0x39, + 0x87, 0x10, 0x21, 0x45, 0x87, 0x10, 0x21, 0x51, + 0x8b, 0x10, 0x31, 0x59, 0xa1, 0x26, 0x47, 0x59, + 0xa1, 0x26, 0x47, 0x65, 0x8b, 0x10, 0x31, 0x65, + 0xb5, 0x0b, 0x0b, 0x63, 0xc1, 0x17, 0x17, 0x63, + 0xc1, 0x17, 0x17, 0x63, 0xc1, 0x17, 0x17, 0x63, + 0xd5, 0x00, 0x00, 0x5b, 0xd5, 0x00, 0x00, 0x4f, + 0xdf, 0x00, 0x00, 0x47, 0xdf, 0x00, 0x00, 0x3b, + 0xe5, 0x02, 0x07, 0x33, 0xe6, 0x07, 0x0d, 0x27, + 0xe7, 0x0c, 0x13, 0x1d, 0xe8, 0x11, 0x19, 0x1d, + 0xeb, 0x1b, 0x1c, 0x12, 0xec, 0x3a, 0x3b, 0x0e, + 0xed, 0x5a, 0x59, 0x0b, 0xee, 0x7a, 0x78, 0x08, + 0x9e, 0x86, 0xa7, 0x02, 0x9a, 0x82, 0xa3, 0x05, + 0x8f, 0x56, 0x7f, 0x08, 0x72, 0x39, 0x62, 0x0b, + 0x71, 0x3c, 0x75, 0x11, 0x75, 0x31, 0x68, 0x16, + 0x7a, 0x26, 0x5b, 0x1a, 0x7e, 0x1b, 0x4e, 0x20, + 0x82, 0x1c, 0x4f, 0x29, 0x8e, 0x28, 0x5b, 0x33, + 0x8e, 0x28, 0x5b, 0x3b, 0xa4, 0x1c, 0x1c, 0x41, + 0xb3, 0x0e, 0x0e, 0x45, 0xad, 0x08, 0x08, 0x4b, + 0xbd, 0x18, 0x18, 0x54, 0xb7, 0x12, 0x12, 0x54, + 0xbd, 0x00, 0x00, 0x55, 0xc9, 0x03, 0x0b, 0x55, + 0xd6, 0x00, 0x08, 0x4f, 0xd6, 0x00, 0x08, 0x4f, + 0xdb, 0x00, 0x08, 0x48, 0xdd, 0x01, 0x07, 0x3e, + 0xdf, 0x02, 0x06, 0x38, 0xe1, 0x03, 0x05, 0x32, + 0xe3, 0x00, 0x00, 0x27, 0xe5, 0x07, 0x0a, 0x21, + 0xe7, 0x0e, 0x14, 0x1b, 0xe9, 0x15, 0x1e, 0x15, + 0xeb, 0x26, 0x24, 0x0f, 0xed, 0x46, 0x42, 0x0c, + 0xef, 0x66, 0x5f, 0x09, 0xf1, 0x85, 0x7d, 0x06, + 0x9a, 0x82, 0xa3, 0x02, 0xa4, 0x8c, 0xad, 0x05, + 0xa9, 0x70, 0x99, 0x05, 0x8f, 0x56, 0x7f, 0x08, + 0x83, 0x3f, 0x6a, 0x0d, 0x88, 0x34, 0x5d, 0x11, + 0x8c, 0x29, 0x50, 0x16, 0x90, 0x1e, 0x43, 0x1a, + 0xa4, 0x1c, 0x1c, 0x21, 0xa4, 0x1c, 0x1c, 0x29, + 0xb0, 0x28, 0x28, 0x29, 0xa4, 0x1c, 0x1c, 0x33, + 0xad, 0x08, 0x08, 0x3c, 0xbd, 0x18, 0x18, 0x3c, + 0xbd, 0x18, 0x18, 0x45, 0xb3, 0x0e, 0x0e, 0x45, + 0xc9, 0x03, 0x0b, 0x41, 0xc9, 0x03, 0x0b, 0x41, + 0xd6, 0x00, 0x08, 0x41, 0xdc, 0x06, 0x0e, 0x41, + 0xdc, 0x05, 0x0c, 0x38, 0xde, 0x06, 0x0b, 0x32, + 0xe0, 0x07, 0x0a, 0x2c, 0xe2, 0x08, 0x09, 0x26, + 0xe2, 0x04, 0x03, 0x21, 0xe4, 0x0b, 0x0d, 0x1b, + 0xe6, 0x12, 0x17, 0x15, 0xe8, 0x19, 0x21, 0x11, + 0xe9, 0x31, 0x2b, 0x0c, 0xeb, 0x51, 0x49, 0x09, + 0xed, 0x71, 0x66, 0x06, 0xef, 0x90, 0x84, 0x03, + 0xa4, 0x8c, 0xad, 0x02, 0x94, 0x7c, 0x9d, 0x02, + 0xa9, 0x70, 0x99, 0x05, 0x8f, 0x56, 0x7f, 0x08, + 0x96, 0x41, 0x5f, 0x0a, 0x9a, 0x36, 0x52, 0x0d, + 0x9e, 0x2b, 0x45, 0x11, 0xa2, 0x20, 0x38, 0x16, + 0xa4, 0x1c, 0x1c, 0x1b, 0xa4, 0x1c, 0x1c, 0x21, + 0xb0, 0x28, 0x28, 0x21, 0xb0, 0x28, 0x28, 0x29, + 0xcc, 0x0e, 0x0e, 0x2a, 0xcc, 0x0e, 0x0e, 0x33, + 0xcc, 0x0e, 0x0e, 0x33, 0xd0, 0x12, 0x12, 0x33, + 0xd3, 0x0d, 0x15, 0x37, 0xd3, 0x0d, 0x15, 0x37, + 0xe6, 0x10, 0x18, 0x37, 0xdc, 0x06, 0x0e, 0x2f, + 0xdd, 0x09, 0x10, 0x2c, 0xdf, 0x0a, 0x0f, 0x2c, + 0xe1, 0x0b, 0x0e, 0x26, 0xe3, 0x0c, 0x0d, 0x20, + 0xe1, 0x08, 0x06, 0x1b, 0xe3, 0x0f, 0x10, 0x15, + 0xe5, 0x16, 0x1a, 0x11, 0xe7, 0x1d, 0x24, 0x0b, + 0xe7, 0x3c, 0x33, 0x09, 0xe9, 0x5c, 0x50, 0x06, + 0xeb, 0x7c, 0x6e, 0x03, 0xed, 0x9b, 0x8b, 0x03, + 0xa4, 0x8c, 0xad, 0x02, 0x94, 0x7c, 0x9d, 0x02, + 0xa9, 0x70, 0x99, 0x02, 0x8f, 0x56, 0x7f, 0x05, + 0xa8, 0x44, 0x54, 0x07, 0xac, 0x39, 0x47, 0x0a, + 0xb0, 0x2e, 0x3a, 0x0d, 0xb5, 0x23, 0x2d, 0x11, + 0xa4, 0x1c, 0x1c, 0x15, 0xb0, 0x28, 0x28, 0x15, + 0xb0, 0x28, 0x28, 0x1b, 0xb0, 0x28, 0x28, 0x21, + 0xd6, 0x18, 0x18, 0x24, 0xd0, 0x12, 0x12, 0x24, + 0xd6, 0x18, 0x18, 0x2a, 0xd6, 0x18, 0x18, 0x2a, + 0xdf, 0x19, 0x21, 0x29, 0xdf, 0x19, 0x21, 0x29, + 0xe6, 0x10, 0x18, 0x29, 0xe6, 0x10, 0x18, 0x23, + 0xde, 0x0e, 0x14, 0x26, 0xe0, 0x0f, 0x13, 0x20, + 0xe2, 0x10, 0x12, 0x20, 0xe4, 0x11, 0x11, 0x16, + 0xe0, 0x0c, 0x09, 0x15, 0xe2, 0x13, 0x13, 0x11, + 0xe4, 0x1a, 0x1d, 0x0b, 0xe6, 0x21, 0x27, 0x0b, + 0xe5, 0x47, 0x3a, 0x06, 0xe7, 0x67, 0x57, 0x06, + 0xe9, 0x87, 0x75, 0x03, 0xeb, 0xa6, 0x92, 0x03, + 0xd5, 0x8b, 0x83, 0x01, 0xc1, 0x77, 0x6f, 0x01, + 0xb9, 0x56, 0x56, 0x02, 0xb9, 0x56, 0x56, 0x03, + 0xcd, 0x49, 0x49, 0x05, 0xcd, 0x49, 0x49, 0x08, + 0xb9, 0x35, 0x35, 0x08, 0xb9, 0x35, 0x35, 0x0c, + 0xcb, 0x2e, 0x2c, 0x0e, 0xcb, 0x2c, 0x2c, 0x11, + 0xcb, 0x2a, 0x2c, 0x14, 0xcb, 0x28, 0x2c, 0x16, + 0xd7, 0x20, 0x24, 0x18, 0xda, 0x20, 0x23, 0x1d, + 0xdd, 0x1f, 0x22, 0x1d, 0xe0, 0x1f, 0x21, 0x1d, + 0xe7, 0x22, 0x24, 0x1e, 0xe7, 0x20, 0x24, 0x1e, + 0xe7, 0x1d, 0x24, 0x1e, 0xe7, 0x1b, 0x24, 0x1b, + 0xe3, 0x1c, 0x20, 0x19, 0xe3, 0x1c, 0x20, 0x17, + 0xe3, 0x1c, 0x20, 0x14, 0xe3, 0x1c, 0x20, 0x11, + 0xdf, 0x1a, 0x20, 0x0f, 0xe0, 0x23, 0x25, 0x0c, + 0xe1, 0x2b, 0x2a, 0x09, 0xe2, 0x34, 0x2f, 0x06, + 0xe3, 0x54, 0x49, 0x05, 0xe4, 0x69, 0x5e, 0x03, + 0xe5, 0x7e, 0x74, 0x02, 0xe6, 0x92, 0x89, 0x01, + 0xe7, 0x9d, 0x95, 0x00, 0xd5, 0x8b, 0x83, 0x01, + 0xcd, 0x6a, 0x6a, 0x01, 0xb9, 0x56, 0x56, 0x02, + 0xcd, 0x49, 0x49, 0x02, 0xcd, 0x49, 0x49, 0x05, + 0xcd, 0x49, 0x49, 0x05, 0xcd, 0x49, 0x49, 0x08, + 0xd8, 0x46, 0x46, 0x0b, 0xd8, 0x44, 0x46, 0x0b, + 0xd8, 0x42, 0x46, 0x0e, 0xd8, 0x40, 0x46, 0x11, + 0xdd, 0x3c, 0x3f, 0x12, 0xe0, 0x3b, 0x3e, 0x15, + 0xe3, 0x3b, 0x3d, 0x15, 0xe6, 0x3a, 0x3c, 0x18, + 0xe9, 0x3d, 0x3c, 0x16, 0xe9, 0x3a, 0x3c, 0x16, + 0xe9, 0x38, 0x3c, 0x16, 0xe9, 0x35, 0x3c, 0x13, + 0xe7, 0x36, 0x3b, 0x11, 0xe7, 0x36, 0x3b, 0x11, + 0xe7, 0x36, 0x3b, 0x0e, 0xe7, 0x36, 0x3b, 0x0b, + 0xe3, 0x34, 0x3a, 0x09, 0xe4, 0x3d, 0x3f, 0x09, + 0xe5, 0x45, 0x44, 0x06, 0xe6, 0x4e, 0x49, 0x04, + 0xe6, 0x63, 0x59, 0x03, 0xe7, 0x78, 0x6f, 0x02, + 0xe8, 0x8d, 0x84, 0x01, 0xe9, 0xa2, 0x99, 0x01, + 0xfb, 0xb1, 0xa9, 0x00, 0xe7, 0x9d, 0x95, 0x00, + 0xdf, 0x7c, 0x7c, 0x01, 0xcd, 0x6a, 0x6a, 0x01, + 0xe2, 0x66, 0x66, 0x02, 0xe2, 0x66, 0x66, 0x02, + 0xe2, 0x66, 0x66, 0x05, 0xe2, 0x66, 0x66, 0x05, + 0xe5, 0x5f, 0x5f, 0x08, 0xe5, 0x5d, 0x5f, 0x08, + 0xe5, 0x5b, 0x5f, 0x0b, 0xe5, 0x59, 0x5f, 0x0b, + 0xe3, 0x58, 0x59, 0x0c, 0xe6, 0x57, 0x58, 0x0f, + 0xe9, 0x57, 0x57, 0x0f, 0xec, 0x56, 0x56, 0x0f, + 0xeb, 0x58, 0x53, 0x10, 0xeb, 0x55, 0x53, 0x10, + 0xeb, 0x53, 0x53, 0x10, 0xeb, 0x50, 0x53, 0x10, + 0xeb, 0x51, 0x55, 0x0e, 0xeb, 0x51, 0x55, 0x0b, + 0xeb, 0x51, 0x55, 0x0b, 0xeb, 0x51, 0x55, 0x08, + 0xe7, 0x4f, 0x53, 0x06, 0xe8, 0x57, 0x58, 0x06, + 0xe9, 0x60, 0x5d, 0x04, 0xea, 0x68, 0x62, 0x04, + 0xe9, 0x73, 0x6a, 0x02, 0xea, 0x87, 0x7f, 0x01, + 0xeb, 0x9c, 0x94, 0x01, 0xec, 0xb1, 0xa9, 0x00, + 0xfb, 0xb1, 0xa9, 0x00, 0xfb, 0xb1, 0xa9, 0x00, + 0xf3, 0x90, 0x90, 0x00, 0xf3, 0x90, 0x90, 0x01, + 0xf8, 0x7c, 0x7c, 0x02, 0xf8, 0x7c, 0x7c, 0x02, + 0xf8, 0x7c, 0x7c, 0x02, 0xf8, 0x7c, 0x7c, 0x02, + 0xf2, 0x77, 0x79, 0x05, 0xf2, 0x75, 0x79, 0x05, + 0xf2, 0x73, 0x79, 0x05, 0xf2, 0x71, 0x79, 0x08, + 0xe9, 0x73, 0x74, 0x09, 0xec, 0x73, 0x73, 0x09, + 0xef, 0x72, 0x72, 0x09, 0xf2, 0x72, 0x71, 0x09, + 0xed, 0x72, 0x6b, 0x0a, 0xed, 0x70, 0x6b, 0x0a, + 0xed, 0x6d, 0x6b, 0x0a, 0xed, 0x6b, 0x6b, 0x0a, + 0xef, 0x6b, 0x70, 0x08, 0xef, 0x6b, 0x70, 0x08, + 0xef, 0x6b, 0x70, 0x06, 0xef, 0x6b, 0x70, 0x06, + 0xeb, 0x69, 0x6d, 0x04, 0xec, 0x71, 0x72, 0x04, + 0xed, 0x7a, 0x77, 0x01, 0xee, 0x82, 0x7c, 0x01, + 0xec, 0x82, 0x7a, 0x01, 0xed, 0x97, 0x8f, 0x01, + 0xee, 0xab, 0xa4, 0x00, 0xef, 0xc0, 0xba, 0x00, + ]) +} + diff --git a/dom/canvas/test/webgl-mochitest/test_webgl_compressed_texture_es3.html b/dom/canvas/test/webgl-mochitest/test_webgl_compressed_texture_es3.html new file mode 100644 index 0000000000..48dee2fc6f --- /dev/null +++ b/dom/canvas/test/webgl-mochitest/test_webgl_compressed_texture_es3.html @@ -0,0 +1,753 @@ + + + + + + + + +WebGL test: test WEBGL_compressed_texture_es3 extension + + + +
+ +
+ + + + + + + diff --git a/dom/webidl/WebGLRenderingContext.webidl b/dom/webidl/WebGLRenderingContext.webidl index 35693ae398..ba412ef088 100644 --- a/dom/webidl/WebGLRenderingContext.webidl +++ b/dom/webidl/WebGLRenderingContext.webidl @@ -827,6 +827,21 @@ interface WEBGL_compressed_texture_atc const GLenum COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE; }; +[NoInterfaceObject] +interface WEBGL_compressed_texture_es3 +{ + const GLenum COMPRESSED_R11_EAC = 0x9270; + const GLenum COMPRESSED_SIGNED_R11_EAC = 0x9271; + const GLenum COMPRESSED_RG11_EAC = 0x9272; + const GLenum COMPRESSED_SIGNED_RG11_EAC = 0x9273; + const GLenum COMPRESSED_RGB8_ETC2 = 0x9274; + const GLenum COMPRESSED_SRGB8_ETC2 = 0x9275; + const GLenum COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276; + const GLenum COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277; + const GLenum COMPRESSED_RGBA8_ETC2_EAC = 0x9278; + const GLenum COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279; +}; + [NoInterfaceObject] interface WEBGL_compressed_texture_etc1 { diff --git a/gfx/gl/GLTextureImage.cpp b/gfx/gl/GLTextureImage.cpp index 6973231126..5663fb3dcd 100644 --- a/gfx/gl/GLTextureImage.cpp +++ b/gfx/gl/GLTextureImage.cpp @@ -12,6 +12,7 @@ #include "mozilla/gfx/2D.h" #include "ScopedGLHelpers.h" #include "GLUploadHelpers.h" +#include "GfxTexturesReporter.h" #include "TextureImageEGL.h" #ifdef XP_MACOSX @@ -95,6 +96,16 @@ gfx::IntRect TextureImage::GetSrcTileRect() { return GetTileRect(); } +void +TextureImage::UpdateUploadSize(size_t amount) +{ + if (mUploadSize > 0) { + GfxTexturesReporter::UpdateAmount(GfxTexturesReporter::MemoryFreed, mUploadSize); + } + mUploadSize = amount; + GfxTexturesReporter::UpdateAmount(GfxTexturesReporter::MemoryAllocated, mUploadSize); +} + BasicTextureImage::~BasicTextureImage() { GLContext *ctx = mGLContext; @@ -162,16 +173,20 @@ BasicTextureImage::EndUpdate() RefPtr updateData = updateSnapshot->GetDataSurface(); bool relative = FinishedSurfaceUpdate(); - + size_t uploadSize; mTextureFormat = UploadSurfaceToTexture(mGLContext, updateData, mUpdateRegion, mTexture, + &uploadSize, mTextureState == Created, mUpdateOffset, relative); FinishedSurfaceUpload(); + if (uploadSize > 0) { + UpdateUploadSize(uploadSize); + } mUpdateDrawTarget = nullptr; mTextureState = Valid; @@ -214,14 +229,19 @@ BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion region = aRegion; } + size_t uploadSize; mTextureFormat = UploadSurfaceToTexture(mGLContext, aSurf, region, mTexture, + &uploadSize, mTextureState == Created, bounds.TopLeft() + IntPoint(aFrom.x, aFrom.y), false); + if (uploadSize > 0) { + UpdateUploadSize(uploadSize); + } mTextureState = Valid; return true; } @@ -273,6 +293,7 @@ TextureImage::TextureImage(const gfx::IntSize& aSize, , mTextureFormat(gfx::SurfaceFormat::UNKNOWN) , mFilter(Filter::GOOD) , mFlags(aFlags) + , mUploadSize(0) {} BasicTextureImage::BasicTextureImage(GLuint aTexture, diff --git a/gfx/gl/GLTextureImage.h b/gfx/gl/GLTextureImage.h index 231f6b6d18..958d6ae506 100644 --- a/gfx/gl/GLTextureImage.h +++ b/gfx/gl/GLTextureImage.h @@ -203,6 +203,8 @@ public: protected: friend class GLContext; + void UpdateUploadSize(size_t amount); + /** * After the ctor, the TextureImage is invalid. Implementations * must allocate resources successfully before returning the new @@ -214,7 +216,9 @@ protected: Flags aFlags = NoFlags); // Protected destructor, to discourage deletion outside of Release(): - virtual ~TextureImage() {} + virtual ~TextureImage() { + UpdateUploadSize(0); + } virtual gfx::IntRect GetSrcTileRect(); @@ -224,6 +228,7 @@ protected: gfx::SurfaceFormat mTextureFormat; gfx::Filter mFilter; Flags mFlags; + size_t mUploadSize; }; /** diff --git a/gfx/gl/GLUploadHelpers.cpp b/gfx/gl/GLUploadHelpers.cpp index b92c47a61d..0c52557b0d 100644 --- a/gfx/gl/GLUploadHelpers.cpp +++ b/gfx/gl/GLUploadHelpers.cpp @@ -9,6 +9,8 @@ #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Tools.h" // For BytesPerPixel #include "nsRegion.h" +#include "GfxTexturesReporter.h" +#include "mozilla/gfx/Logging.h" namespace mozilla { @@ -379,6 +381,51 @@ TexImage2DHelper(GLContext *gl, } } +static uint32_t +GetBytesPerTexel(GLenum format, GLenum type) +{ + // If there is no defined format or type, we're not taking up any memory + if (!format || !type) { + return 0; + } + + if (format == LOCAL_GL_DEPTH_COMPONENT) { + if (type == LOCAL_GL_UNSIGNED_SHORT) + return 2; + else if (type == LOCAL_GL_UNSIGNED_INT) + return 4; + } else if (format == LOCAL_GL_DEPTH_STENCIL) { + if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT) + return 4; + } + + if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT || type == LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV) { + uint32_t multiplier = type == LOCAL_GL_UNSIGNED_BYTE ? 1 : 4; + switch (format) { + case LOCAL_GL_ALPHA: + case LOCAL_GL_LUMINANCE: + return 1 * multiplier; + case LOCAL_GL_LUMINANCE_ALPHA: + return 2 * multiplier; + case LOCAL_GL_RGB: + return 3 * multiplier; + case LOCAL_GL_RGBA: + return 4 * multiplier; + default: + break; + } + } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 || + type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 || + type == LOCAL_GL_UNSIGNED_SHORT_5_6_5) + { + return 2; + } + + gfxCriticalError() << "Unknown texture type " << type << " or format " << format; + MOZ_CRASH(); + return 0; +} + SurfaceFormat UploadImageDataToTexture(GLContext* gl, unsigned char* aData, @@ -386,6 +433,7 @@ UploadImageDataToTexture(GLContext* gl, SurfaceFormat aFormat, const nsIntRegion& aDstRegion, GLuint& aTexture, + size_t* aOutUploadSize, bool aOverwrite, bool aPixelBuffer, GLenum aTextureUnit, @@ -505,6 +553,10 @@ UploadImageDataToTexture(GLContext* gl, // Top left point of the region's bounding rectangle. IntPoint topLeft = paintRegion.GetBounds().TopLeft(); + if (aOutUploadSize) { + *aOutUploadSize = 0; + } + for (auto iter = paintRegion.RectIter(); !iter.Done(); iter.Next()) { const IntRect& rect = iter.Get(); // The inital data pointer is at the top left point of the region's @@ -544,6 +596,11 @@ UploadImageDataToTexture(GLContext* gl, rectData); } + if (aOutUploadSize && !textureInited) { + uint32_t texelSize = GetBytesPerTexel(internalFormat, type); + size_t numTexels = size_t(rect.width) * size_t(rect.height); + *aOutUploadSize += texelSize * numTexels; + } } return surfaceFormat; @@ -551,9 +608,10 @@ UploadImageDataToTexture(GLContext* gl, SurfaceFormat UploadSurfaceToTexture(GLContext* gl, - DataSourceSurface *aSurface, + DataSourceSurface* aSurface, const nsIntRegion& aDstRegion, GLuint& aTexture, + size_t* aOutUploadSize, bool aOverwrite, const gfx::IntPoint& aSrcPoint, bool aPixelBuffer, @@ -565,8 +623,8 @@ UploadSurfaceToTexture(GLContext* gl, SurfaceFormat format = aSurface->GetFormat(); data += DataOffset(aSrcPoint, stride, format); return UploadImageDataToTexture(gl, data, stride, format, - aDstRegion, aTexture, aOverwrite, - aPixelBuffer, aTextureUnit, + aDstRegion, aTexture, aOutUploadSize, + aOverwrite, aPixelBuffer, aTextureUnit, aTextureTarget); } diff --git a/gfx/gl/GLUploadHelpers.h b/gfx/gl/GLUploadHelpers.h index 46db6fe068..25a3348855 100644 --- a/gfx/gl/GLUploadHelpers.h +++ b/gfx/gl/GLUploadHelpers.h @@ -40,6 +40,7 @@ class GLContext; * \param aData Image data to upload. * \param aDstRegion Region of texture to upload to. * \param aTexture Texture to use, or 0 to have one created for you. + * \param aOutUploadSize if set, the number of bytes the texture requires will be returned here * \param aOverwrite Over an existing texture with a new one. * \param aSrcPoint Offset into aSrc where the region's bound's * TopLeft() sits. @@ -59,6 +60,7 @@ UploadImageDataToTexture(GLContext* gl, gfx::SurfaceFormat aFormat, const nsIntRegion& aDstRegion, GLuint& aTexture, + size_t* aOutUploadSize = nullptr, bool aOverwrite = false, bool aPixelBuffer = false, GLenum aTextureUnit = LOCAL_GL_TEXTURE0, @@ -72,6 +74,7 @@ UploadSurfaceToTexture(GLContext* gl, gfx::DataSourceSurface *aSurface, const nsIntRegion& aDstRegion, GLuint& aTexture, + size_t* aOutUploadSize = nullptr, bool aOverwrite = false, const gfx::IntPoint& aSrcPoint = gfx::IntPoint(0, 0), bool aPixelBuffer = false, diff --git a/gfx/gl/GfxTexturesReporter.cpp b/gfx/gl/GfxTexturesReporter.cpp index 59f35b4bc5..416349c0b2 100644 --- a/gfx/gl/GfxTexturesReporter.cpp +++ b/gfx/gl/GfxTexturesReporter.cpp @@ -5,85 +5,22 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "GfxTexturesReporter.h" -#include "GLDefs.h" using namespace mozilla; using namespace mozilla::gl; NS_IMPL_ISUPPORTS(GfxTexturesReporter, nsIMemoryReporter) -Atomic GfxTexturesReporter::sAmount(0); -Atomic GfxTexturesReporter::sTileWasteAmount(0); - -static uint32_t -GetBitsPerTexel(GLenum format, GLenum type) -{ - // If there is no defined format or type, we're not taking up any memory - if (!format || !type) { - return 0; - } - - if (format == LOCAL_GL_DEPTH_COMPONENT) { - if (type == LOCAL_GL_UNSIGNED_SHORT) - return 2*8; - else if (type == LOCAL_GL_UNSIGNED_INT) - return 4*8; - } else if (format == LOCAL_GL_DEPTH_STENCIL) { - if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT) - return 4*8; - } - - if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) { - uint32_t multiplier = type == LOCAL_GL_FLOAT ? 32 : 8; - switch (format) { - case LOCAL_GL_ALPHA: - case LOCAL_GL_LUMINANCE: - return 1 * multiplier; - case LOCAL_GL_LUMINANCE_ALPHA: - return 2 * multiplier; - case LOCAL_GL_RGB: - return 3 * multiplier; - case LOCAL_GL_RGBA: - return 4 * multiplier; - case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1: - case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1: - return 2; - case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case LOCAL_GL_ATC_RGB: - case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1: - case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1: - case LOCAL_GL_ETC1_RGB8_OES: - return 4; - case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA: - case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA: - return 8; - default: - break; - } - } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 || - type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 || - type == LOCAL_GL_UNSIGNED_SHORT_5_6_5) - { - return 2*8; - } - - MOZ_ASSERT(false); - return 0; -} +Atomic GfxTexturesReporter::sAmount(0); +Atomic GfxTexturesReporter::sTileWasteAmount(0); /* static */ void -GfxTexturesReporter::UpdateAmount(MemoryUse action, GLenum format, - GLenum type, int32_t tileWidth, - int32_t tileHeight) +GfxTexturesReporter::UpdateAmount(MemoryUse action, size_t amount) { - int64_t bitsPerTexel = GetBitsPerTexel(format, type); - int64_t bytes = int64_t(tileWidth) * int64_t(tileHeight) * bitsPerTexel/8; if (action == MemoryFreed) { - sAmount -= bytes; + MOZ_RELEASE_ASSERT(amount <= sAmount); + sAmount -= amount; } else { - sAmount += bytes; + sAmount += amount; } } diff --git a/gfx/gl/GfxTexturesReporter.h b/gfx/gl/GfxTexturesReporter.h index 89f9c4d151..7553853f14 100644 --- a/gfx/gl/GfxTexturesReporter.h +++ b/gfx/gl/GfxTexturesReporter.h @@ -41,10 +41,9 @@ public: // When memory is used/freed for tile textures, call this method to update // the value reported by this memory reporter. - static void UpdateAmount(MemoryUse action, GLenum format, GLenum type, - int32_t tileWidth, int32_t tileHeight); + static void UpdateAmount(MemoryUse action, size_t amount); - static void UpdateWasteAmount(int32_t delta) { + static void UpdateWasteAmount(size_t delta) { sTileWasteAmount += delta; } @@ -52,17 +51,17 @@ public: nsISupports* aData, bool aAnonymize) override { MOZ_COLLECT_REPORT("gfx-tiles-waste", KIND_OTHER, UNITS_BYTES, - sTileWasteAmount, + int64_t(sTileWasteAmount), "Memory lost due to tiles extending past content boundaries"); return MOZ_COLLECT_REPORT( - "gfx-textures", KIND_OTHER, UNITS_BYTES, sAmount, + "gfx-textures", KIND_OTHER, UNITS_BYTES, int64_t(sAmount), "Memory used for storing GL textures."); } private: - static Atomic sAmount; + static Atomic sAmount; // Count the amount of memory lost to tile waste - static Atomic sTileWasteAmount; + static Atomic sTileWasteAmount; }; class GfxTextureWasteTracker { diff --git a/gfx/gl/TextureImageEGL.cpp b/gfx/gl/TextureImageEGL.cpp index 1f4323b60e..31150f08b7 100644 --- a/gfx/gl/TextureImageEGL.cpp +++ b/gfx/gl/TextureImageEGL.cpp @@ -207,14 +207,19 @@ TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& region = aRegion; } + size_t uploadSize = 0; mTextureFormat = UploadSurfaceToTexture(mGLContext, aSurf, region, mTexture, + &uploadSize, mTextureState == Created, bounds.TopLeft() + gfx::IntPoint(aFrom.x, aFrom.y), false); + if (uploadSize > 0) { + UpdateUploadSize(uploadSize); + } mTextureState = Valid; return true; diff --git a/js/src/asmjs/AsmJS.cpp b/js/src/asmjs/AsmJS.cpp index 2b8d5becdd..881c79383f 100644 --- a/js/src/asmjs/AsmJS.cpp +++ b/js/src/asmjs/AsmJS.cpp @@ -918,6 +918,10 @@ ParseVarOrConstStatement(AsmJSParser& parser, ParseNode** var) // out of range: otherwise // Lastly, a literal may be a float literal which is any double or integer // literal coerced with Math.fround. +// +// This class distinguishes between signed and unsigned integer SIMD types like +// Int32x4 and Uint32x4, and so does Type below. The wasm ValType and ExprType +// enums, and the wasm::Val class do not. class NumLit { public: @@ -928,6 +932,7 @@ class NumLit Double, Float, Int32x4, + Uint32x4, Float32x4, Bool32x4, OutOfRangeInt = -1 @@ -982,7 +987,8 @@ class NumLit } bool isSimd() const { - return which_ == Int32x4 || which_ == Float32x4 || which_ == Bool32x4; + return which_ == Int32x4 || which_ == Uint32x4 || which_ == Float32x4 || + which_ == Bool32x4; } const SimdConstant& simdValue() const { @@ -1006,6 +1012,7 @@ class NumLit case NumLit::Float: return toFloat() == 0.f && !IsNegativeZero(toFloat()); case NumLit::Int32x4: + case NumLit::Uint32x4: return simdValue() == SimdConstant::SplatX4(0); case NumLit::Float32x4: return simdValue() == SimdConstant::SplatX4(0.f); @@ -1028,6 +1035,7 @@ class NumLit case NumLit::Double: return Val(toDouble()); case NumLit::Int32x4: + case NumLit::Uint32x4: return Val(simdValue().asInt32x4()); case NumLit::Float32x4: return Val(simdValue().asFloat32x4()); @@ -1063,6 +1071,7 @@ class Type DoubleLit = NumLit::Double, Float = NumLit::Float, Int32x4 = NumLit::Int32x4, + Uint32x4 = NumLit::Uint32x4, Float32x4 = NumLit::Float32x4, Bool32x4 = NumLit::Bool32x4, Double, @@ -1083,6 +1092,7 @@ class Type MOZ_IMPLICIT Type(SimdType type) { switch (type) { case SimdType::Int32x4: which_ = Int32x4; return; + case SimdType::Uint32x4: which_ = Uint32x4; return; case SimdType::Float32x4: which_ = Float32x4; return; case SimdType::Bool32x4: which_ = Bool32x4; return; default: break; @@ -1090,35 +1100,6 @@ class Type MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad SimdType"); } - static Type var(ValType t) { - switch (t) { - case ValType::I32: return Int; - case ValType::I64: MOZ_CRASH("no int64 in asm.js"); - case ValType::F32: return Float; - case ValType::F64: return Double; - case ValType::I32x4: return Int32x4; - case ValType::F32x4: return Float32x4; - case ValType::B32x4: return Bool32x4; - case ValType::Limit: break; - } - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad type"); - } - - static Type ret(ExprType t) { - switch (t) { - case ExprType::Void: return Type::Void; - case ExprType::I32: return Signed; - case ExprType::I64: MOZ_CRASH("no int64 in asm.js"); - case ExprType::F32: return Float; - case ExprType::F64: return Double; - case ExprType::I32x4: return Int32x4; - case ExprType::F32x4: return Float32x4; - case ExprType::B32x4: return Bool32x4; - case ExprType::Limit: break; - } - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad type"); - } - // Map an already canonicalized Type to the return type of a function call. static Type ret(Type t) { MOZ_ASSERT(t.isCanonical()); @@ -1156,6 +1137,7 @@ class Type return Void; case Int32x4: + case Uint32x4: case Float32x4: case Bool32x4: return t; @@ -1184,6 +1166,7 @@ class Type case Double: return isDouble(); case Float: return isFloat(); case Int32x4: return isInt32x4(); + case Uint32x4: return isUint32x4(); case Float32x4: return isFloat32x4(); case Bool32x4: return isBool32x4(); case MaybeDouble: return isMaybeDouble(); @@ -1253,6 +1236,10 @@ class Type return which_ == Int32x4; } + bool isUint32x4() const { + return which_ == Uint32x4; + } + bool isFloat32x4() const { return which_ == Float32x4; } @@ -1262,17 +1249,27 @@ class Type } bool isSimd() const { - return isInt32x4() || isFloat32x4() || isBool32x4(); + return isInt32x4() || isUint32x4() || isFloat32x4() || isBool32x4(); + } + + bool isUnsignedSimd() const { + return isUint32x4(); } // Check if this is one of the valid types for a function argument. bool isArgType() const { - return isInt() || isFloat() || isDouble() || isSimd(); + return isInt() || isFloat() || isDouble() || (isSimd() && !isUnsignedSimd()); } // Check if this is one of the valid types for a function return value. bool isReturnType() const { - return isSigned() || isFloat() || isDouble() || isSimd() || isVoid(); + return isSigned() || isFloat() || isDouble() || (isSimd() && !isUnsignedSimd()) || + isVoid(); + } + + // Check if this is one of the valid types for a global variable. + bool isGlobalVarType() const { + return isArgType(); } // Check if this is one of the canonical vartype representations of a @@ -1301,6 +1298,7 @@ class Type case Float: return ExprType::F32; case Double: return ExprType::F64; case Void: return ExprType::Void; + case Uint32x4: case Int32x4: return ExprType::I32x4; case Float32x4: return ExprType::F32x4; case Bool32x4: return ExprType::B32x4; @@ -1327,6 +1325,7 @@ class Type case Unsigned: return "unsigned"; case Intish: return "intish"; case Int32x4: return "int32x4"; + case Uint32x4: return "uint32x4"; case Float32x4: return "float32x4"; case Bool32x4: return "bool32x4"; case Void: return "void"; @@ -1830,11 +1829,13 @@ class MOZ_STACK_CLASS ModuleValidator MOZ_ASSERT(n->isTenured()); module_->bufferArgumentName = n; } - bool addGlobalVarInit(PropertyName* var, const NumLit& lit, bool isConst) { + bool addGlobalVarInit(PropertyName* var, const NumLit& lit, Type type, bool isConst) + { + MOZ_ASSERT(type.isGlobalVarType()); + MOZ_ASSERT(type == Type::canonicalize(Type::lit(lit))); + uint32_t index; - Type litType = Type::lit(lit); - Type canonicalType = Type::canonicalize(litType); - if (!mg_.allocateGlobalVar(canonicalType.canonicalToValType(), isConst, &index)) + if (!mg_.allocateGlobalVar(type.canonicalToValType(), isConst, &index)) return false; Global::Which which = isConst ? Global::ConstantLiteral : Global::Variable; @@ -1842,7 +1843,7 @@ class MOZ_STACK_CLASS ModuleValidator if (!global) return false; global->u.varOrConst.index_ = index; - global->u.varOrConst.type_ = (isConst ? litType : canonicalType).which(); + global->u.varOrConst.type_ = (isConst ? Type::lit(lit) : type).which(); if (isConst) global->u.varOrConst.literalValue_ = lit; if (!globalMap_.putNew(var, global)) @@ -1854,9 +1855,12 @@ class MOZ_STACK_CLASS ModuleValidator g.pod.u.var.globalDataOffset_ = mg_.globalVar(index).globalDataOffset; return module_->globals.append(g); } - bool addGlobalVarImport(PropertyName* var, PropertyName* field, ValType type, bool isConst) { + bool addGlobalVarImport(PropertyName* var, PropertyName* field, Type type, bool isConst) { + MOZ_ASSERT(type.isGlobalVarType()); + uint32_t index; - if (!mg_.allocateGlobalVar(type, isConst, &index)) + ValType valType = type.canonicalToValType(); + if (!mg_.allocateGlobalVar(valType, isConst, &index)) return false; Global::Which which = isConst ? Global::ConstantImport : Global::Variable; @@ -1864,13 +1868,13 @@ class MOZ_STACK_CLASS ModuleValidator if (!global) return false; global->u.varOrConst.index_ = index; - global->u.varOrConst.type_ = Type::var(type).which(); + global->u.varOrConst.type_ = type.which(); if (!globalMap_.putNew(var, global)) return false; AsmJSGlobal g(AsmJSGlobal::Variable, field); g.pod.u.var.initKind_ = AsmJSGlobal::InitImport; - g.pod.u.var.u.importType_ = type; + g.pod.u.var.u.importType_ = valType; g.pod.u.var.globalDataOffset_ = mg_.globalVar(index).globalDataOffset; return module_->globals.append(g); } @@ -2369,6 +2373,7 @@ IsSimdLiteral(ModuleValidator& m, ParseNode* pn) uint32_t _; switch (type) { case SimdType::Int32x4: + case SimdType::Uint32x4: case SimdType::Bool32x4: if (!IsLiteralInt(m, arg, &_)) return false; @@ -2425,7 +2430,8 @@ ExtractSimdValue(ModuleValidator& m, ParseNode* pn) ParseNode* arg = CallArgList(pn); switch (type) { - case SimdType::Int32x4: { + case SimdType::Int32x4: + case SimdType::Uint32x4: { MOZ_ASSERT(GetSimdLanes(type) == 4); int32_t val[4]; for (size_t i = 0; i < 4; i++, arg = NextNode(arg)) { @@ -2434,7 +2440,8 @@ ExtractSimdValue(ModuleValidator& m, ParseNode* pn) val[i] = int32_t(u32); } MOZ_ASSERT(arg== nullptr); - return NumLit(NumLit::Int32x4, SimdConstant::CreateX4(val)); + NumLit::Which w = type == SimdType::Uint32x4 ? NumLit::Uint32x4 : NumLit::Int32x4; + return NumLit(w, SimdConstant::CreateX4(val)); } case SimdType::Float32x4: { MOZ_ASSERT(GetSimdLanes(type) == 4); @@ -2524,6 +2531,7 @@ IsLiteralInt(NumLit lit, uint32_t* u32) case NumLit::Float: case NumLit::OutOfRangeInt: case NumLit::Int32x4: + case NumLit::Uint32x4: case NumLit::Float32x4: case NumLit::Bool32x4: return false; @@ -2751,6 +2759,7 @@ class MOZ_STACK_CLASS FunctionValidator return encoder().writeExpr(Expr::F64Const) && encoder().writeFixedF64(lit.toDouble()); case NumLit::Int32x4: + case NumLit::Uint32x4: return encoder().writeExpr(Expr::I32x4Const) && encoder().writeFixedI32x4(lit.simdValue().asInt32x4()); case NumLit::Float32x4: @@ -2901,7 +2910,11 @@ CheckGlobalVariableInitConstant(ModuleValidator& m, PropertyName* varName, Parse if (!lit.valid()) return m.fail(initNode, "global initializer is out of representable integer range"); - return m.addGlobalVarInit(varName, lit, isConst); + Type canonicalType = Type::canonicalize(Type::lit(lit)); + if (!canonicalType.isGlobalVarType()) + return m.fail(initNode, "global variable type not allowed"); + + return m.addGlobalVarInit(varName, lit, canonicalType, isConst); } static bool @@ -2937,12 +2950,20 @@ CheckTypeAnnotation(ModuleValidator& m, ParseNode* coercionNode, Type* coerceTo, } static bool -CheckGlobalVariableImportExpr(ModuleValidator& m, PropertyName* varName, ValType coerceTo, - ParseNode* coercedExpr, bool isConst) +CheckGlobalVariableInitImport(ModuleValidator& m, PropertyName* varName, ParseNode* initNode, + bool isConst) { + Type coerceTo; + ParseNode* coercedExpr; + if (!CheckTypeAnnotation(m, initNode, &coerceTo, &coercedExpr)) + return false; + if (!coercedExpr->isKind(PNK_DOT)) return m.failName(coercedExpr, "invalid import expression for global '%s'", varName); + if (!coerceTo.isGlobalVarType()) + return m.fail(initNode, "global variable type not allowed"); + ParseNode* base = DotBase(coercedExpr); PropertyName* field = DotMember(coercedExpr); @@ -2955,17 +2976,6 @@ CheckGlobalVariableImportExpr(ModuleValidator& m, PropertyName* varName, ValType return m.addGlobalVarImport(varName, field, coerceTo, isConst); } -static bool -CheckGlobalVariableInitImport(ModuleValidator& m, PropertyName* varName, ParseNode* initNode, - bool isConst) -{ - Type coerceTo; - ParseNode* coercedExpr; - if (!CheckTypeAnnotation(m, initNode, &coerceTo, &coercedExpr)) - return false; - return CheckGlobalVariableImportExpr(m, varName, coerceTo.canonicalToValType(), coercedExpr, isConst); -} - static bool IsArrayViewCtorName(ModuleValidator& m, PropertyName* name, Scalar::Type* type) { @@ -3051,24 +3061,6 @@ CheckNewArrayView(ModuleValidator& m, PropertyName* varName, ParseNode* newExpr) return m.addArrayView(varName, type, field); } -static bool -IsSimdTypeName(ModuleValidator& m, PropertyName* name, SimdType* type) -{ - if (name == m.cx()->names().Int32x4) { - *type = SimdType::Int32x4; - return true; - } - if (name == m.cx()->names().Float32x4) { - *type = SimdType::Float32x4; - return true; - } - if (name == m.cx()->names().Bool32x4) { - *type = SimdType::Bool32x4; - return true; - } - return false; -} - static bool IsSimdValidOperationType(SimdType type, SimdOperation op) { @@ -3076,27 +3068,39 @@ IsSimdValidOperationType(SimdType type, SimdOperation op) switch(type) { case SimdType::Int32x4: switch (op) { + case SimdOperation::Constructor: + case SimdOperation::Fn_fromUint32x4Bits: + FORALL_INT32X4_ASMJS_OP(CASE) return true; + default: return false; + } + break; + case SimdType::Uint32x4: + switch (op) { + case SimdOperation::Constructor: + case SimdOperation::Fn_fromInt32x4Bits: FORALL_INT32X4_ASMJS_OP(CASE) return true; default: return false; } break; case SimdType::Float32x4: switch (op) { + case SimdOperation::Constructor: FORALL_FLOAT32X4_ASMJS_OP(CASE) return true; default: return false; } break; case SimdType::Bool32x4: switch (op) { + case SimdOperation::Constructor: FORALL_BOOL_SIMD_OP(CASE) return true; default: return false; } break; default: - break; + // Unimplemented SIMD type. + return false; } #undef CASE - MOZ_CRASH("Unhandles SIMD type"); } static bool @@ -3140,8 +3144,17 @@ CheckGlobalSimdImport(ModuleValidator& m, ParseNode* initNode, PropertyName* var // SIMD constructor, with the form glob.SIMD.[[type]] SimdType simdType; - if (!IsSimdTypeName(m, field, &simdType)) + if (!IsSimdTypeName(m.cx()->names(), field, &simdType)) return m.failName(initNode, "'%s' is not a standard SIMD type", field); + + // IsSimdTypeName will return true for any SIMD type supported by the VM. + // + // Since we may not support all of those SIMD types in asm.js, use the + // asm.js-specific IsSimdValidOperationType() to check if this specific + // constructor is supported in asm.js. + if (!IsSimdValidOperationType(simdType, SimdOperation::Constructor)) + return m.failName(initNode, "'%s' is not a supported SIMD type", field); + return m.addSimdCtor(varName, simdType, field); } @@ -3313,6 +3326,9 @@ CheckArgumentType(FunctionValidator& f, ParseNode* stmt, PropertyName* name, Typ if (!CheckTypeAnnotation(f.m(), coercionNode, type, &coercedExpr)) return false; + if (!type->isArgType()) + return f.failName(stmt, "invalid type for argument '%s'", name); + if (!IsUseOfName(coercedExpr, name)) return ArgFail(f, name, stmt); @@ -3591,6 +3607,14 @@ static bool CheckAndPrepareArrayAccess(FunctionValidator& f, ParseNode* viewName, ParseNode* indexExpr, Scalar::Type* viewType, int32_t* mask) { + // asm.js doesn't have constant offsets, so just encode a 0. + if (!f.encoder().writeVarU32(0)) + return false; + + size_t alignAt; + if (!f.encoder().writePatchableVarU8(&alignAt)) + return false; + size_t prepareAt; if (!f.encoder().writePatchableExpr(&prepareAt)) return false; @@ -3598,6 +3622,9 @@ CheckAndPrepareArrayAccess(FunctionValidator& f, ParseNode* viewName, ParseNode* if (!CheckArrayAccess(f, viewName, indexExpr, viewType, mask)) return false; + // asm.js only has naturally-aligned accesses. + f.encoder().patchVarU8(alignAt, TypedArrayElemSize(*viewType)); + // Don't generate the mask op if there is no need for it which could happen for // a shift of zero or a SIMD access. if (*mask != NoMask) { @@ -4244,14 +4271,14 @@ CheckSignatureAgainstExisting(ModuleValidator& m, ParseNode* usepn, const Sig& s for (unsigned i = 0; i < sig.args().length(); i++) { if (sig.arg(i) != existing.arg(i)) { - return m.failf(usepn, "incompatible type for argument %u: (%s here vs. %s before)", - i, Type::var(sig.arg(i)).toChars(), Type::var(existing.arg(i)).toChars()); + return m.failf(usepn, "incompatible type for argument %u: (%s here vs. %s before)", i, + ToCString(sig.arg(i)), ToCString(existing.arg(i))); } } if (sig.ret() != existing.ret()) { return m.failf(usepn, "%s incompatible with previous return of type %s", - Type::ret(sig.ret()).toChars(), Type::ret(existing.ret()).toChars()); + ToCString(sig.ret()), ToCString(existing.ret())); } MOZ_ASSERT(sig == existing); @@ -4280,7 +4307,10 @@ static bool CheckIsArgType(FunctionValidator& f, ParseNode* argNode, Type type) { if (!type.isArgType()) - return f.failf(argNode, "%s is not a subtype of int, float or double", type.toChars()); + return f.failf(argNode, + "%s is not a subtype of int, float, double, or an allowed SIMD type", + type.toChars()); + return true; } @@ -4663,6 +4693,7 @@ SimdToCoercedScalarType(SimdType t) { switch (t) { case SimdType::Int32x4: + case SimdType::Uint32x4: case SimdType::Bool32x4: return Type::Intish; case SimdType::Float32x4: @@ -4851,7 +4882,7 @@ CheckSimdBinaryShift(FunctionValidator& f, ParseNode* call, SimdType opType, Sim return false; if (!CheckSimdCallArgs(f, call, 2, CheckSimdVectorScalarArgs(opType))) return false; - *type = Type::Int32x4; + *type = opType; return true; } @@ -4863,7 +4894,7 @@ CheckSimdBinaryComp(FunctionValidator& f, ParseNode* call, SimdType opType, Simd return false; if (!CheckSimdCallArgs(f, call, 2, CheckArgIsSubtypeOf(opType))) return false; - *type = Type::Bool32x4; + *type = GetBooleanSimdType(opType); return true; } @@ -4886,6 +4917,7 @@ CheckSimdExtractLane(FunctionValidator& f, ParseNode* call, SimdType opType, Typ return false; switch (opType) { case SimdType::Int32x4: *type = Type::Signed; break; + case SimdType::Uint32x4: *type = Type::Unsigned; break; case SimdType::Float32x4: *type = Type::Float; break; case SimdType::Bool32x4: *type = Type::Int; break; default: MOZ_CRASH("unhandled simd type"); @@ -5166,6 +5198,9 @@ CheckSimdOperationCall(FunctionValidator& f, ParseNode* call, const ModuleValida case SimdOperation::Fn_fromInt32x4: case SimdOperation::Fn_fromInt32x4Bits: return CheckSimdCast(f, call, SimdType::Int32x4, opType, op, type); + case SimdOperation::Fn_fromUint32x4: + case SimdOperation::Fn_fromUint32x4Bits: + return CheckSimdCast(f, call, SimdType::Uint32x4, opType, op, type); case SimdOperation::Fn_fromFloat32x4: case SimdOperation::Fn_fromFloat32x4Bits: return CheckSimdCast(f, call, SimdType::Float32x4, opType, op, type); @@ -5207,12 +5242,10 @@ CheckSimdOperationCall(FunctionValidator& f, ParseNode* call, const ModuleValida case SimdOperation::Constructor: MOZ_CRASH("constructors are handled in CheckSimdCtorCall"); - case SimdOperation::Fn_fromUint32x4: case SimdOperation::Fn_fromInt8x16Bits: case SimdOperation::Fn_fromInt16x8Bits: case SimdOperation::Fn_fromUint8x16Bits: case SimdOperation::Fn_fromUint16x8Bits: - case SimdOperation::Fn_fromUint32x4Bits: case SimdOperation::Fn_fromFloat64x2Bits: MOZ_CRASH("NYI"); } @@ -5593,12 +5626,8 @@ CheckConditional(FunctionValidator& f, ParseNode* ternary, Type* type) *type = Type::Double; } else if (thenType.isFloat() && elseType.isFloat()) { *type = Type::Float; - } else if (elseType.isInt32x4() && thenType.isInt32x4()) { - *type = Type::Int32x4; - } else if (elseType.isFloat32x4() && thenType.isFloat32x4()) { - *type = Type::Float32x4; - } else if (elseType.isBool32x4() && thenType.isBool32x4()) { - *type = Type::Bool32x4; + } else if (thenType.isSimd() && elseType == thenType) { + *type = thenType; } else { return f.failf(ternary, "then/else branches of conditional must both produce int, float, " "double or SIMD types, current types are %s and %s", @@ -5626,6 +5655,7 @@ IsValidIntMultiplyConstant(ModuleValidator& m, ParseNode* expr) case NumLit::Float: case NumLit::OutOfRangeInt: case NumLit::Int32x4: + case NumLit::Uint32x4: case NumLit::Float32x4: case NumLit::Bool32x4: return false; @@ -6167,6 +6197,7 @@ CheckCaseExpr(FunctionValidator& f, ParseNode* caseExpr, int32_t* value) case NumLit::Double: case NumLit::Float: case NumLit::Int32x4: + case NumLit::Uint32x4: case NumLit::Float32x4: case NumLit::Bool32x4: return f.fail(caseExpr, "switch case expression must be an integer literal"); @@ -6327,7 +6358,7 @@ CheckReturnType(FunctionValidator& f, ParseNode* usepn, Type ret) if (f.returnedType() != ret.canonicalToExprType()) { return f.failf(usepn, "%s incompatible with previous return of type %s", - Type::ret(ret).toChars(), Type::ret(f.returnedType()).toChars()); + Type::ret(ret).toChars(), ToCString(f.returnedType())); } return true; @@ -6840,6 +6871,7 @@ GetDataProperty(JSContext* cx, HandleValue objVal, HandlePropertyName field, Mut static bool HasPureCoercion(JSContext* cx, HandleValue v) { + // Unsigned SIMD types are not allowed in function signatures. if (IsVectorObject(v) || IsVectorObject(v) || IsVectorObject(v)) return true; @@ -7040,7 +7072,7 @@ ValidateSimdType(JSContext* cx, const AsmJSGlobal& global, HandleValue globalVal else type = global.simdOperationType(); - RootedPropertyName simdTypeName(cx, SimdTypeToName(cx, type)); + RootedPropertyName simdTypeName(cx, SimdTypeToName(cx->names(), type)); if (!GetDataProperty(cx, v, simdTypeName, &v)) return false; @@ -7080,12 +7112,21 @@ ValidateSimdOperation(JSContext* cx, const AsmJSGlobal& global, HandleValue glob Native native = nullptr; switch (global.simdOperationType()) { #define SET_NATIVE_INT32X4(op) case SimdOperation::Fn_##op: native = simd_int32x4_##op; break; +#define SET_NATIVE_UINT32X4(op) case SimdOperation::Fn_##op: native = simd_uint32x4_##op; break; #define SET_NATIVE_FLOAT32X4(op) case SimdOperation::Fn_##op: native = simd_float32x4_##op; break; #define SET_NATIVE_BOOL32X4(op) case SimdOperation::Fn_##op: native = simd_bool32x4_##op; break; #define FALLTHROUGH(op) case SimdOperation::Fn_##op: case SimdType::Int32x4: switch (global.simdOperation()) { FORALL_INT32X4_ASMJS_OP(SET_NATIVE_INT32X4) + SET_NATIVE_INT32X4(fromUint32x4Bits) + default: MOZ_CRASH("shouldn't have been validated in the first place"); + } + break; + case SimdType::Uint32x4: + switch (global.simdOperation()) { + FORALL_INT32X4_ASMJS_OP(SET_NATIVE_UINT32X4) + SET_NATIVE_UINT32X4(fromInt32x4Bits) default: MOZ_CRASH("shouldn't have been validated in the first place"); } break; @@ -7103,8 +7144,9 @@ ValidateSimdOperation(JSContext* cx, const AsmJSGlobal& global, HandleValue glob break; default: MOZ_CRASH("unhandled simd type"); #undef FALLTHROUGH -#undef SET_NATIVE_FLOAT32X4 #undef SET_NATIVE_INT32X4 +#undef SET_NATIVE_UINT32X4 +#undef SET_NATIVE_FLOAT32X4 #undef SET_NATIVE_BOOL32X4 #undef SET_NATIVE } diff --git a/js/src/asmjs/Wasm.cpp b/js/src/asmjs/Wasm.cpp index 3cd7357b2c..24205cfbfd 100644 --- a/js/src/asmjs/Wasm.cpp +++ b/js/src/asmjs/Wasm.cpp @@ -83,23 +83,6 @@ class FunctionDecoder } }; -static const char* -ToCString(ExprType type) -{ - switch (type) { - case ExprType::Void: return "void"; - case ExprType::I32: return "i32"; - case ExprType::I64: return "i64"; - case ExprType::F32: return "f32"; - case ExprType::F64: return "f64"; - case ExprType::I32x4: return "i32x4"; - case ExprType::F32x4: return "f32x4"; - case ExprType::B32x4: return "b32x4"; - case ExprType::Limit:; - } - MOZ_CRASH("bad expression type"); -} - static bool CheckType(FunctionDecoder& f, ExprType actual, ExprType expected) { @@ -129,6 +112,10 @@ DecodeValType(JSContext* cx, Decoder& d, ValType *type) case ValType::F64: break; case ValType::I64: +#ifndef JS_CPU_X64 + return Fail(cx, d, "i64 NYI on this platform"); +#endif + break; case ValType::I32x4: case ValType::F32x4: case ValType::B32x4: @@ -153,6 +140,10 @@ DecodeExprType(JSContext* cx, Decoder& d, ExprType *type) case ExprType::Void: break; case ExprType::I64: +#ifndef JS_CPU_X64 + return Fail(cx, d, "i64 NYI on this platform"); +#endif + break; case ExprType::I32x4: case ExprType::F32x4: case ExprType::B32x4: @@ -376,10 +367,7 @@ DecodeLoadStoreAddress(FunctionDecoder &f) if (!mozilla::IsPowerOfTwo(align)) return f.fail("memory access alignment must be a power of two"); - if (!DecodeExpr(f, ExprType::I32)) - return false; - - return f.fail("NYI: wasm loads and stores"); + return DecodeExpr(f, ExprType::I32); } static bool @@ -423,8 +411,7 @@ DecodeExpr(FunctionDecoder& f, ExprType expected) case Expr::I32Const: return DecodeConstI32(f, expected); case Expr::I64Const: - return f.fail("NYI: i64") && - DecodeConstI64(f, expected); + return DecodeConstI64(f, expected); case Expr::F32Const: return DecodeConstF32(f, expected); case Expr::F64Const: diff --git a/js/src/asmjs/WasmBinary.h b/js/src/asmjs/WasmBinary.h index bf52fe0eec..cbb9215586 100644 --- a/js/src/asmjs/WasmBinary.h +++ b/js/src/asmjs/WasmBinary.h @@ -476,6 +476,15 @@ class Encoder return patchVarU32(offset, patchBits, UINT32_MAX); } + MOZ_WARN_UNUSED_RESULT bool writePatchableVarU8(size_t* offset) { + *offset = bytecode_.length(); + return writeU8(UINT8_MAX); + } + void patchVarU8(size_t offset, uint8_t patchBits) { + MOZ_ASSERT(patchBits < 0x80); + return patchU8(offset, patchBits); + } + MOZ_WARN_UNUSED_RESULT bool writePatchableExpr(size_t* offset) { return writePatchableEnum(offset); } diff --git a/js/src/asmjs/WasmIonCompile.cpp b/js/src/asmjs/WasmIonCompile.cpp index 816c491e50..11c46fd55e 100644 --- a/js/src/asmjs/WasmIonCompile.cpp +++ b/js/src/asmjs/WasmIonCompile.cpp @@ -118,7 +118,8 @@ class FunctionCompiler ins = MConstant::NewAsmJS(alloc(), Int32Value(0), MIRType_Int32); break; case ValType::I64: - MOZ_CRASH("int64"); + ins = MConstant::NewInt64(alloc(), 0); + break; case ValType::F32: ins = MConstant::NewAsmJS(alloc(), Float32Value(0.f), MIRType_Float32); break; @@ -1421,10 +1422,22 @@ static bool EmitExpr(FunctionCompiler&, ExprType, MDefinition**, LabelVector* = static bool EmitExprStmt(FunctionCompiler&, MDefinition**, LabelVector* = nullptr); static bool -EmitLoadArray(FunctionCompiler& f, Scalar::Type scalarType, MDefinition** def) +EmitLoadStoreAddress(FunctionCompiler& f, uint32_t* offset, uint32_t* align, MDefinition** base) { + *offset = f.readVarU32(); + MOZ_ASSERT(*offset == 0, "Non-zero offsets not supported yet"); + + *align = f.readVarU32(); + + return EmitExpr(f, ExprType::I32, base); +} + +static bool +EmitLoad(FunctionCompiler& f, Scalar::Type scalarType, MDefinition** def) +{ + uint32_t offset, align; MDefinition* ptr; - if (!EmitExpr(f, ExprType::I32, &ptr)) + if (!EmitLoadStoreAddress(f, &offset, &align, &ptr)) return false; *def = f.loadHeap(scalarType, ptr); return true; @@ -1433,8 +1446,9 @@ EmitLoadArray(FunctionCompiler& f, Scalar::Type scalarType, MDefinition** def) static bool EmitStore(FunctionCompiler& f, Scalar::Type viewType, MDefinition** def) { + uint32_t offset, align; MDefinition* ptr; - if (!EmitExpr(f, ExprType::I32, &ptr)) + if (!EmitLoadStoreAddress(f, &offset, &align, &ptr)) return false; MDefinition* rhs = nullptr; @@ -1465,8 +1479,9 @@ static bool EmitStoreWithCoercion(FunctionCompiler& f, Scalar::Type rhsType, Scalar::Type viewType, MDefinition **def) { + uint32_t offset, align; MDefinition* ptr; - if (!EmitExpr(f, ExprType::I32, &ptr)) + if (!EmitLoadStoreAddress(f, &offset, &align, &ptr)) return false; MDefinition* rhs = nullptr; @@ -1536,9 +1551,12 @@ static bool EmitAtomicsLoad(FunctionCompiler& f, MDefinition** def) { Scalar::Type viewType = Scalar::Type(f.readU8()); + + uint32_t offset, align; MDefinition* index; - if (!EmitExpr(f, ExprType::I32, &index)) + if (!EmitLoadStoreAddress(f, &offset, &align, &index)) return false; + *def = f.atomicLoadHeap(viewType, index); return true; } @@ -1547,9 +1565,12 @@ static bool EmitAtomicsStore(FunctionCompiler& f, MDefinition** def) { Scalar::Type viewType = Scalar::Type(f.readU8()); + + uint32_t offset, align; MDefinition* index; - if (!EmitExpr(f, ExprType::I32, &index)) + if (!EmitLoadStoreAddress(f, &offset, &align, &index)) return false; + MDefinition* value; if (!EmitExpr(f, ExprType::I32, &value)) return false; @@ -1563,9 +1584,12 @@ EmitAtomicsBinOp(FunctionCompiler& f, MDefinition** def) { Scalar::Type viewType = Scalar::Type(f.readU8()); js::jit::AtomicOp op = js::jit::AtomicOp(f.readU8()); + + uint32_t offset, align; MDefinition* index; - if (!EmitExpr(f, ExprType::I32, &index)) + if (!EmitLoadStoreAddress(f, &offset, &align, &index)) return false; + MDefinition* value; if (!EmitExpr(f, ExprType::I32, &value)) return false; @@ -1577,9 +1601,12 @@ static bool EmitAtomicsCompareExchange(FunctionCompiler& f, MDefinition** def) { Scalar::Type viewType = Scalar::Type(f.readU8()); + + uint32_t offset, align; MDefinition* index; - if (!EmitExpr(f, ExprType::I32, &index)) + if (!EmitLoadStoreAddress(f, &offset, &align, &index)) return false; + MDefinition* oldValue; if (!EmitExpr(f, ExprType::I32, &oldValue)) return false; @@ -1594,9 +1621,12 @@ static bool EmitAtomicsExchange(FunctionCompiler& f, MDefinition** def) { Scalar::Type viewType = Scalar::Type(f.readU8()); + + uint32_t offset, align; MDefinition* index; - if (!EmitExpr(f, ExprType::I32, &index)) + if (!EmitLoadStoreAddress(f, &offset, &align, &index)) return false; + MDefinition* value; if (!EmitExpr(f, ExprType::I32, &value)) return false; @@ -2338,10 +2368,6 @@ EmitSimdOp(FunctionCompiler& f, ExprType type, SimdOperation op, SimdSign sign, return EmitSimdShift(f, type, MSimdShift::lsh, def); case SimdOperation::Fn_shiftRightByScalar: return EmitSimdShift(f, type, MSimdShift::rshForSign(sign), def); - case SimdOperation::Fn_shiftRightArithmeticByScalar: - return EmitSimdShift(f, type, MSimdShift::rsh, def); - case SimdOperation::Fn_shiftRightLogicalByScalar: - return EmitSimdShift(f, type, MSimdShift::ursh, def); #define _CASE(OP) \ case SimdOperation::Fn_##OP: \ return EmitSimdBinaryComp(f, type, MSimdBinaryComp::OP, sign, def); @@ -2774,15 +2800,15 @@ EmitExpr(FunctionCompiler& f, ExprType type, MDefinition** def, LabelVector* may case Expr::I32BitNot: return EmitBitwise(f, def); case Expr::I32LoadMem8S: - return EmitLoadArray(f, Scalar::Int8, def); + return EmitLoad(f, Scalar::Int8, def); case Expr::I32LoadMem8U: - return EmitLoadArray(f, Scalar::Uint8, def); + return EmitLoad(f, Scalar::Uint8, def); case Expr::I32LoadMem16S: - return EmitLoadArray(f, Scalar::Int16, def); + return EmitLoad(f, Scalar::Int16, def); case Expr::I32LoadMem16U: - return EmitLoadArray(f, Scalar::Uint16, def); + return EmitLoad(f, Scalar::Uint16, def); case Expr::I32LoadMem: - return EmitLoadArray(f, Scalar::Int32, def); + return EmitLoad(f, Scalar::Int32, def); case Expr::I32StoreMem8: return EmitStore(f, Scalar::Int8, def); case Expr::I32StoreMem16: @@ -2856,7 +2882,7 @@ EmitExpr(FunctionCompiler& f, ExprType type, MDefinition** def, LabelVector* may case Expr::F32ConvertUI32: return EmitUnary(f, ExprType::I32, def); case Expr::F32LoadMem: - return EmitLoadArray(f, Scalar::Float32, def); + return EmitLoad(f, Scalar::Float32, def); case Expr::F32StoreMem: return EmitStore(f, Scalar::Float32, def); case Expr::F32StoreMemF64: @@ -2904,7 +2930,7 @@ EmitExpr(FunctionCompiler& f, ExprType type, MDefinition** def, LabelVector* may case Expr::F64ConvertUI32: return EmitUnary(f, ExprType::I32, def); case Expr::F64LoadMem: - return EmitLoadArray(f, Scalar::Float64, def); + return EmitLoad(f, Scalar::Float64, def); case Expr::F64StoreMem: return EmitStore(f, Scalar::Float64, def); case Expr::F64StoreMemF32: diff --git a/js/src/asmjs/WasmTypes.h b/js/src/asmjs/WasmTypes.h index 1a141ab2b5..05aaf9e764 100644 --- a/js/src/asmjs/WasmTypes.h +++ b/js/src/asmjs/WasmTypes.h @@ -74,7 +74,7 @@ ToMIRType(ValType vt) { switch (vt) { case ValType::I32: return jit::MIRType_Int32; - case ValType::I64: MOZ_CRASH("NYI"); + case ValType::I64: return jit::MIRType_Int64; case ValType::F32: return jit::MIRType_Float32; case ValType::F64: return jit::MIRType_Double; case ValType::I32x4: return jit::MIRType_Int32x4; @@ -194,6 +194,29 @@ ToMIRType(ExprType et) return IsVoid(et) ? jit::MIRType_None : ToMIRType(ValType(et)); } +static inline const char* +ToCString(ExprType type) +{ + switch (type) { + case ExprType::Void: return "void"; + case ExprType::I32: return "i32"; + case ExprType::I64: return "i64"; + case ExprType::F32: return "f32"; + case ExprType::F64: return "f64"; + case ExprType::I32x4: return "i32x4"; + case ExprType::F32x4: return "f32x4"; + case ExprType::B32x4: return "b32x4"; + case ExprType::Limit:; + } + MOZ_CRASH("bad expression type"); +} + +static inline const char* +ToCString(ValType type) +{ + return ToCString(ToExprType(type)); +} + // The Sig class represents a WebAssembly function signature which takes a list // of value types and returns an expression type. The engine uses two in-memory // representations of the argument Vector's memory (when elements do not fit diff --git a/js/src/builtin/SIMD.cpp b/js/src/builtin/SIMD.cpp index fc903303d4..bc2fc34900 100644 --- a/js/src/builtin/SIMD.cpp +++ b/js/src/builtin/SIMD.cpp @@ -39,19 +39,6 @@ using mozilla::NumberIsInt32; static_assert(unsigned(SimdType::Count) == 12, "sync with TypedObjectConstants.h"); -PropertyName* -js::SimdTypeToName(JSContext* cx, SimdType type) -{ - switch (type) { - case SimdType::Int32x4: return cx->names().Int32x4; - case SimdType::Float32x4: return cx->names().Float32x4; - case SimdType::Bool32x4: return cx->names().Bool32x4; - default: break; - } - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("unexpected SIMD type"); -} - - static bool CheckVectorObject(HandleValue v, SimdType expectedType) { @@ -107,6 +94,30 @@ js::SimdTypeToString(SimdType type) return ""; } +PropertyName* +js::SimdTypeToName(const JSAtomState& atoms, SimdType type) +{ + switch (type) { +#define CASE_(TypeName) case SimdType::TypeName: return atoms.TypeName; + FOR_EACH_SIMD(CASE_) +#undef CASE_ + case SimdType::Count: break; + } + MOZ_CRASH("bad SIMD type"); +} + +bool +js::IsSimdTypeName(const JSAtomState& atoms, const PropertyName* name, SimdType* type) +{ +#define CHECK_(TypeName) if (name == atoms.TypeName) { \ + *type = SimdType::TypeName; \ + return true; \ + } + FOR_EACH_SIMD(CHECK_) +#undef CHECK_ + return false; +} + static inline bool ErrorBadArgs(JSContext* cx) { @@ -701,27 +712,37 @@ template struct Or { static T apply(T l, T r) { return l | r; } }; + // For the following three operators, if the value v we're trying to shift is // such that v << bits can't fit in the int32 range, then we have undefined -// behavior, according to C++11 [expr.shift]p2. +// behavior, according to C++11 [expr.shift]p2. However, left-shifting an +// unsigned type is well-defined. +// +// In C++, shifting by an amount outside the range [0;N-1] is undefined +// behavior. SIMD.js reduces the shift amount modulo the number of bits in a +// lane and has defined behavior for all shift amounts. template struct ShiftLeft { static T apply(T v, int32_t bits) { - return uint32_t(bits) >= sizeof(T) * 8 ? 0 : v << bits; + typedef typename mozilla::MakeUnsigned::Type UnsignedT; + uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8); + return UnsignedT(v) << maskedBits; } }; template struct ShiftRightArithmetic { static T apply(T v, int32_t bits) { typedef typename mozilla::MakeSigned::Type SignedT; - uint32_t maxBits = sizeof(T) * 8; - return SignedT(v) >> (uint32_t(bits) >= maxBits ? maxBits - 1 : bits); + uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8); + return SignedT(v) >> maskedBits; } }; template struct ShiftRightLogical { static T apply(T v, int32_t bits) { - return uint32_t(bits) >= sizeof(T) * 8 ? 0 : uint32_t(v) >> bits; + typedef typename mozilla::MakeUnsigned::Type UnsignedT; + uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8); + return UnsignedT(v) >> maskedBits; } }; diff --git a/js/src/builtin/SIMD.h b/js/src/builtin/SIMD.h index bdc5dc252b..eab6c6e8f7 100644 --- a/js/src/builtin/SIMD.h +++ b/js/src/builtin/SIMD.h @@ -250,8 +250,6 @@ V(subSaturate, (BinaryFunc), 2) \ V(shiftLeftByScalar, (BinaryScalar), 2) \ V(shiftRightByScalar, (BinaryScalar), 2) \ - V(shiftRightArithmeticByScalar, (BinaryScalar), 2) \ - V(shiftRightLogicalByScalar, (BinaryScalar), 2) \ V(xor, (BinaryFunc), 2) #define INT8X16_TERNARY_FUNCTION_LIST(V) \ @@ -301,8 +299,6 @@ V(subSaturate, (BinaryFunc), 2) \ V(shiftLeftByScalar, (BinaryScalar), 2) \ V(shiftRightByScalar, (BinaryScalar), 2) \ - V(shiftRightArithmeticByScalar, (BinaryScalar), 2) \ - V(shiftRightLogicalByScalar, (BinaryScalar), 2) \ V(xor, (BinaryFunc), 2) #define UINT8X16_TERNARY_FUNCTION_LIST(V) \ @@ -352,8 +348,6 @@ V(subSaturate, (BinaryFunc), 2) \ V(shiftLeftByScalar, (BinaryScalar), 2) \ V(shiftRightByScalar, (BinaryScalar), 2) \ - V(shiftRightArithmeticByScalar, (BinaryScalar), 2) \ - V(shiftRightLogicalByScalar, (BinaryScalar), 2) \ V(xor, (BinaryFunc), 2) #define INT16X8_TERNARY_FUNCTION_LIST(V) \ @@ -403,8 +397,6 @@ V(subSaturate, (BinaryFunc), 2) \ V(shiftLeftByScalar, (BinaryScalar), 2) \ V(shiftRightByScalar, (BinaryScalar), 2) \ - V(shiftRightArithmeticByScalar, (BinaryScalar), 2) \ - V(shiftRightLogicalByScalar, (BinaryScalar), 2) \ V(xor, (BinaryFunc), 2) #define UINT16X8_TERNARY_FUNCTION_LIST(V) \ @@ -456,8 +448,6 @@ V(sub, (BinaryFunc), 2) \ V(shiftLeftByScalar, (BinaryScalar), 2) \ V(shiftRightByScalar, (BinaryScalar), 2) \ - V(shiftRightArithmeticByScalar, (BinaryScalar), 2) \ - V(shiftRightLogicalByScalar, (BinaryScalar), 2) \ V(xor, (BinaryFunc), 2) #define INT32X4_TERNARY_FUNCTION_LIST(V) \ @@ -512,8 +502,6 @@ V(sub, (BinaryFunc), 2) \ V(shiftLeftByScalar, (BinaryScalar), 2) \ V(shiftRightByScalar, (BinaryScalar), 2) \ - V(shiftRightArithmeticByScalar, (BinaryScalar), 2) \ - V(shiftRightLogicalByScalar, (BinaryScalar), 2) \ V(xor, (BinaryFunc), 2) #define UINT32X4_TERNARY_FUNCTION_LIST(V) \ @@ -586,9 +574,7 @@ // Bitwise shifts defined on integer SIMD types. #define FOREACH_SHIFT_SIMD_OP(_) \ _(shiftLeftByScalar) \ - _(shiftRightByScalar) \ - _(shiftRightArithmeticByScalar) \ - _(shiftRightLogicalByScalar) + _(shiftRightByScalar) // Unary arithmetic operators defined on numeric SIMD types. #define FOREACH_NUMERIC_SIMD_UNOP(_) \ @@ -1103,7 +1089,12 @@ struct Bool64x2 { } }; -PropertyName* SimdTypeToName(JSContext* cx, SimdType type); +// Get the well known name of the SIMD.* object corresponding to type. +PropertyName* SimdTypeToName(const JSAtomState& atoms, SimdType type); + +// Check if name is the well known name of a SIMD type. +// Returns true and sets *type iff name is known. +bool IsSimdTypeName(const JSAtomState& atoms, const PropertyName* name, SimdType* type); const char* SimdTypeToString(SimdType type); diff --git a/js/src/jit-test/tests/SIMD/shift.js b/js/src/jit-test/tests/SIMD/shift.js index 14fddedea2..8448e52ecb 100644 --- a/js/src/jit-test/tests/SIMD/shift.js +++ b/js/src/jit-test/tests/SIMD/shift.js @@ -4,21 +4,25 @@ setJitCompilerOption("ion.warmup.trigger", 50); function curry(f, arg) { return f.bind(null, arg); } -function binaryLsh(count, v) { if (count>>>0 >= 32) return 0; return (v << count) | 0; } +function binaryLsh(count, v) { count &= 31; return (v << count) | 0; } function lsh(count) { return curry(binaryLsh, count); } -function binaryRsh(count, v) { if (count>>>0 >= 32) count = 31; return (v >> count) | 0; } +function binaryRsh(count, v) { count &= 31; return (v >> count) | 0; } function rsh(count) { return curry(binaryRsh, count); } -function binaryUrsh(count, v) { if (count>>>0 >= 32) return 0; return (v >>> count) | 0; } +function binaryUlsh(count, v) { count &= 31; return (v << count) >>> 0; } +function ulsh(count) { return curry(binaryUlsh, count); } + +function binaryUrsh(count, v) { count &= 31; return v >>> count; } function ursh(count) { return curry(binaryUrsh, count); } function f() { var v = SIMD.Int32x4(1, 2, -3, 4); + var u = SIMD.Uint32x4(1, 0x55005500, -3, 0xaa00aa00); var a = [1, 2, -3, 4]; - var zeros = [0,0,0,0]; + var b = [1, 0x55005500, -3, 0xaa00aa00]; - var shifts = [-1, 0, 1, 31, 32]; + var shifts = [-2, -1, 0, 1, 31, 32, 33]; var r; for (var i = 0; i < 150; i++) { @@ -29,33 +33,40 @@ function f() { assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, 2), a.map(lsh(2))); assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, 31), a.map(lsh(31))); assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, 32), a.map(lsh(32))); - - assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, -1), a.map(rsh(31))); - assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, 0), a.map(rsh(0))); - assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, 1), a.map(rsh(1))); - assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, 2), a.map(rsh(2))); - assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, 31), a.map(rsh(31))); - assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, 32), a.map(rsh(31))); - - assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, -1), a.map(ursh(-1))); - assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 0), a.map(ursh(0))); - assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 1), a.map(ursh(1))); - assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 2), a.map(ursh(2))); - assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 31), a.map(ursh(31))); - assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 32), a.map(ursh(32))); + assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, 33), a.map(lsh(33))); assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, -1), a.map(rsh(31))); assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 0), a.map(rsh(0))); assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 1), a.map(rsh(1))); assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 2), a.map(rsh(2))); assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 31), a.map(rsh(31))); - assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 32), a.map(rsh(31))); + assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 32), a.map(rsh(32))); + assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 33), a.map(rsh(33))); + + assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, -1), b.map(ulsh(-1))); + assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 0), b.map(ulsh(0))); + assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 1), b.map(ulsh(1))); + assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 2), b.map(ulsh(2))); + assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 31), b.map(ulsh(31))); + assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 32), b.map(ulsh(32))); + assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 33), b.map(ulsh(33))); + + assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, -1), b.map(ursh(-1))); + assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 0), b.map(ursh(0))); + assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 1), b.map(ursh(1))); + assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 2), b.map(ursh(2))); + assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 31), b.map(ursh(31))); + assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 32), b.map(ursh(32))); + assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 33), b.map(ursh(33))); // Non constant shift counts var c = shifts[i % shifts.length]; + assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, c), a.map(lsh(c))); - assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, c), a.map(rsh(c))); - assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, c), a.map(ursh(c))); + assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, c), a.map(rsh(c))); + + assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, c), b.map(ulsh(c))); + assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, c), b.map(ursh(c))); } return r; } diff --git a/js/src/jit-test/tests/asm.js/testSIMD.js b/js/src/jit-test/tests/asm.js/testSIMD.js index ee9fb51fcb..e9fbfc1e41 100644 --- a/js/src/jit-test/tests/asm.js/testSIMD.js +++ b/js/src/jit-test/tests/asm.js/testSIMD.js @@ -16,6 +16,15 @@ const CI32 = 'var ci4 = i4.check;' const I32A = 'var i4a = i4.add;' const I32S = 'var i4s = i4.sub;' const I32M = 'var i4m = i4.mul;' +const I32U32 = 'var i4u4 = i4.fromUint32x4Bits;' + +const U32 = 'var u4 = glob.SIMD.Uint32x4;' +const CU32 = 'var cu4 = u4.check;' +const U32A = 'var u4a = u4.add;' +const U32S = 'var u4s = u4.sub;' +const U32M = 'var u4m = u4.mul;' +const U32I32 = 'var u4i4 = u4.fromInt32x4Bits;' + const F32 = 'var f4 = glob.SIMD.Float32x4;' const CF32 = 'var cf4 = f4.check;' const F32A = 'var f4a = f4.add;' @@ -27,6 +36,7 @@ const B32 = 'var b4 = glob.SIMD.Bool32x4;' const CB32 = 'var cb4 = b4.check;' const EXTI4 = 'var e = i4.extractLane;' +const EXTU4 = 'var e = u4.extractLane;' const EXTF4 = 'var e = f4.extractLane;' const EXTB4 = 'var e = b4.extractLane;' @@ -36,6 +46,7 @@ const ALLB4 = 'var allt=b4.allTrue;' const INT32_MAX = Math.pow(2, 31) - 1; const INT32_MIN = INT32_MAX + 1 | 0; +const UINT32_MAX = Math.pow(2, 32) - 1; const assertEqFFI = {assertEq:assertEq}; @@ -46,6 +57,15 @@ function CheckI4(header, code, expected) { assertEqX4(observed, expected); } +function CheckU4(header, code, expected) { + // code needs to contain a local called x. + header = USE_ASM + U32 + CU32 + EXTU4 + I32 + CI32 + I32U32 + header; + var observed = asmLink(asmCompile('glob', header + ';function f() {' + code + ';return ci4(i4u4(x))} return f'), this)(); + // We can't return an unsigned SIMD type. Return Int32x4, convert to unsigned here. + observed = SIMD.Uint32x4.fromInt32x4Bits(observed) + assertEqX4(observed, expected); +} + function CheckF4(header, code, expected) { // code needs to contain a local called x header = USE_ASM + F32 + CF32 + EXTF4 + header; @@ -176,6 +196,7 @@ assertAsmTypeFail('glob', USE_ASM + "function f() {var x=42; return x.signMask;} assertAsmTypeFail('glob', USE_ASM + "function f() {var x=42.; return x.signMask;} return f"); assertAsmTypeFail('glob', USE_ASM + FROUND + "function f() {var x=f32(42.); return x.signMask;} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + 'function f() { var x=i4(1,2,3,4); return x.signMask | 0 } return f'); +assertAsmTypeFail('glob', USE_ASM + U32 + 'function f() { var x=u4(1,2,3,4); return x.signMask | 0 } return f'); assertAsmTypeFail('glob', USE_ASM + F32 + FROUND + 'var Infinity = glob.Infinity; function f() { var x=f4(0,0,0,0); x=f4(f32(1), f32(-13.37), f32(42), f32(-Infinity)); return x.signMask | 0 } return f'); // Check lane extraction. @@ -186,6 +207,11 @@ function CheckLanes(innerBody, type, expected) { coerceBefore = ''; coerceAfter = '|0'; extractLane = 'ei'; + } else if (type === SIMD.Uint32x4) { + // Coerce Uint32 lanes to double so they can be legally returned. + coerceBefore = '+'; + coerceAfter = ''; + extractLane = 'eu'; } else if (type === SIMD.Float32x4) { coerceBefore = '+'; coerceAfter = ''; @@ -201,9 +227,11 @@ function CheckLanes(innerBody, type, expected) { var lane = i; var laneCheckCode = `"use asm"; var i4=glob.SIMD.Int32x4; + var u4=glob.SIMD.Uint32x4; var f4=glob.SIMD.Float32x4; var b4=glob.SIMD.Bool32x4; var ei=i4.extractLane; + var eu=u4.extractLane; var ef=f4.extractLane; var eb=b4.extractLane; function f() {${innerBody}; return ${coerceBefore}${extractLane}(x, ${lane})${coerceAfter} } @@ -212,6 +240,7 @@ function CheckLanes(innerBody, type, expected) { } } function CheckLanesI4(innerBody, expected) { return CheckLanes(innerBody, SIMD.Int32x4, expected); } +function CheckLanesU4(innerBody, expected) { return CheckLanes(innerBody, SIMD.Uint32x4, expected); } function CheckLanesF4(innerBody, expected) { return CheckLanes(innerBody, SIMD.Float32x4, expected); } function CheckLanesB4(innerBody, expected) { return CheckLanes(innerBody, SIMD.Bool32x4, expected); } @@ -222,6 +251,13 @@ CheckLanesI4('var x=i4(1,2,3,4); var y=i4(5,6,7,8)', [1,2,3,4]); CheckLanesI4('var a=1; var b=i4(9,8,7,6); var c=13.37; var x=i4(1,2,3,4); var y=i4(5,6,7,8)', [1,2,3,4]); CheckLanesI4('var y=i4(5,6,7,8); var x=i4(1,2,3,4)', [1,2,3,4]); +CheckLanesU4('var x=u4(0,0,0,0);', [0,0,0,0]); +CheckLanesU4('var x=u4(1,2,3,4000000000);', [1,2,3,4000000000]); +CheckLanesU4('var x=u4(' + INT32_MIN + ',2,3,' + UINT32_MAX + ')', [INT32_MIN>>>0,2,3,UINT32_MAX]); +CheckLanesU4('var x=u4(1,2,3,4); var y=u4(5,6,7,8)', [1,2,3,4]); +CheckLanesU4('var a=1; var b=u4(9,8,7,6); var c=13.37; var x=u4(1,2,3,4); var y=u4(5,6,7,8)', [1,2,3,4]); +CheckLanesU4('var y=u4(5,6,7,8); var x=u4(1,2,3,4)', [1,2,3,4]); + CheckLanesF4('var x=f4(' + INT32_MAX + ', 2, 3, ' + INT32_MIN + ')', [INT32_MAX, 2, 3, INT32_MIN]); CheckLanesF4('var x=f4(' + (INT32_MAX + 1) + ', 2, 3, 4)', [INT32_MAX + 1, 2, 3, 4]); CheckLanesF4('var x=f4(1.3, 2.4, 3.5, 98.76)', [1.3, 2.4, 3.5, 98.76]); @@ -253,6 +289,10 @@ CheckI4('', 'var x=i4(1,2,3,4); x=i4(5,6,7,8)', [5, 6, 7, 8]); CheckI4('', 'var x=i4(1,2,3,4); var c=6; x=i4(5,c|0,7,8)', [5, 6, 7, 8]); CheckI4('', 'var x=i4(8,7,6,5); x=i4(e(x,3)|0,e(x,2)|0,e(x,1)|0,e(x,0)|0)', [5, 6, 7, 8]); +CheckU4('', 'var x=u4(1,2,3,4); x=u4(5,6,7,4000000000)', [5, 6, 7, 4000000000]); +CheckU4('', 'var x=u4(1,2,3,4); var c=6; x=u4(5,c|0,7,8)', [5, 6, 7, 8]); +CheckU4('', 'var x=u4(8,7,6,5); x=u4(e(x,3)|0,e(x,2)|0,e(x,1)|0,e(x,0)|0)', [5, 6, 7, 8]); + assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4; x=f4(1,2,3,c);} return f"); assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4; x=f4(1.,2.,3.,c);} return f"); assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4.; x=f4(1,2,3,c);} return f"); @@ -281,6 +321,8 @@ assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "function f() {var x=f4(1,2,3,4); var y=i4(1,2,3,4); x=1?x:y;} return f"); assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "function f() {var x=f4(1,2,3,4); var y=i4(1,2,3,4); x=1?y:y;} return f"); assertAsmTypeFail('glob', USE_ASM + B32 + I32 + "function f() {var x=b4(1,2,3,4); var y=i4(1,2,3,4); x=1?y:y;} return f"); +assertAsmTypeFail('glob', USE_ASM + U32 + I32 + "function f() {var x=u4(1,2,3,4); var y=i4(1,2,3,4); x=1?y:y;} return f"); +assertAsmTypeFail('glob', USE_ASM + U32 + I32 + "function f() {var x=i4(1,2,3,4); var y=u4(1,2,3,4); x=1?y:y;} return f"); CheckF4('', 'var x=f4(1,2,3,4); var y=f4(4,3,2,1); x=3?y:x', [4, 3, 2, 1]); assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + "function f(x) {x=x|0; var v=f4(1,2,3,4); var w=f4(5,6,7,8); return cf4(x?w:v);} return f"), this)(1), [5,6,7,8]); @@ -292,6 +334,10 @@ assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(x) {x=x assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(v) {v=ci4(v); var w=i4(5,6,7,8); return ci4(4?w:v);} return f"), this)(SIMD.Int32x4(1,2,3,4)), [5,6,7,8]); assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(v, x) {v=ci4(v); x=x|0; var w=i4(5,6,7,8); return ci4(x?w:v);} return f"), this)(SIMD.Int32x4(1,2,3,4), 0), [1,2,3,4]); +// Unsigned SIMD types can't be function arguments or return values. +assertAsmTypeFail('glob', USE_ASM + U32 + CU32 + "function f(x) {x=cu4(x);} return f"); +assertAsmTypeFail('glob', USE_ASM + U32 + CU32 + "function f() {x=u4(0,0,0,0); return cu4(x);} return f"); + // 1.3.4 Return values assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f() {var x=1; return ci4(x)} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f() {var x=1; return ci4(x + x)} return f"); @@ -395,11 +441,15 @@ assertAsmTypeFail('glob', USE_ASM + F32 + "var g=f4(1., 2., 3., 4.); var f32=glo assertAsmTypeFail('glob', USE_ASM + F32 + I32 + CI32 + "var g=f4(1., 2., 3., 4.); function f() {var x=i4(1,2,3,4); x=ci4(g);} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CF32 + "var g=i4(1,2,3,4); function f() {var x=f4(1.,2.,3.,4.); x=cf4(g);} return f"); +assertAsmTypeFail('glob', USE_ASM + U32 + I32 + CI32 + "var g=u4(1,2,3,4); function f() {var x=i4(1,2,3,4); x=ci4(g);} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + "var g=0; function f() {var x=i4(1,2,3,4); x=g|0;} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + "var g=0.; function f() {var x=i4(1,2,3,4); x=+g;} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + "var f32=glob.Math.fround; var g=f32(0.); function f() {var x=i4(1,2,3,4); x=f32(g);} return f"); +// Unsigned SIMD globals are not allowed. +assertAsmTypeFail('glob', USE_ASM + U32 + "var g=u4(0,0,0,0); function f() {var x=u4(1,2,3,4); x=g;} return f"); + assertAsmTypeFail('glob', USE_ASM + F32 + "var g=0; function f() {var x=f4(0.,0.,0.,0.); x=g|0;} return f"); assertAsmTypeFail('glob', USE_ASM + F32 + "var g=0.; function f() {var x=f4(0.,0.,0.,0.); x=+g;} return f"); assertAsmTypeFail('glob', USE_ASM + F32 + "var f32=glob.Math.fround; var g=f32(0.); function f() {var x=f4(0.,0.,0.,0.); x=f32(g);} return f"); @@ -447,6 +497,9 @@ assertEq(SIMD.Int32x4.extractLane(Int32x4, 3), 4); for (var v of [1, {}, "totally legit SIMD variable", SIMD.Float32x4(1,2,3,4)]) assertCaught(asmCompile('glob', 'ffi', USE_ASM + I32 + CI32 + "var g=ci4(ffi.g); function f() {return ci4(g)} return f"), this, {g: v}); +// Unsigned SIMD globals are not allowed. +assertAsmTypeFail('glob', 'ffi', USE_ASM + U32 + CU32 + "var g=cu4(ffi.g); function f() {} return f"); + var Float32x4 = asmLink(asmCompile('glob', 'ffi', USE_ASM + F32 + CF32 + "var g=cf4(ffi.g); function f() {return cf4(g)} return f"), this, {g: SIMD.Float32x4(1,2,3,4)})(); assertEq(SIMD.Float32x4.extractLane(Float32x4, 0), 1); assertEq(SIMD.Float32x4.extractLane(Float32x4, 1), 2); @@ -492,6 +545,8 @@ assertAsmTypeFail('glob', USE_ASM + "var g = 3; var add = g.add; return {}"); assertAsmTypeFail('glob', USE_ASM + I32 + "var func = i4.doTheHarlemShake; return {}"); assertAsmTypeFail('glob', USE_ASM + I32 + "var div = i4.div; return {}"); assertAsmTypeFail('glob', USE_ASM + "var f32 = glob.Math.fround; var i4a = f32.add; return {}"); +// Operation exists, but in a different type. +assertAsmTypeFail('glob', USE_ASM + I32 + "var func = i4.fromUint32x4; return {}"); // 2.2 Linking assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + I32 + I32A + "function f() {} return f"), {}); @@ -519,6 +574,7 @@ assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(1,2,3,4 assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(1,2,3,4); var y=4; x=i4a(x, y);} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(0,0,0,0); var y=4; x=i4a(y, y);} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(0,0,0,0); var y=4; y=i4a(x, x);} return f"); +assertAsmTypeFail('glob', USE_ASM + I32 + I32A + U32 + "function f() {var x=i4(0,0,0,0); var y=u4(1,2,3,4); y=i4a(x, y);} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); x=i4a(x, y);} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); y=i4a(x, y);} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); y=i4a(x, x);} return f"); @@ -535,6 +591,10 @@ CheckI4(I32A, 'var x=i4(1,2,3,4); x=i4a(x,x)', [2,4,6,8]); CheckI4(I32A, 'var x=i4(' + INT32_MAX + ',2,3,4); var y=i4(1,1,0,3); x=i4a(x,y)', [INT32_MIN,3,3,7]); CheckI4(I32A, 'var x=i4(' + INT32_MAX + ',2,3,4); var y=i4(1,1,0,3); x=ci4(i4a(x,y))', [INT32_MIN,3,3,7]); +CheckU4(U32A, 'var z=u4(1,2,3,4); var y=u4(0,1,0,3); var x=u4(0,0,0,0); x=u4a(z,y)', [1,3,3,7]); +CheckU4(U32A, 'var x=u4(2,3,4,5); var y=u4(0,1,0,3); x=u4a(x,y)', [2,4,4,8]); +CheckU4(U32A, 'var x=u4(1,2,3,4); x=u4a(x,x)', [2,4,6,8]); + CheckF4(F32A, 'var x=f4(1,2,3,4); x=f4a(x,x)', [2,4,6,8]); CheckF4(F32A, 'var x=f4(1,2,3,4); var y=f4(4,3,5,2); x=f4a(x,y)', [5,5,8,6]); CheckF4(F32A, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4a(x,y)', [Math.fround(13.37) + 4,5,8,6]); @@ -547,6 +607,12 @@ CheckI4(I32S, 'var x=i4(1,2,3,4); x=i4s(x,x)', [0,0,0,0]); CheckI4(I32S, 'var x=i4(' + INT32_MIN + ',2,3,4); var y=i4(1,1,0,3); x=i4s(x,y)', [INT32_MAX,1,3,1]); CheckI4(I32S, 'var x=i4(' + INT32_MIN + ',2,3,4); var y=i4(1,1,0,3); x=ci4(i4s(x,y))', [INT32_MAX,1,3,1]); +CheckU4(U32S, 'var x=u4(1,2,3,4); var y=u4(-1,1,0,2); x=u4s(x,y)', [2,1,3,2]); +CheckU4(U32S, 'var x=u4(5,4,3,2); var y=u4(1,2,3,4); x=u4s(x,y)', [4,2,0,-2>>>0]); +CheckU4(U32S, 'var x=u4(1,2,3,4); x=u4s(x,x)', [0,0,0,0]); +CheckU4(U32S, 'var x=u4(' + INT32_MIN + ',2,3,4); var y=u4(1,1,0,3); x=u4s(x,y)', [INT32_MAX,1,3,1]); +CheckU4(U32S, 'var x=u4(' + INT32_MIN + ',2,3,4); var y=u4(1,1,0,3); x=cu4(u4s(x,y))', [INT32_MAX,1,3,1]); + CheckF4(F32S, 'var x=f4(1,2,3,4); x=f4s(x,x)', [0,0,0,0]); CheckF4(F32S, 'var x=f4(1,2,3,4); var y=f4(4,3,5,2); x=f4s(x,y)', [-3,-1,-2,2]); CheckF4(F32S, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4s(x,y)', [Math.fround(13.37) - 4,-1,-2,2]); @@ -603,6 +669,16 @@ function CheckUnaryI4(op, checkFunc) { } } +function CheckUnaryU4(op, checkFunc) { + var _ = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32U32 + U32 + U32I32 + + 'var op=u4.' + op + '; function f(x){x=ci4(x); return ci4(i4u4(op(u4i4(x)))); } return f'), this); + return function(input) { + var simd = SIMD.Int32x4(input[0], input[1], input[2], input[3]); + var res = SIMD.Uint32x4.fromInt32x4Bits(_(simd)); + assertEqX4(res, input.map(checkFunc).map(function(x) { return x >>> 0 })); + } +} + function CheckUnaryB4(op, checkFunc) { var _ = asmLink(asmCompile('glob', USE_ASM + B32 + CB32 + 'var op=b4.' + op + '; function f(x){x=cb4(x); return cb4(op(x)); } return f'), this); return function(input) { @@ -614,6 +690,9 @@ function CheckUnaryB4(op, checkFunc) { CheckUnaryI4('neg', function(x) { return -x })([1, -2, INT32_MIN, INT32_MAX]); CheckUnaryI4('not', function(x) { return ~x })([1, -2, INT32_MIN, INT32_MAX]); +CheckUnaryU4('neg', function(x) { return -x })([1, -2, INT32_MIN, INT32_MAX]); +CheckUnaryU4('not', function(x) { return ~x })([1, -2, INT32_MIN, INT32_MAX]); + var CheckNotB = CheckUnaryB4('not', function(x) { return !x }); CheckNotB([true, false, true, true]); CheckNotB([true, true, true, true]); @@ -714,6 +793,12 @@ CheckI4(RLI, 'var x = i4(1,2,3,4); x = r(x, 1, 42);', [1, 42, 3, 4]); CheckI4(RLI, 'var x = i4(1,2,3,4); x = r(x, 2, 42);', [1, 2, 42, 4]); CheckI4(RLI, 'var x = i4(1,2,3,4); x = r(x, 3, 42);', [1, 2, 3, 42]); +const RLU = 'var r = u4.replaceLane;'; +CheckU4(RLU, 'var x = u4(1,2,3,4); x = r(x, 0, 42);', [42, 2, 3, 4]); +CheckU4(RLU, 'var x = u4(1,2,3,4); x = r(x, 1, 42);', [1, 42, 3, 4]); +CheckU4(RLU, 'var x = u4(1,2,3,4); x = r(x, 2, 42);', [1, 2, 42, 4]); +CheckU4(RLU, 'var x = u4(1,2,3,4); x = r(x, 3, 42);', [1, 2, 3, 42]); + const RLB = 'var r = b4.replaceLane;'; CheckB4(RLB, 'var x = b4(1,1,0,0); x = r(x, 0, 0);', [false, true, false, false]); CheckB4(RLB, 'var x = b4(1,1,0,0); x = r(x, 1, 0);', [true, false, false, false]); @@ -756,6 +841,37 @@ CheckB4(I32+GEI32, 'var x=b4(0,0,0,0); var a=i4(1,2,3,4); var b=i4(-1,1,0,2); x CheckB4(I32+GEI32, 'var x=b4(0,0,0,0); var a=i4(-1,1,0,2); var b=i4(1,2,3,4); x=ge(a,b)', [F, F, F, F]); CheckB4(I32+GEI32, 'var x=b4(0,0,0,0); var a=i4(1,0,3,4); var b=i4(1,1,7,0); x=ge(a,b)', [T, F, F, T]); +const EQU32 = 'var eq = u4.equal'; +const NEU32 = 'var ne = u4.notEqual'; +const LTU32 = 'var lt = u4.lessThan;'; +const LEU32 = 'var le = u4.lessThanOrEqual'; +const GTU32 = 'var gt = u4.greaterThan;'; +const GEU32 = 'var ge = u4.greaterThanOrEqual'; + +CheckB4(U32+EQU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=eq(a,b)', [F, F, F, F]); +CheckB4(U32+EQU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=eq(a,b)', [F, F, F, F]); +CheckB4(U32+EQU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=eq(a,b)', [T, F, F, F]); + +CheckB4(U32+NEU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=ne(a,b)', [T, T, T, T]); +CheckB4(U32+NEU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=ne(a,b)', [T, T, T, T]); +CheckB4(U32+NEU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=ne(a,b)', [F, T, T, T]); + +CheckB4(U32+LTU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=lt(a,b)', [T, F, F, F]); +CheckB4(U32+LTU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=lt(a,b)', [F, T, T, T]); +CheckB4(U32+LTU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=lt(a,b)', [F, T, T, F]); + +CheckB4(U32+LEU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=le(a,b)', [T, F, F, F]); +CheckB4(U32+LEU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=le(a,b)', [F, T, T, T]); +CheckB4(U32+LEU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=le(a,b)', [T, T, T, F]); + +CheckB4(U32+GTU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=gt(a,b)', [F, T, T, T]); +CheckB4(U32+GTU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=gt(a,b)', [T, F, F, F]); +CheckB4(U32+GTU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=gt(a,b)', [F, F, F, T]); + +CheckB4(U32+GEU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=ge(a,b)', [F, T, T, T]); +CheckB4(U32+GEU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=ge(a,b)', [T, F, F, F]); +CheckB4(U32+GEU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=ge(a,b)', [T, F, F, T]); + const LTF32 = 'var lt=f4.lessThan;'; const LEF32 = 'var le=f4.lessThanOrEqual;'; const GTF32 = 'var gt=f4.greaterThan;'; @@ -808,8 +924,13 @@ assertEq(f(SIMD.Int32x4(1,2,3,5)), 0); // Conversions operators const CVTIF = 'var cvt=f4.fromInt32x4;'; const CVTFI = 'var cvt=i4.fromFloat32x4;'; +const CVTUF = 'var cvt=f4.fromUint32x4;'; +const CVTFU = 'var cvt=u4.fromFloat32x4;'; assertAsmTypeFail('glob', USE_ASM + I32 + "var cvt=i4.fromInt32x4; return {}"); +assertAsmTypeFail('glob', USE_ASM + I32 + "var cvt=i4.fromUint32x4; return {}"); +assertAsmTypeFail('glob', USE_ASM + U32 + "var cvt=u4.fromInt32x4; return {}"); +assertAsmTypeFail('glob', USE_ASM + U32 + "var cvt=u4.fromUint32x4; return {}"); assertAsmTypeFail('glob', USE_ASM + F32 + "var cvt=f4.fromFloat32x4; return {}"); assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIF + "function f() {var x=i4(1,2,3,4); x=cvt(x);} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIF + "function f() {var x=f4(1,2,3,4); x=cvt(x);} return f"); @@ -818,6 +939,11 @@ var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + CI32 + CVTIF + ' assertEqX4(f(SIMD.Int32x4(1,2,3,4)), [1, 2, 3, 4]); assertEqX4(f(SIMD.Int32x4(0,INT32_MIN,INT32_MAX,-1)), [0, Math.fround(INT32_MIN), Math.fround(INT32_MAX), -1]); +var f = asmLink(asmCompile('glob', USE_ASM + I32 + U32 + U32I32 + F32 + CF32 + CI32 + CVTUF + + 'function f(x){x=ci4(x); var y=f4(0,0,0,0); y=cvt(u4i4(x)); return cf4(y);} return f'), this); +assertEqX4(f(SIMD.Int32x4(1,2,3,4)), [1, 2, 3, 4]); +assertEqX4(f(SIMD.Int32x4(0,INT32_MIN,INT32_MAX,-1)), [0, Math.fround(INT32_MAX+1), Math.fround(INT32_MAX), Math.fround(UINT32_MAX)]); + var f = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + F32 + CF32 + CVTFI + 'function f(x){x=cf4(x); var y=i4(0,0,0,0); y=cvt(x); return ci4(y);} return f'), this); assertEqX4(f(SIMD.Float32x4(1,2,3,4)), [1, 2, 3, 4]); // Test that INT32_MIN (exactly representable as an float32) and the first @@ -832,6 +958,20 @@ assertThrowsInstanceOf(() => f(SIMD.Float32x4(NaN, 0, 0, 0)), RangeError); assertThrowsInstanceOf(() => f(SIMD.Float32x4(Infinity, 0, 0, 0)), RangeError); assertThrowsInstanceOf(() => f(SIMD.Float32x4(-Infinity, 0, 0, 0)), RangeError); +var f = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + U32 + I32U32 + F32 + CF32 + CVTFU + + 'function f(x){x=cf4(x); var y=u4(0,0,0,0); y=cvt(x); return ci4(i4u4(y));} return f'), this); +assertEqX4(f(SIMD.Float32x4(1,2,3,4)), [1, 2, 3, 4]); +// TODO: Test negative numbers > -1. They should truncate to 0. See https://github.com/tc39/ecmascript_simd/issues/315 +assertEqX4(SIMD.Uint32x4.fromInt32x4Bits(f(SIMD.Float32x4(0xffffff00, INT32_MAX+1, -0, 0))), + [0xffffff00, INT32_MAX+1, 0, 0].map(Math.fround)); +// Test boundaries: -1 or less. +assertThrowsInstanceOf(() => f(SIMD.Float32x4(-1, 0, 0, 0)), RangeError); +assertThrowsInstanceOf(() => f(SIMD.Float32x4(Math.pow(2, 32), 0, 0, 0)), RangeError); +// Special values +assertThrowsInstanceOf(() => f(SIMD.Float32x4(NaN, 0, 0, 0)), RangeError); +assertThrowsInstanceOf(() => f(SIMD.Float32x4(Infinity, 0, 0, 0)), RangeError); +assertThrowsInstanceOf(() => f(SIMD.Float32x4(-Infinity, 0, 0, 0)), RangeError); + // Cast operators const CVTIFB = 'var cvt=f4.fromInt32x4Bits;'; const CVTFIB = 'var cvt=i4.fromFloat32x4Bits;'; @@ -886,6 +1026,14 @@ CheckI4(ANDI32, 'var x=i4(42,1337,-1,13); var y=i4(2, 4, 7, 15); x=andd(x,y)', [ CheckI4(ORI32, ' var x=i4(42,1337,-1,13); var y=i4(2, 4, 7, 15); x=orr(x,y)', [42 | 2, 1337 | 4, -1 | 7, 13 | 15]); CheckI4(XORI32, 'var x=i4(42,1337,-1,13); var y=i4(2, 4, 7, 15); x=xorr(x,y)', [42 ^ 2, 1337 ^ 4, -1 ^ 7, 13 ^ 15]); +const ANDU32 = 'var andd=u4.and;'; +const ORU32 = 'var orr=u4.or;'; +const XORU32 = 'var xorr=u4.xor;'; + +CheckU4(ANDU32, 'var x=u4(42,1337,-1,13); var y=u4(2, 4, 7, 15); x=andd(x,y)', [42 & 2, 1337 & 4, (-1 & 7) >>> 0, 13 & 15]); +CheckU4(ORU32, ' var x=u4(42,1337,-1,13); var y=u4(2, 4, 7, 15); x=orr(x,y)', [42 | 2, 1337 | 4, (-1 | 7) >>> 0, 13 | 15]); +CheckU4(XORU32, 'var x=u4(42,1337,-1,13); var y=u4(2, 4, 7, 15); x=xorr(x,y)', [42 ^ 2, 1337 ^ 4, (-1 ^ 7) >>> 0, 13 ^ 15]); + const ANDB32 = 'var andd=b4.and;'; const ORB32 = 'var orr=b4.or;'; const XORB32 = 'var xorr=b4.xor;'; @@ -908,8 +1056,6 @@ assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + NOTF32 + 'function f() {var x=f // Logical ops const LSHI = 'var lsh=i4.shiftLeftByScalar;' const RSHI = 'var rsh=i4.shiftRightByScalar;' -const ARSHI = 'var arsh=i4.shiftRightArithmeticByScalar;' -const URSHI = 'var ursh=i4.shiftRightLogicalByScalar;' assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return ci4(lsh(x,f32(42)));} return f"); assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return ci4(lsh(x,42));} return f"); @@ -919,33 +1065,49 @@ assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + FROUND + LSHI + "function f() { var input = 'i4(0, 1, ' + INT32_MIN + ', ' + INT32_MAX + ')'; var vinput = [0, 1, INT32_MIN, INT32_MAX]; -// TODO: What to do for masks > 31? Should we keep only the five low bits of -// the mask (JS) or not (x86)? -// Behave as x86 for now, fix when more broadly specified. See also bug 1068028 -function Lsh(i) { if (i > 31) return () => 0; return function(x) { return (x << i) | 0 } } -function Rsh(i) { if (i > 31) return (x) => (x<0)?-1:0; return function(x) { return (x >> i) | 0 } } -function Arsh(i) { if (i > 31) return (x) => (x<0)?-1:0; return function(x) { return (x >> i) | 0 } } -function Ursh(i) { if (i > 31) return () => 0; return function(x) { return (x >>> i) | 0 } } +function Lsh(i) { return function(x) { return (x << (i & 31)) | 0 } } +function Rsh(i) { return function(x) { return (x >> (i & 31)) | 0 } } var asmLsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + LSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(lsh(v, x+y))} return f;'), this) var asmRsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + RSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(rsh(v, x+y))} return f;'), this) -var asmArsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + ARSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(arsh(v, x+y))} return f;'), this) -var asmUrsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + URSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(ursh(v, x+y))} return f;'), this) for (var i = 1; i < 64; i++) { CheckI4(LSHI, 'var x=' + input + '; x=lsh(x, ' + i + ')', vinput.map(Lsh(i))); CheckI4(RSHI, 'var x=' + input + '; x=rsh(x, ' + i + ')', vinput.map(Rsh(i))); - CheckI4(ARSHI, 'var x=' + input + '; x=arsh(x, ' + i + ')', vinput.map(Arsh(i))); - CheckI4(URSHI, 'var x=' + input + '; x=ursh(x, ' + i + ')', vinput.map(Ursh(i))); assertEqX4(asmLsh(i, 3), vinput.map(Lsh(i + 3))); assertEqX4(asmRsh(i, 3), vinput.map(Rsh(i + 3))); - assertEqX4(asmArsh(i, 3), vinput.map(Arsh(i + 3))); - assertEqX4(asmUrsh(i, 3), vinput.map(Ursh(i + 3))); +} + +// Same thing for Uint32x4. +const LSHU = 'var lsh=u4.shiftLeftByScalar;' +const RSHU = 'var rsh=u4.shiftRightByScalar;' + +input = 'u4(0, 1, 0x80008000, ' + INT32_MAX + ')'; +vinput = [0, 1, 0x80008000, INT32_MAX]; + +function uLsh(i) { return function(x) { return (x << (i & 31)) >>> 0 } } +function uRsh(i) { return function(x) { return (x >>> (i & 31)) } } + +// Need to bitcast to Int32x4 before returning result. +asmLsh = asmLink(asmCompile('glob', USE_ASM + U32 + CU32 + LSHU + I32 + CI32 + I32U32 + + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(i4u4(lsh(v, x+y)));} return f;'), this) +asmRsh = asmLink(asmCompile('glob', USE_ASM + U32 + CU32 + RSHU + I32 + CI32 + I32U32 + + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(i4u4(rsh(v, x+y)));} return f;'), this) + +for (var i = 1; i < 64; i++) { + // Constant shifts. + CheckU4(LSHU, 'var x=' + input + '; x=lsh(x, ' + i + ')', vinput.map(uLsh(i))); + CheckU4(RSHU, 'var x=' + input + '; x=rsh(x, ' + i + ')', vinput.map(uRsh(i))); + + // Dynamically computed shifts. The asm function returns a Int32x4. + assertEqX4(SIMD.Uint32x4.fromInt32x4Bits(asmLsh(i, 3)), vinput.map(uLsh(i + 3))); + assertEqX4(SIMD.Uint32x4.fromInt32x4Bits(asmRsh(i, 3)), vinput.map(uRsh(i + 3))); } // Select const I32SEL = 'var i4sel = i4.select;' +const U32SEL = 'var u4sel = u4.select;' const F32SEL = 'var f4sel = f4.select;' assertAsmTypeFail('glob', USE_ASM + I32 + F32 + B32 + CI32 + I32SEL + "function f() {var x=f4(1,2,3,4); return ci4(i4sel(x,x,x));} return f"); @@ -975,8 +1137,14 @@ assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + B32 + F32 + CF32 + F32SEL assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + B32 + F32 + CF32 + F32SEL + "function f() {var m=b4(0,1,0,1); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]); assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + B32 + F32 + CF32 + F32SEL + "function f() {var m=b4(0,0,1,1); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]); +CheckU4(B32 + U32SEL, "var m=b4(0,0,0,0); var x=u4(1,2,3,4); var y=u4(5,6,7,8); x=u4sel(m,x,y);", [5, 6, 7, 8]); +CheckU4(B32 + U32SEL, "var m=b4(1,1,1,1); var x=u4(1,2,3,4); var y=u4(5,6,7,8); x=u4sel(m,x,y);", [1, 2, 3, 4]); +CheckU4(B32 + U32SEL, "var m=b4(0,1,0,1); var x=u4(1,2,3,4); var y=u4(5,6,7,8); x=u4sel(m,x,y);", [5, 2, 7, 4]); +CheckU4(B32 + U32SEL, "var m=b4(0,0,1,1); var x=u4(1,2,3,4); var y=u4(5,6,7,8); x=u4sel(m,x,y);", [5, 6, 3, 4]); + // Splat const I32SPLAT = 'var splat=i4.splat;' +const U32SPLAT = 'var splat=u4.splat;' const F32SPLAT = 'var splat=f4.splat;' const B32SPLAT = 'var splat=b4.splat;' @@ -991,6 +1159,8 @@ assertAsmTypeFail('glob', USE_ASM + I32 + I32SPLAT + FROUND + "function f() {var assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32SPLAT + 'function f(){return ci4(splat(42));} return f'), this)(), [42, 42, 42, 42]); assertEqX4(asmLink(asmCompile('glob', USE_ASM + B32 + CB32 + B32SPLAT + 'function f(){return cb4(splat(42));} return f'), this)(), [true, true, true, true]); assertEqX4(asmLink(asmCompile('glob', USE_ASM + B32 + CB32 + B32SPLAT + 'function f(){return cb4(splat(0));} return f'), this)(), [false, false, false, false]); +CheckU4(B32 + U32SPLAT, "var x=u4(1,2,3,4); x=splat(0);", [0, 0, 0, 0]); +CheckU4(B32 + U32SPLAT, "var x=u4(1,2,3,4); x=splat(0xaabbccdd);", [0xaabbccdd, 0xaabbccdd, 0xaabbccdd, 0xaabbccdd]); const l33t = Math.fround(13.37); assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + F32SPLAT + FROUND + 'function f(){return cf4(splat(f32(1)));} return f'), this)(), [1, 1, 1, 1]); @@ -1030,6 +1200,7 @@ var before = Date.now(); for (var i = 0; i < Math.pow(4, 4); i++) { var lanes = [i & 3, (i >> 2) & 3, (i >> 4) & 3, (i >> 6) & 3]; CheckI4('var swizzle=i4.swizzle;', 'var x=i4(1,2,3,4); x=swizzle(x, ' + lanes.join(',') + ')', swizzle([1,2,3,4], lanes)); + CheckU4('var swizzle=u4.swizzle;', 'var x=u4(1,2,3,4); x=swizzle(x, ' + lanes.join(',') + ')', swizzle([1,2,3,4], lanes)); CheckF4('var swizzle=f4.swizzle;', 'var x=f4(1,2,3,4); x=swizzle(x, ' + lanes.join(',') + ')', swizzle([1,2,3,4], lanes)); } DEBUG && print('time for checking all swizzles:', Date.now() - before); @@ -1102,6 +1273,7 @@ const LANE_SELECTORS = [ for (var lanes of LANE_SELECTORS) { CheckI4('var shuffle=i4.shuffle;', 'var x=i4(1,2,3,4); var y=i4(5,6,7,8); x=shuffle(x, y, ' + lanes.join(',') + ')', shuffle([1,2,3,4], [5,6,7,8], lanes)); + CheckU4('var shuffle=u4.shuffle;', 'var x=u4(1,2,3,4); var y=u4(5,6,7,8); x=shuffle(x, y, ' + lanes.join(',') + ')', shuffle([1,2,3,4], [5,6,7,8], lanes)); CheckF4('var shuffle=f4.shuffle;', 'var x=f4(1,2,3,4); var y=f4(5,6,7,8); x=shuffle(x, y, ' + lanes.join(',') + ')', shuffle([1,2,3,4], [5,6,7,8], lanes)); } DEBUG && print('time for checking all shuffles:', Date.now() - before); @@ -1121,11 +1293,13 @@ assertAsmTypeFail('glob', USE_ASM + I32 + "var pow=glob.Math.pow; function f() { // 3.2. FFI calls // Can't pass SIMD arguments to FFI assertAsmTypeFail('glob', 'ffi', USE_ASM + I32 + "var func=ffi.func; function f() {var x=i4(1,2,3,4); func(x);} return f"); +assertAsmTypeFail('glob', 'ffi', USE_ASM + U32 + "var func=ffi.func; function f() {var x=u4(1,2,3,4); func(x);} return f"); assertAsmTypeFail('glob', 'ffi', USE_ASM + F32 + "var func=ffi.func; function f() {var x=f4(1,2,3,4); func(x);} return f"); assertAsmTypeFail('glob', 'ffi', USE_ASM + B32 + "var func=ffi.func; function f() {var x=b4(1,2,3,4); func(x);} return f"); // Can't have FFI return SIMD values assertAsmTypeFail('glob', 'ffi', USE_ASM + I32 + "var func=ffi.func; function f() {var x=i4(1,2,3,4); x=i4(func());} return f"); +assertAsmTypeFail('glob', 'ffi', USE_ASM + U32 + "var func=ffi.func; function f() {var x=u4(1,2,3,4); x=i4(func());} return f"); assertAsmTypeFail('glob', 'ffi', USE_ASM + F32 + "var func=ffi.func; function f() {var x=f4(1,2,3,4); x=f4(func());} return f"); assertAsmTypeFail('glob', 'ffi', USE_ASM + B32 + "var func=ffi.func; function f() {var x=b4(1,2,3,4); x=b4(func());} return f"); diff --git a/js/src/jit-test/tests/wasm/basic.js b/js/src/jit-test/tests/wasm/basic.js index 82ed6c7156..4ac395c02e 100644 --- a/js/src/jit-test/tests/wasm/basic.js +++ b/js/src/jit-test/tests/wasm/basic.js @@ -87,8 +87,11 @@ wasmEvalText('(module (func (result i32) (param i32) (i32.const 42)))'); wasmEvalText('(module (func (param f32)))'); wasmEvalText('(module (func (param f64)))'); -assertErrorMessage(() => wasmEvalText('(module (func (param i64)))'), TypeError, /NYI/); -assertErrorMessage(() => wasmEvalText('(module (func (result i64)))'), TypeError, /NYI/); +var hasI64 = getBuildConfiguration().x64; +if (!hasI64) { + assertErrorMessage(() => wasmEvalText('(module (func (param i64)))'), TypeError, /NYI/); + assertErrorMessage(() => wasmEvalText('(module (func (result i64)))'), TypeError, /NYI/); +} // ---------------------------------------------------------------------------- // imports @@ -223,7 +226,8 @@ wasmEvalText('(module (func (local i32) (local f32) (set_local 1 (get_local 1))) assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (i32.const 42))) (export "" 0))')(), 42); assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (get_local 0))) (export "" 0))')(), 0); -assertErrorMessage(() => wasmEvalText('(module (func (local i64)))'), TypeError, /NYI/); +if (!hasI64) + assertErrorMessage(() => wasmEvalText('(module (func (local i64)))'), TypeError, /NYI/); assertEq(wasmEvalText('(module (func (param $a i32) (result i32) (get_local $a)) (export "" 0))')(), 0); assertEq(wasmEvalText('(module (func (param $a i32) (local $b i32) (result i32) (block (set_local $b (get_local $a)) (get_local $b))) (export "" 0))')(42), 42); @@ -348,15 +352,12 @@ for (bad of [6, 7, 100, Math.pow(2,31)-1, Math.pow(2,31), Math.pow(2,31)+1, Math assertThrowsInstanceOf(() => i2v(bad, 0), RangeError); } -// When the test below starts failing, remove it and uncomment the lines below! -assertErrorMessage(() => wasmEvalText('(module (func (param i64)))'), TypeError, /NYI/); -/* -assertErrorMessage(() => wasmEvalText('(module (func (param i64) (result i32) (i32.const 123)) (export "" 0))'), TypeError, /i64 argument/); -assertErrorMessage(() => wasmEvalText('(module (func (param i32) (result i64) (i64.const 123)) (export "" 0))'), TypeError, /i64 return type/); -assertErrorMessage(() => wasmEvalText('(module (import "a" "" (param i64) (result i32)))'), TypeError, /i64 argument/); -assertErrorMessage(() => wasmEvalText('(module (import "a" "" (result i64)))'), TypeError, /i64 return type/); -*/ - +if (hasI64) { + assertErrorMessage(() => wasmEvalText('(module (func (param i64) (result i32) (i32.const 123)) (export "" 0))'), TypeError, /i64 argument/); + assertErrorMessage(() => wasmEvalText('(module (func (param i32) (result i64) (i64.const 123)) (export "" 0))'), TypeError, /i64 return type/); + assertErrorMessage(() => wasmEvalText('(module (import "a" "" (param i64) (result i32)))'), TypeError, /i64 argument/); + assertErrorMessage(() => wasmEvalText('(module (import "a" "" (result i64)))'), TypeError, /i64 return type/); +} var {v2i, i2i, i2v} = wasmEvalText(`(module (type $a (func (result i32))) diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index e0f34a8abc..27557006d0 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -2490,6 +2490,12 @@ CodeGenerator::visitInteger(LInteger* lir) masm.move32(Imm32(lir->getValue()), ToRegister(lir->output())); } +void +CodeGenerator::visitInteger64(LInteger64* lir) +{ + masm.move64(Imm64(lir->getValue()), ToOutRegister64(lir)); +} + void CodeGenerator::visitPointer(LPointer* lir) { @@ -9312,23 +9318,23 @@ CodeGenerator::visitToIdV(LToIdV* lir) Label notInt32; FloatRegister temp = ToFloatRegister(lir->tempFloat()); const ValueOperand out = ToOutValue(lir); - ValueOperand index = ToValue(lir, LToIdV::Index); + ValueOperand input = ToValue(lir, LToIdV::Input); OutOfLineCode* ool = oolCallVM(ToIdInfo, lir, ArgList(ImmGCPtr(current->mir()->info().script()), ImmPtr(lir->mir()->resumePoint()->pc()), - ToValue(lir, LToIdV::Index)), + ToValue(lir, LToIdV::Input)), StoreValueTo(out)); - Register tag = masm.splitTagForTest(index); + Register tag = masm.splitTagForTest(input); masm.branchTestInt32(Assembler::NotEqual, tag, ¬Int32); - masm.moveValue(index, out); + masm.moveValue(input, out); masm.jump(ool->rejoin()); masm.bind(¬Int32); masm.branchTestDouble(Assembler::NotEqual, tag, ool->entry()); - masm.unboxDouble(index, temp); + masm.unboxDouble(input, temp); masm.convertDoubleToInt32(temp, out.scratchReg(), ool->entry(), true); masm.tagValue(JSVAL_TYPE_INT32, out.scratchReg(), out); diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index e627e6ba32..19d6d67679 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -106,6 +106,7 @@ class CodeGenerator : public CodeGeneratorSpecific void visitValueToString(LValueToString* lir); void visitValueToObjectOrNull(LValueToObjectOrNull* lir); void visitInteger(LInteger* lir); + void visitInteger64(LInteger64* lir); void visitRegExp(LRegExp* lir); void visitRegExpMatcher(LRegExpMatcher* lir); void visitOutOfLineRegExpMatcher(OutOfLineRegExpMatcher* ool); diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h index fac2269d99..807aabbfcc 100644 --- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -50,6 +50,8 @@ static const uint32_t PAYLOAD_INDEX = 1; # error "Unknown!" #endif +static const uint32_t INT64_PIECES = sizeof(int64_t) / sizeof(uintptr_t); + // Represents storage for an operand. For constants, the pointer is tagged // with a single bit, and the untagged pointer is a pointer to a Value. class LAllocation : public TempObject @@ -291,6 +293,50 @@ class LUse : public LAllocation static const uint32_t MAX_VIRTUAL_REGISTERS = LUse::VREG_MASK; +class LBoxAllocation +{ +#ifdef JS_NUNBOX32 + LAllocation type_; + LAllocation payload_; +#else + LAllocation value_; +#endif + + public: +#ifdef JS_NUNBOX32 + LBoxAllocation(LAllocation type, LAllocation payload) : type_(type), payload_(payload) {} + + LAllocation type() const { return type_; } + LAllocation payload() const { return payload_; } +#else + explicit LBoxAllocation(LAllocation value) : value_(value) {} + + LAllocation value() const { return value_; } +#endif +}; + +class LInt64Allocation +{ +#if JS_BITS_PER_WORD == 32 + LAllocation high_; + LAllocation low_; +#else + LAllocation value_; +#endif + + public: +#if JS_BITS_PER_WORD == 32 + LInt64Allocation(LAllocation high, LAllocation low) : high_(high), low_(low) {} + + LAllocation high() const { return high_; } + LAllocation low() const { return low_; } +#else + explicit LInt64Allocation(LAllocation value) : value_(value) {} + + LAllocation value() const { return value_; } +#endif +}; + class LGeneralReg : public LAllocation { public: @@ -567,6 +613,9 @@ class LDefinition case MIRType_Elements: return LDefinition::SLOTS; case MIRType_Pointer: +#if JS_BITS_PER_WORD == 64 + case MIRType_Int64: +#endif return LDefinition::GENERAL; case MIRType_Bool32x4: case MIRType_Int32x4: @@ -1050,6 +1099,14 @@ class LInstructionHelper : public details::LInstructionFixedDefsTempsHelper diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index b7166f1783..cbd91e26c6 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -24,22 +24,22 @@ using namespace jit; using mozilla::DebugOnly; using JS::GenericNaN; -void -LIRGenerator::useBoxAtStart(LInstruction* lir, size_t n, MDefinition* mir, LUse::Policy policy) -{ - return useBox(lir, n, mir, policy, true); -} - -void -LIRGenerator::useBoxFixedAtStart(LInstruction* lir, size_t n, MDefinition* mir, ValueOperand op) +LBoxAllocation +LIRGenerator::useBoxFixedAtStart(MDefinition* mir, ValueOperand op) { #if defined(JS_NUNBOX32) - return useBoxFixed(lir, n, mir, op.typeReg(), op.payloadReg(), true); + return useBoxFixed(mir, op.typeReg(), op.payloadReg(), true); #elif defined(JS_PUNBOX64) - return useBoxFixed(lir, n, mir, op.valueReg(), op.scratchReg(), true); + return useBoxFixed(mir, op.valueReg(), op.scratchReg(), true); #endif } +LBoxAllocation +LIRGenerator::useBoxAtStart(MDefinition* mir, LUse::Policy policy) +{ + return useBox(mir, policy, /* useAtStart = */ true); +} + void LIRGenerator::visitCloneLiteral(MCloneLiteral* ins) { @@ -155,7 +155,6 @@ LIRGenerator::visitTableSwitch(MTableSwitch* tableswitch) // If we don't know the type. if (opd->type() == MIRType_Value) { LTableSwitchV* lir = newLTableSwitchV(tableswitch); - useBox(lir, LTableSwitchV::InputValue, opd); add(lir); return; } @@ -312,9 +311,9 @@ LIRGenerator::visitNewStringObject(MNewStringObject* ins) void LIRGenerator::visitInitElem(MInitElem* ins) { - LInitElem* lir = new(alloc()) LInitElem(useRegisterAtStart(ins->getObject())); - useBoxAtStart(lir, LInitElem::IdIndex, ins->getId()); - useBoxAtStart(lir, LInitElem::ValueIndex, ins->getValue()); + LInitElem* lir = new(alloc()) LInitElem(useRegisterAtStart(ins->getObject()), + useBoxAtStart(ins->getId()), + useBoxAtStart(ins->getValue())); add(lir, ins); assignSafepoint(lir, ins); } @@ -324,8 +323,8 @@ LIRGenerator::visitInitElemGetterSetter(MInitElemGetterSetter* ins) { LInitElemGetterSetter* lir = new(alloc()) LInitElemGetterSetter(useRegisterAtStart(ins->object()), + useBoxAtStart(ins->idValue()), useRegisterAtStart(ins->value())); - useBoxAtStart(lir, LInitElemGetterSetter::IdIndex, ins->idValue()); add(lir, ins); assignSafepoint(lir, ins); } @@ -333,8 +332,8 @@ LIRGenerator::visitInitElemGetterSetter(MInitElemGetterSetter* ins) void LIRGenerator::visitMutateProto(MMutateProto* ins) { - LMutateProto* lir = new(alloc()) LMutateProto(useRegisterAtStart(ins->getObject())); - useBoxAtStart(lir, LMutateProto::ValueIndex, ins->getValue()); + LMutateProto* lir = new(alloc()) LMutateProto(useRegisterAtStart(ins->getObject()), + useBoxAtStart(ins->getValue())); add(lir, ins); assignSafepoint(lir, ins); } @@ -342,8 +341,8 @@ LIRGenerator::visitMutateProto(MMutateProto* ins) void LIRGenerator::visitInitProp(MInitProp* ins) { - LInitProp* lir = new(alloc()) LInitProp(useRegisterAtStart(ins->getObject())); - useBoxAtStart(lir, LInitProp::ValueIndex, ins->getValue()); + LInitProp* lir = new(alloc()) LInitProp(useRegisterAtStart(ins->getObject()), + useBoxAtStart(ins->getValue())); add(lir, ins); assignSafepoint(lir, ins); } @@ -408,16 +407,16 @@ void LIRGenerator::visitSetArgumentsObjectArg(MSetArgumentsObjectArg* ins) { LAllocation argsObj = useRegister(ins->getArgsObject()); - LSetArgumentsObjectArg* lir = new(alloc()) LSetArgumentsObjectArg(argsObj, temp()); - useBox(lir, LSetArgumentsObjectArg::ValueIndex, ins->getValue()); + LSetArgumentsObjectArg* lir = + new(alloc()) LSetArgumentsObjectArg(argsObj, useBox(ins->getValue()), temp()); add(lir, ins); } void LIRGenerator::visitReturnFromCtor(MReturnFromCtor* ins) { - LReturnFromCtor* lir = new(alloc()) LReturnFromCtor(useRegister(ins->getObject())); - useBox(lir, LReturnFromCtor::ValueIndex, ins->getValue()); + LReturnFromCtor* lir = new(alloc()) LReturnFromCtor(useBox(ins->getValue()), + useRegister(ins->getObject())); define(lir, ins); } @@ -427,13 +426,10 @@ LIRGenerator::visitComputeThis(MComputeThis* ins) MOZ_ASSERT(ins->type() == MIRType_Value); MOZ_ASSERT(ins->input()->type() == MIRType_Value); - LComputeThis* lir = new(alloc()) LComputeThis(); - // Don't use useBoxAtStart because ComputeThis has a safepoint and needs to // have its inputs in different registers than its return value so that // they aren't clobbered. - useBox(lir, LComputeThis::ValueIndex, ins->input()); - + LComputeThis* lir = new(alloc()) LComputeThis(useBox(ins->input())); defineBox(lir, ins); assignSafepoint(lir, ins); } @@ -472,8 +468,7 @@ LIRGenerator::lowerCallArguments(MCall* call) // Values take a slow path. if (arg->type() == MIRType_Value) { - LStackArgV* stack = new(alloc()) LStackArgV(argslot); - useBox(stack, 0, arg); + LStackArgV* stack = new(alloc()) LStackArgV(argslot, useBox(arg)); add(stack); } else { // Known types can move constant types and/or payloads. @@ -554,12 +549,10 @@ LIRGenerator::visitApplyArgs(MApplyArgs* apply) LApplyArgsGeneric* lir = new(alloc()) LApplyArgsGeneric( useFixed(apply->getFunction(), CallTempReg3), useFixed(apply->getArgc(), CallTempReg0), + useBoxFixed(apply->getThis(), CallTempReg4, CallTempReg5), tempFixed(CallTempReg1), // object register tempFixed(CallTempReg2)); // stack counter register - MDefinition* self = apply->getThis(); - useBoxFixed(lir, LApplyArgsGeneric::ThisIndex, self, CallTempReg4, CallTempReg5); - // Bailout is only needed in the case of possible non-JSFunction callee. if (!apply->getSingleTarget()) assignSnapshot(lir, Bailout_NonJSFunctionCallee); @@ -582,15 +575,13 @@ LIRGenerator::visitApplyArray(MApplyArray* apply) MOZ_ASSERT(CallTempReg2 != JSReturnReg_Data); LApplyArrayGeneric* lir = new(alloc()) LApplyArrayGeneric( - useFixed(apply->getFunction(), CallTempReg3), - useFixed(apply->getElements(), CallTempReg0), + useFixedAtStart(apply->getFunction(), CallTempReg3), + useFixedAtStart(apply->getElements(), CallTempReg0), + useBoxFixed(apply->getThis(), CallTempReg4, CallTempReg5), tempFixed(CallTempReg1), // object register tempFixed(CallTempReg2)); // stack counter register - MDefinition* self = apply->getThis(); - useBoxFixed(lir, LApplyArrayGeneric::ThisIndex, self, CallTempReg4, CallTempReg5); - - // Bailout is needed in the case of possible non-JSFunction callee + // Bailout is needed in the case of possible non-JSFunction callee, // too many values in the array, or empty space at the end of the // array. I'm going to use NonJSFunctionCallee for the code even // if that is not an adequate description. @@ -682,9 +673,8 @@ LIRGenerator::visitCallDirectEval(MCallDirectEval* ins) MDefinition* newTargetValue = ins->getNewTargetValue(); LInstruction* lir = new(alloc()) LCallDirectEval(useRegisterAtStart(scopeChain), - useRegisterAtStart(string)); - useBoxAtStart(lir, LCallDirectEval::NewTarget, newTargetValue); - + useRegisterAtStart(string), + useBoxAtStart(newTargetValue)); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -733,8 +723,7 @@ LIRGenerator::visitTest(MTest* test) temp1 = LDefinition::BogusTemp(); } LTestVAndBranch* lir = - new(alloc()) LTestVAndBranch(ifTrue, ifFalse, tempDouble(), temp0, temp1); - useBox(lir, LTestVAndBranch::Input, opd); + new(alloc()) LTestVAndBranch(ifTrue, ifFalse, useBox(opd), tempDouble(), temp0, temp1); add(lir, test); return; } @@ -814,9 +803,8 @@ LIRGenerator::visitTest(MTest* test) } LIsNullOrLikeUndefinedAndBranchV* lir = - new(alloc()) LIsNullOrLikeUndefinedAndBranchV(comp, ifTrue, ifFalse, + new(alloc()) LIsNullOrLikeUndefinedAndBranchV(comp, ifTrue, ifFalse, useBox(left), tmp, tmpToUnbox); - useBox(lir, LIsNullOrLikeUndefinedAndBranchV::Value, left); add(lir, test); return; } @@ -826,9 +814,9 @@ LIRGenerator::visitTest(MTest* test) MOZ_ASSERT(left->type() == MIRType_Value); MOZ_ASSERT(right->type() == MIRType_Boolean); - LAllocation rhs = useRegisterOrConstant(right); - LCompareBAndBranch* lir = new(alloc()) LCompareBAndBranch(comp, rhs, ifTrue, ifFalse); - useBox(lir, LCompareBAndBranch::Lhs, left); + LCompareBAndBranch* lir = new(alloc()) LCompareBAndBranch(comp, useBox(left), + useRegisterOrConstant(right), + ifTrue, ifFalse); add(lir, test); return; } @@ -874,9 +862,9 @@ LIRGenerator::visitTest(MTest* test) // Compare values. if (comp->compareType() == MCompare::Compare_Bitwise) { LCompareBitwiseAndBranch* lir = - new(alloc()) LCompareBitwiseAndBranch(comp, ifTrue, ifFalse); - useBoxAtStart(lir, LCompareBitwiseAndBranch::LhsInput, left); - useBoxAtStart(lir, LCompareBitwiseAndBranch::RhsInput, right); + new(alloc()) LCompareBitwiseAndBranch(comp, ifTrue, ifFalse, + useBoxAtStart(left), + useBoxAtStart(right)); add(lir, test); return; } @@ -898,8 +886,8 @@ LIRGenerator::visitTest(MTest* test) MDefinition* input = opd->toIsObject()->input(); MOZ_ASSERT(input->type() == MIRType_Value); - LIsObjectAndBranch* lir = new(alloc()) LIsObjectAndBranch(ifTrue, ifFalse); - useBoxAtStart(lir, LIsObjectAndBranch::Input, input); + LIsObjectAndBranch* lir = new(alloc()) LIsObjectAndBranch(ifTrue, ifFalse, + useBoxAtStart(input)); add(lir, test); return; } @@ -910,8 +898,8 @@ LIRGenerator::visitTest(MTest* test) MDefinition* input = opd->toIsNoIter()->input(); MOZ_ASSERT(input->type() == MIRType_Value); - LIsNoIterAndBranch* lir = new(alloc()) LIsNoIterAndBranch(ifTrue, ifFalse); - useBox(lir, LIsNoIterAndBranch::Input, input); + LIsNoIterAndBranch* lir = new(alloc()) LIsNoIterAndBranch(ifTrue, ifFalse, + useBox(input)); add(lir, test); return; } @@ -1000,8 +988,8 @@ LIRGenerator::visitCompare(MCompare* comp) MOZ_ASSERT(left->type() == MIRType_Value); MOZ_ASSERT(right->type() == MIRType_String); - LCompareStrictS* lir = new(alloc()) LCompareStrictS(useRegister(right), tempToUnbox()); - useBox(lir, LCompareStrictS::Lhs, left); + LCompareStrictS* lir = new(alloc()) LCompareStrictS(useBox(left), useRegister(right), + tempToUnbox()); define(lir, comp); assignSafepoint(lir, comp); return; @@ -1009,9 +997,7 @@ LIRGenerator::visitCompare(MCompare* comp) // Unknown/unspecialized compare use a VM call. if (comp->compareType() == MCompare::Compare_Unknown) { - LCompareVM* lir = new(alloc()) LCompareVM(); - useBoxAtStart(lir, LCompareVM::LhsInput, left); - useBoxAtStart(lir, LCompareVM::RhsInput, right); + LCompareVM* lir = new(alloc()) LCompareVM(useBoxAtStart(left), useBoxAtStart(right)); defineReturn(lir, comp); assignSafepoint(lir, comp); return; @@ -1048,8 +1034,8 @@ LIRGenerator::visitCompare(MCompare* comp) tmpToUnbox = LDefinition::BogusTemp(); } - LIsNullOrLikeUndefinedV* lir = new(alloc()) LIsNullOrLikeUndefinedV(tmp, tmpToUnbox); - useBox(lir, LIsNullOrLikeUndefinedV::Value, left); + LIsNullOrLikeUndefinedV* lir = new(alloc()) LIsNullOrLikeUndefinedV(useBox(left), + tmp, tmpToUnbox); define(lir, comp); return; } @@ -1059,8 +1045,7 @@ LIRGenerator::visitCompare(MCompare* comp) MOZ_ASSERT(left->type() == MIRType_Value); MOZ_ASSERT(right->type() == MIRType_Boolean); - LCompareB* lir = new(alloc()) LCompareB(useRegisterOrConstant(right)); - useBox(lir, LCompareB::Lhs, left); + LCompareB* lir = new(alloc()) LCompareB(useBox(left), useRegisterOrConstant(right)); define(lir, comp); return; } @@ -1098,9 +1083,8 @@ LIRGenerator::visitCompare(MCompare* comp) // Compare values. if (comp->compareType() == MCompare::Compare_Bitwise) { - LCompareBitwise* lir = new(alloc()) LCompareBitwise(); - useBoxAtStart(lir, LCompareBitwise::LhsInput, left); - useBoxAtStart(lir, LCompareBitwise::RhsInput, right); + LCompareBitwise* lir = new(alloc()) LCompareBitwise(useBoxAtStart(left), + useBoxAtStart(right)); define(lir, comp); return; } @@ -1120,9 +1104,7 @@ LIRGenerator::lowerBitOp(JSOp op, MInstruction* ins) return; } - LBitOpV* lir = new(alloc()) LBitOpV(op); - useBoxAtStart(lir, LBitOpV::LhsInput, lhs); - useBoxAtStart(lir, LBitOpV::RhsInput, rhs); + LBitOpV* lir = new(alloc()) LBitOpV(op, useBoxAtStart(lhs), useBoxAtStart(rhs)); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -1133,16 +1115,14 @@ LIRGenerator::visitTypeOf(MTypeOf* ins) MDefinition* opd = ins->input(); MOZ_ASSERT(opd->type() == MIRType_Value); - LTypeOfV* lir = new(alloc()) LTypeOfV(tempToUnbox()); - useBox(lir, LTypeOfV::Input, opd); + LTypeOfV* lir = new(alloc()) LTypeOfV(useBox(opd), tempToUnbox()); define(lir, ins); } void LIRGenerator::visitToId(MToId* ins) { - LToIdV* lir = new(alloc()) LToIdV(tempDouble()); - useBox(lir, LToIdV::Index, ins->input()); + LToIdV* lir = new(alloc()) LToIdV(useBox(ins->input()), tempDouble()); defineBox(lir, ins); assignSafepoint(lir, ins); } @@ -1157,8 +1137,7 @@ LIRGenerator::visitBitNot(MBitNot* ins) return; } - LBitNotV* lir = new(alloc()) LBitNotV; - useBoxAtStart(lir, LBitNotV::Input, input); + LBitNotV* lir = new(alloc()) LBitNotV(useBoxAtStart(input)); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -1242,9 +1221,7 @@ LIRGenerator::lowerShiftOp(JSOp op, MShiftInstruction* ins) return; } - LBitOpV* lir = new(alloc()) LBitOpV(op); - useBoxAtStart(lir, LBitOpV::LhsInput, lhs); - useBoxAtStart(lir, LBitOpV::RhsInput, rhs); + LBitOpV* lir = new(alloc()) LBitOpV(op, useBoxAtStart(lhs), useBoxAtStart(rhs)); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -1676,9 +1653,7 @@ LIRGenerator::lowerBinaryV(JSOp op, MBinaryInstruction* ins) MOZ_ASSERT(lhs->type() == MIRType_Value); MOZ_ASSERT(rhs->type() == MIRType_Value); - LBinaryV* lir = new(alloc()) LBinaryV(op); - useBoxAtStart(lir, LBinaryV::LhsInput, lhs); - useBoxAtStart(lir, LBinaryV::RhsInput, rhs); + LBinaryV* lir = new(alloc()) LBinaryV(op, useBoxAtStart(lhs), useBoxAtStart(rhs)); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -1797,8 +1772,7 @@ LIRGenerator::visitToDouble(MToDouble* convert) switch (opd->type()) { case MIRType_Value: { - LValueToDouble* lir = new(alloc()) LValueToDouble(); - useBox(lir, LValueToDouble::Input, opd); + LValueToDouble* lir = new(alloc()) LValueToDouble(useBox(opd)); assignSnapshot(lir, Bailout_NonPrimitiveInput); define(lir, convert); break; @@ -1853,8 +1827,7 @@ LIRGenerator::visitToFloat32(MToFloat32* convert) switch (opd->type()) { case MIRType_Value: { - LValueToFloat32* lir = new(alloc()) LValueToFloat32(); - useBox(lir, LValueToFloat32::Input, opd); + LValueToFloat32* lir = new(alloc()) LValueToFloat32(useBox(opd)); assignSnapshot(lir, Bailout_NonPrimitiveInput); define(lir, convert); break; @@ -1909,8 +1882,7 @@ LIRGenerator::visitToInt32(MToInt32* convert) case MIRType_Value: { LValueToInt32* lir = - new(alloc()) LValueToInt32(tempDouble(), temp(), LValueToInt32::NORMAL); - useBox(lir, LValueToInt32::Input, opd); + new(alloc()) LValueToInt32(useBox(opd), tempDouble(), temp(), LValueToInt32::NORMAL); assignSnapshot(lir, Bailout_NonPrimitiveInput); define(lir, convert); assignSafepoint(lir, convert); @@ -1968,9 +1940,8 @@ LIRGenerator::visitTruncateToInt32(MTruncateToInt32* truncate) switch (opd->type()) { case MIRType_Value: { - LValueToInt32* lir = new(alloc()) LValueToInt32(tempDouble(), temp(), + LValueToInt32* lir = new(alloc()) LValueToInt32(useBox(opd), tempDouble(), temp(), LValueToInt32::TRUNCATE); - useBox(lir, LValueToInt32::Input, opd); assignSnapshot(lir, Bailout_NonPrimitiveInput); define(lir, truncate); assignSafepoint(lir, truncate); @@ -2049,8 +2020,7 @@ LIRGenerator::visitToString(MToString* ins) break; case MIRType_Value: { - LValueToString* lir = new(alloc()) LValueToString(tempToUnbox()); - useBox(lir, LValueToString::Input, opd); + LValueToString* lir = new(alloc()) LValueToString(useBox(opd), tempToUnbox()); if (ins->fallible()) assignSnapshot(lir, Bailout_NonPrimitiveInput); define(lir, ins); @@ -2069,8 +2039,7 @@ LIRGenerator::visitToObjectOrNull(MToObjectOrNull* ins) { MOZ_ASSERT(ins->input()->type() == MIRType_Value); - LValueToObjectOrNull* lir = new(alloc()) LValueToObjectOrNull(); - useBox(lir, LValueToString::Input, ins->input()); + LValueToObjectOrNull* lir = new(alloc()) LValueToObjectOrNull(useBox(ins->input())); define(lir, ins); assignSafepoint(lir, ins); } @@ -2220,11 +2189,8 @@ LIRGenerator::visitBinarySharedStub(MBinarySharedStub* ins) MOZ_ASSERT(ins->type() == MIRType_Value); MOZ_ASSERT(ins->type() == MIRType_Value); - LBinarySharedStub* lir = new(alloc()) LBinarySharedStub(); - - useBoxFixedAtStart(lir, LBinarySharedStub::LhsInput, lhs, R0); - useBoxFixedAtStart(lir, LBinarySharedStub::RhsInput, rhs, R1); - + LBinarySharedStub* lir = new(alloc()) LBinarySharedStub(useBoxFixedAtStart(lhs, R0), + useBoxFixedAtStart(rhs, R1)); defineSharedStubReturn(lir, ins); assignSafepoint(lir, ins); } @@ -2235,10 +2201,7 @@ LIRGenerator::visitUnarySharedStub(MUnarySharedStub* ins) MDefinition* input = ins->getOperand(0); MOZ_ASSERT(ins->type() == MIRType_Value); - LUnarySharedStub* lir = new(alloc()) LUnarySharedStub(); - - useBoxFixedAtStart(lir, LUnarySharedStub::Input, input, R0); - + LUnarySharedStub* lir = new(alloc()) LUnarySharedStub(useBoxFixedAtStart(input, R0)); defineSharedStubReturn(lir, ins); assignSafepoint(lir, ins); } @@ -2268,8 +2231,8 @@ LIRGenerator::visitLambdaArrow(MLambdaArrow* ins) MOZ_ASSERT(ins->scopeChain()->type() == MIRType_Object); MOZ_ASSERT(ins->newTargetDef()->type() == MIRType_Value); - LLambdaArrow* lir = new(alloc()) LLambdaArrow(useRegister(ins->scopeChain())); - useBox(lir, LLambdaArrow::NewTargetValue, ins->newTargetDef()); + LLambdaArrow* lir = new(alloc()) LLambdaArrow(useRegister(ins->scopeChain()), + useBox(ins->newTargetDef())); define(lir, ins); assignSafepoint(lir, ins); } @@ -2377,8 +2340,7 @@ LIRGenerator::visitStoreSlot(MStoreSlot* ins) switch (ins->value()->type()) { case MIRType_Value: - lir = new(alloc()) LStoreSlotV(useRegister(ins->slots())); - useBox(lir, LStoreSlotV::Value, ins->value()); + lir = new(alloc()) LStoreSlotV(useRegister(ins->slots()), useBox(ins->value())); add(lir, ins); break; @@ -2429,8 +2391,7 @@ LIRGenerator::visitTypeBarrier(MTypeBarrier* ins) // Handle typebarrier with Value as input. if (inputType == MIRType_Value) { LDefinition tmp = needTemp ? temp() : tempToUnbox(); - LTypeBarrierV* barrier = new(alloc()) LTypeBarrierV(tmp); - useBox(barrier, LTypeBarrierV::Input, ins->input()); + LTypeBarrierV* barrier = new(alloc()) LTypeBarrierV(useBox(ins->input()), tmp); assignSnapshot(barrier, Bailout_TypeBarrierV); add(barrier, ins); redefine(ins, ins->input()); @@ -2471,8 +2432,7 @@ LIRGenerator::visitMonitorTypes(MMonitorTypes* ins) bool needTemp = !types->unknownObject() && types->getObjectCount() > 0; LDefinition tmp = needTemp ? temp() : tempToUnbox(); - LMonitorTypes* lir = new(alloc()) LMonitorTypes(tmp); - useBox(lir, LMonitorTypes::Input, ins->input()); + LMonitorTypes* lir = new(alloc()) LMonitorTypes(useBox(ins->input()), tmp); assignSnapshot(lir, Bailout_MonitorTypes); add(lir, ins); } @@ -2518,8 +2478,8 @@ LIRGenerator::visitPostWriteBarrier(MPostWriteBarrier* ins) new(alloc()) LPostWriteBarrierV(useConstantObject ? useOrConstant(ins->object()) : useRegister(ins->object()), + useBox(ins->value()), tmp); - useBox(lir, LPostWriteBarrierV::Input, ins->value()); add(lir, ins); assignSafepoint(lir, ins); break; @@ -2567,8 +2527,8 @@ LIRGenerator::visitPostWriteElementBarrier(MPostWriteElementBarrier* ins) ? useOrConstant(ins->object()) : useRegister(ins->object()), useRegister(ins->index()), + useBox(ins->value()), tmp); - useBox(lir, LPostWriteElementBarrierV::Input, ins->value()); add(lir, ins); assignSafepoint(lir, ins); break; @@ -2756,8 +2716,7 @@ LIRGenerator::visitNot(MNot* ins) temp1 = LDefinition::BogusTemp(); } - LNotV* lir = new(alloc()) LNotV(tempDouble(), temp0, temp1); - useBox(lir, LNotV::Input, op); + LNotV* lir = new(alloc()) LNotV(useBox(op), tempDouble(), temp0, temp1); define(lir, ins); break; } @@ -2912,10 +2871,9 @@ LIRGenerator::visitStoreElement(MStoreElement* ins) switch (ins->value()->type()) { case MIRType_Value: { - LInstruction* lir = new(alloc()) LStoreElementV(elements, index); + LInstruction* lir = new(alloc()) LStoreElementV(elements, index, useBox(ins->value())); if (ins->fallible()) assignSnapshot(lir, Bailout_Hole); - useBox(lir, LStoreElementV::Value, ins->value()); add(lir, ins); break; } @@ -2950,8 +2908,8 @@ LIRGenerator::visitStoreElementHole(MStoreElementHole* ins) LInstruction* lir; switch (ins->value()->type()) { case MIRType_Value: - lir = new(alloc()) LStoreElementHoleV(object, elements, index, tempDef); - useBox(lir, LStoreElementHoleV::Value, ins->value()); + lir = new(alloc()) LStoreElementHoleV(object, elements, index, useBox(ins->value()), + tempDef); break; default: @@ -3049,8 +3007,7 @@ LIRGenerator::visitArrayPush(MArrayPush* ins) switch (ins->value()->type()) { case MIRType_Value: { - LArrayPushV* lir = new(alloc()) LArrayPushV(object, temp()); - useBox(lir, LArrayPushV::Value, ins->value()); + LArrayPushV* lir = new(alloc()) LArrayPushV(object, useBox(ins->value()), temp()); define(lir, ins); assignSafepoint(lir, ins); break; @@ -3192,8 +3149,7 @@ LIRGenerator::visitClampToUint8(MClampToUint8* ins) case MIRType_Value: { - LClampVToUint8* lir = new(alloc()) LClampVToUint8(tempDouble()); - useBox(lir, LClampVToUint8::Input, in); + LClampVToUint8* lir = new(alloc()) LClampVToUint8(useBox(in), tempDouble()); assignSnapshot(lir, Bailout_NonPrimitiveInput); define(lir, ins); assignSafepoint(lir, ins); @@ -3339,8 +3295,8 @@ LIRGenerator::visitStoreFixedSlot(MStoreFixedSlot* ins) MOZ_ASSERT(ins->object()->type() == MIRType_Object); if (ins->value()->type() == MIRType_Value) { - LStoreFixedSlotV* lir = new(alloc()) LStoreFixedSlotV(useRegister(ins->object())); - useBox(lir, LStoreFixedSlotV::Value, ins->value()); + LStoreFixedSlotV* lir = new(alloc()) LStoreFixedSlotV(useRegister(ins->object()), + useBox(ins->value())); add(lir, ins); } else { LStoreFixedSlotT* lir = new(alloc()) LStoreFixedSlotT(useRegister(ins->object()), @@ -3395,13 +3351,15 @@ LIRGenerator::visitGetPropertyCache(MGetPropertyCache* ins) bool useConstId = id->type() == MIRType_String || id->type() == MIRType_Symbol; if (ins->type() == MIRType_Value) { - LGetPropertyCacheV* lir = new(alloc()) LGetPropertyCacheV(useRegister(ins->object())); - useBoxOrTypedOrConstant(lir, LGetPropertyCacheV::Id, id, useConstId); + LGetPropertyCacheV* lir = + new(alloc()) LGetPropertyCacheV(useRegister(ins->object()), + useBoxOrTypedOrConstant(id, useConstId)); defineBox(lir, ins); assignSafepoint(lir, ins); } else { - LGetPropertyCacheT* lir = new(alloc()) LGetPropertyCacheT(useRegister(ins->object())); - useBoxOrTypedOrConstant(lir, LGetPropertyCacheT::Id, id, useConstId); + LGetPropertyCacheT* lir = + new(alloc()) LGetPropertyCacheT(useRegister(ins->object()), + useBoxOrTypedOrConstant(id, useConstId)); define(lir, ins); assignSafepoint(lir, ins); } @@ -3433,8 +3391,9 @@ LIRGenerator::visitSetPropertyPolymorphic(MSetPropertyPolymorphic* ins) if (ins->value()->type() == MIRType_Value) { LSetPropertyPolymorphicV* lir = - new(alloc()) LSetPropertyPolymorphicV(useRegister(ins->obj()), temp()); - useBox(lir, LSetPropertyPolymorphicV::Value, ins->value()); + new(alloc()) LSetPropertyPolymorphicV(useRegister(ins->obj()), + useBox(ins->value()), + temp()); assignSnapshot(lir, Bailout_ShapeGuard); add(lir, ins); } else { @@ -3575,8 +3534,7 @@ LIRGenerator::visitAssertRange(MAssertRange* ins) break; } case MIRType_Value: - lir = new(alloc()) LAssertRangeV(tempToUnbox(), tempDouble(), tempDouble()); - useBox(lir, LAssertRangeV::Input, input); + lir = new(alloc()) LAssertRangeV(useBox(input), tempToUnbox(), tempDouble(), tempDouble()); break; default: @@ -3591,8 +3549,7 @@ LIRGenerator::visitAssertRange(MAssertRange* ins) void LIRGenerator::visitCallGetProperty(MCallGetProperty* ins) { - LCallGetProperty* lir = new(alloc()) LCallGetProperty(); - useBoxAtStart(lir, LCallGetProperty::Value, ins->value()); + LCallGetProperty* lir = new(alloc()) LCallGetProperty(useBoxAtStart(ins->value())); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -3603,9 +3560,8 @@ LIRGenerator::visitCallGetElement(MCallGetElement* ins) MOZ_ASSERT(ins->lhs()->type() == MIRType_Value); MOZ_ASSERT(ins->rhs()->type() == MIRType_Value); - LCallGetElement* lir = new(alloc()) LCallGetElement(); - useBoxAtStart(lir, LCallGetElement::LhsInput, ins->lhs()); - useBoxAtStart(lir, LCallGetElement::RhsInput, ins->rhs()); + LCallGetElement* lir = new(alloc()) LCallGetElement(useBoxAtStart(ins->lhs()), + useBoxAtStart(ins->rhs())); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -3613,8 +3569,8 @@ LIRGenerator::visitCallGetElement(MCallGetElement* ins) void LIRGenerator::visitCallSetProperty(MCallSetProperty* ins) { - LInstruction* lir = new(alloc()) LCallSetProperty(useRegisterAtStart(ins->object())); - useBoxAtStart(lir, LCallSetProperty::Value, ins->value()); + LInstruction* lir = new(alloc()) LCallSetProperty(useRegisterAtStart(ins->object()), + useBoxAtStart(ins->value())); add(lir, ins); assignSafepoint(lir, ins); } @@ -3622,8 +3578,7 @@ LIRGenerator::visitCallSetProperty(MCallSetProperty* ins) void LIRGenerator::visitDeleteProperty(MDeleteProperty* ins) { - LCallDeleteProperty* lir = new(alloc()) LCallDeleteProperty(); - useBoxAtStart(lir, LCallDeleteProperty::Value, ins->value()); + LCallDeleteProperty* lir = new(alloc()) LCallDeleteProperty(useBoxAtStart(ins->value())); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -3631,9 +3586,8 @@ LIRGenerator::visitDeleteProperty(MDeleteProperty* ins) void LIRGenerator::visitDeleteElement(MDeleteElement* ins) { - LCallDeleteElement* lir = new(alloc()) LCallDeleteElement(); - useBoxAtStart(lir, LCallDeleteElement::Value, ins->value()); - useBoxAtStart(lir, LCallDeleteElement::Index, ins->index()); + LCallDeleteElement* lir = new(alloc()) LCallDeleteElement(useBoxAtStart(ins->value()), + useBoxAtStart(ins->index())); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -3672,11 +3626,12 @@ LIRGenerator::visitSetPropertyCache(MSetPropertyCache* ins) tempF32 = hasUnaliasedDouble() ? tempFloat32() : LDefinition::BogusTemp(); } - LInstruction* lir = new(alloc()) LSetPropertyCache(useRegister(ins->object()), temp(), - tempToUnboxIndex, tempD, tempF32); - useBoxOrTypedOrConstant(lir, LSetPropertyCache::Id, id, useConstId); - useBoxOrTypedOrConstant(lir, LSetPropertyCache::Value, ins->value(), useConstValue); - + LInstruction* lir = + new(alloc()) LSetPropertyCache(useRegister(ins->object()), + useBoxOrTypedOrConstant(id, useConstId), + useBoxOrTypedOrConstant(ins->value(), useConstValue), + temp(), + tempToUnboxIndex, tempD, tempF32); add(lir, ins); assignSafepoint(lir, ins); } @@ -3688,10 +3643,9 @@ LIRGenerator::visitCallSetElement(MCallSetElement* ins) MOZ_ASSERT(ins->index()->type() == MIRType_Value); MOZ_ASSERT(ins->value()->type() == MIRType_Value); - LCallSetElement* lir = new(alloc()) LCallSetElement(); - lir->setOperand(0, useRegisterAtStart(ins->object())); - useBoxAtStart(lir, LCallSetElement::Index, ins->index()); - useBoxAtStart(lir, LCallSetElement::Value, ins->value()); + LCallSetElement* lir = new(alloc()) LCallSetElement(useRegisterAtStart(ins->object()), + useBoxAtStart(ins->index()), + useBoxAtStart(ins->value())); add(lir, ins); assignSafepoint(lir, ins); } @@ -3699,9 +3653,8 @@ LIRGenerator::visitCallSetElement(MCallSetElement* ins) void LIRGenerator::visitCallInitElementArray(MCallInitElementArray* ins) { - LCallInitElementArray* lir = new(alloc()) LCallInitElementArray(); - lir->setOperand(0, useRegisterAtStart(ins->object())); - useBoxAtStart(lir, LCallInitElementArray::Value, ins->value()); + LCallInitElementArray* lir = new(alloc()) LCallInitElementArray(useRegisterAtStart(ins->object()), + useBoxAtStart(ins->value())); add(lir, ins); assignSafepoint(lir, ins); } @@ -3777,8 +3730,7 @@ LIRGenerator::visitSetFrameArgument(MSetFrameArgument* ins) MDefinition* input = ins->input(); if (input->type() == MIRType_Value) { - LSetFrameArgumentV* lir = new(alloc()) LSetFrameArgumentV(); - useBox(lir, LSetFrameArgumentV::Input, input); + LSetFrameArgumentV* lir = new(alloc()) LSetFrameArgumentV(useBox(input)); add(lir, ins); } else if (input->type() == MIRType_Undefined || input->type() == MIRType_Null) { Value val = input->type() == MIRType_Undefined ? UndefinedValue() : NullValue(); @@ -3817,8 +3769,7 @@ LIRGenerator::visitThrow(MThrow* ins) MDefinition* value = ins->getOperand(0); MOZ_ASSERT(value->type() == MIRType_Value); - LThrow* lir = new(alloc()) LThrow; - useBoxAtStart(lir, LThrow::Value, value); + LThrow* lir = new(alloc()) LThrow(useBoxAtStart(value)); add(lir, ins); assignSafepoint(lir, ins); } @@ -3832,8 +3783,7 @@ LIRGenerator::visitIn(MIn* ins) MOZ_ASSERT(lhs->type() == MIRType_Value); MOZ_ASSERT(rhs->type() == MIRType_Object); - LIn* lir = new(alloc()) LIn(useRegisterAtStart(rhs)); - useBoxAtStart(lir, LIn::LHS, lhs); + LIn* lir = new(alloc()) LIn(useBoxAtStart(lhs), useRegisterAtStart(rhs)); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -3850,8 +3800,7 @@ LIRGenerator::visitInstanceOf(MInstanceOf* ins) define(lir, ins); assignSafepoint(lir, ins); } else { - LInstanceOfV* lir = new(alloc()) LInstanceOfV(); - useBox(lir, LInstanceOfV::LHS, lhs); + LInstanceOfV* lir = new(alloc()) LInstanceOfV(useBox(lhs)); define(lir, ins); assignSafepoint(lir, ins); } @@ -3866,8 +3815,8 @@ LIRGenerator::visitCallInstanceOf(MCallInstanceOf* ins) MOZ_ASSERT(lhs->type() == MIRType_Value); MOZ_ASSERT(rhs->type() == MIRType_Object); - LCallInstanceOf* lir = new(alloc()) LCallInstanceOf(useRegisterAtStart(rhs)); - useBoxAtStart(lir, LCallInstanceOf::LHS, lhs); + LCallInstanceOf* lir = new(alloc()) LCallInstanceOf(useBoxAtStart(lhs), + useRegisterAtStart(rhs)); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -3911,8 +3860,7 @@ LIRGenerator::visitIsObject(MIsObject* ins) MDefinition* opd = ins->input(); MOZ_ASSERT(opd->type() == MIRType_Value); - LIsObject* lir = new(alloc()) LIsObject(); - useBoxAtStart(lir, LIsObject::Input, opd); + LIsObject* lir = new(alloc()) LIsObject(useBoxAtStart(opd)); define(lir, ins); } @@ -3967,6 +3915,10 @@ LIRGenerator::visitAsmJSReturn(MAsmJSReturn* ins) lir->setOperand(0, useFixed(rval, ReturnSimd128Reg)); else if (rval->type() == MIRType_Int32) lir->setOperand(0, useFixed(rval, ReturnReg)); +#if JS_BITS_PER_WORD == 64 + else if (rval->type() == MIRType_Int64) + lir->setOperand(0, useFixed(rval, ReturnReg)); +#endif else MOZ_CRASH("Unexpected asm.js return type"); add(lir); @@ -4023,10 +3975,6 @@ LIRGenerator::visitSetDOMProperty(MSetDOMProperty* ins) GetTempRegForIntArg(1, 0, &objReg); GetTempRegForIntArg(2, 0, &privReg); GetTempRegForIntArg(3, 0, &valueReg); - LSetDOMProperty* lir = new(alloc()) LSetDOMProperty(tempFixed(cxReg), - useFixed(ins->object(), objReg), - tempFixed(privReg), - tempFixed(valueReg)); // Keep using GetTempRegForIntArg, since we want to make sure we // don't clobber registers we're already using. @@ -4034,7 +3982,12 @@ LIRGenerator::visitSetDOMProperty(MSetDOMProperty* ins) GetTempRegForIntArg(4, 0, &tempReg1); mozilla::DebugOnly ok = GetTempRegForIntArg(5, 0, &tempReg2); MOZ_ASSERT(ok, "How can we not have six temp registers?"); - useBoxFixed(lir, LSetDOMProperty::Value, val, tempReg1, tempReg2); + + LSetDOMProperty* lir = new(alloc()) LSetDOMProperty(tempFixed(cxReg), + useFixed(ins->object(), objReg), + useBoxFixed(val, tempReg1, tempReg2), + tempFixed(privReg), + tempFixed(valueReg)); add(lir, ins); assignSafepoint(lir, ins); } @@ -4422,7 +4375,10 @@ LIRGenerator::visitSimdShift(MSimdShift* ins) LUse vector = useRegisterAtStart(ins->lhs()); LAllocation value = useRegisterOrConstant(ins->rhs()); - LSimdShift* lir = new(alloc()) LSimdShift(vector, value); + // We need a temp register to mask the shift amount, but not if the shift + // amount is a constant. + LDefinition tempReg = value.isConstant() ? LDefinition::BogusTemp() : temp(); + LSimdShift* lir = new(alloc()) LSimdShift(vector, value, tempReg); defineReuseInput(lir, ins, 0); } @@ -4431,8 +4387,7 @@ LIRGenerator::visitLexicalCheck(MLexicalCheck* ins) { MDefinition* input = ins->input(); MOZ_ASSERT(input->type() == MIRType_Value); - LLexicalCheck* lir = new(alloc()) LLexicalCheck(); - useBox(lir, LLexicalCheck::Input, input); + LLexicalCheck* lir = new(alloc()) LLexicalCheck(useBox(input)); assignSnapshot(lir, ins->bailoutKind()); add(lir, ins); redefine(ins, input); @@ -4476,9 +4431,7 @@ LIRGenerator::visitCheckReturn(MCheckReturn* ins) MOZ_ASSERT(retVal->type() == MIRType_Value); MOZ_ASSERT(thisVal->type() == MIRType_Value); - LCheckReturn* lir = new(alloc()) LCheckReturn(); - useBoxAtStart(lir, LCheckReturn::ReturnValue, retVal); - useBoxAtStart(lir, LCheckReturn::ThisValue, thisVal); + LCheckReturn* lir = new(alloc()) LCheckReturn(useBoxAtStart(retVal), useBoxAtStart(thisVal)); assignSnapshot(lir, Bailout_BadDerivedConstructorReturn); add(lir, ins); redefine(ins, retVal); @@ -4490,8 +4443,7 @@ LIRGenerator::visitCheckObjCoercible(MCheckObjCoercible* ins) MDefinition* checkVal = ins->checkValue(); MOZ_ASSERT(checkVal->type() == MIRType_Value); - LCheckObjCoercible* lir = new(alloc()) LCheckObjCoercible(); - useBoxAtStart(lir, LCheckObjCoercible::CheckValue, checkVal); + LCheckObjCoercible* lir = new(alloc()) LCheckObjCoercible(useBoxAtStart(checkVal)); redefine(ins, checkVal); add(lir, ins); assignSafepoint(lir, ins); @@ -4503,8 +4455,7 @@ LIRGenerator::visitDebugCheckSelfHosted(MDebugCheckSelfHosted* ins) MDefinition* checkVal = ins->checkValue(); MOZ_ASSERT(checkVal->type() == MIRType_Value); - LDebugCheckSelfHosted* lir = new (alloc()) LDebugCheckSelfHosted(); - useBoxAtStart(lir, LDebugCheckSelfHosted::CheckValue, checkVal); + LDebugCheckSelfHosted* lir = new (alloc()) LDebugCheckSelfHosted(useBoxAtStart(checkVal)); redefine(ins, checkVal); add(lir, ins); assignSafepoint(lir, ins); diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index a929c877d2..01ee9d3431 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -49,10 +49,8 @@ class LIRGenerator : public LIRGeneratorSpecific bool generate(); private: - - void useBoxAtStart(LInstruction* lir, size_t n, MDefinition* mir, - LUse::Policy policy = LUse::REGISTER); - void useBoxFixedAtStart(LInstruction* lir, size_t n, MDefinition* mir, ValueOperand op); + LBoxAllocation useBoxFixedAtStart(MDefinition* mir, ValueOperand op); + LBoxAllocation useBoxAtStart(MDefinition* mir, LUse::Policy policy = LUse::REGISTER); void lowerBitOp(JSOp op, MInstruction* ins); void lowerShiftOp(JSOp op, MShiftInstruction* ins); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 938d947324..c5bfd3b48c 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -3158,10 +3158,6 @@ IonBuilder::inlineSimd(CallInfo& callInfo, JSFunction* target, SimdType type) return inlineSimdShift(callInfo, native, MSimdShift::lsh, type); case SimdOperation::Fn_shiftRightByScalar: return inlineSimdShift(callInfo, native, MSimdShift::rshForSign(GetSimdSign(type)), type); - case SimdOperation::Fn_shiftRightArithmeticByScalar: - return inlineSimdShift(callInfo, native, MSimdShift::rsh, type); - case SimdOperation::Fn_shiftRightLogicalByScalar: - return inlineSimdShift(callInfo, native, MSimdShift::ursh, type); // Boolean unary. case SimdOperation::Fn_allTrue: diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 1ae434763d..bb6f1f968e 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -672,6 +672,12 @@ class MacroAssembler : public MacroAssemblerSpecific CodeOffset selfReferencePatch_; public: + // =============================================================== + // Move instructions + + inline void move64(Imm64 imm, Register64 dest) PER_ARCH; + inline void move64(Register64 src, Register64 dest) PER_ARCH; + // =============================================================== // Logical instructions diff --git a/js/src/jit/arm/LIR-arm.h b/js/src/jit/arm/LIR-arm.h index a88bc0b422..6ccf5588e5 100644 --- a/js/src/jit/arm/LIR-arm.h +++ b/js/src/jit/arm/LIR-arm.h @@ -60,9 +60,11 @@ class LUnboxFloatingPoint : public LInstructionHelper<1, 2, 0> static const size_t Input = 0; - LUnboxFloatingPoint(MIRType type) + LUnboxFloatingPoint(const LBoxAllocation& input, MIRType type) : type_(type) - { } + { + setBoxOperand(Input, input); + } MUnbox* mir() const { return mir_->toUnbox(); @@ -301,9 +303,10 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 2> public: LIR_HEADER(TableSwitchV); - LTableSwitchV(const LDefinition& inputCopy, const LDefinition& floatCopy, - MTableSwitch* ins) + LTableSwitchV(const LBoxAllocation& input, const LDefinition& inputCopy, + const LDefinition& floatCopy, MTableSwitch* ins) { + setBoxOperand(InputValue, input); setTemp(0, inputCopy); setTemp(1, floatCopy); setMir(ins); diff --git a/js/src/jit/arm/Lowering-arm.cpp b/js/src/jit/arm/Lowering-arm.cpp index ed15a6fb51..2e8479e8b8 100644 --- a/js/src/jit/arm/Lowering-arm.cpp +++ b/js/src/jit/arm/Lowering-arm.cpp @@ -17,16 +17,15 @@ using namespace js::jit; using mozilla::FloorLog2; -void -LIRGeneratorARM::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, - Register reg2, bool useAtStart) +LBoxAllocation +LIRGeneratorARM::useBoxFixed(MDefinition* mir, Register reg1, Register reg2, bool useAtStart) { MOZ_ASSERT(mir->type() == MIRType_Value); MOZ_ASSERT(reg1 != reg2); ensureDefined(mir); - lir->setOperand(n, LUse(reg1, mir->virtualRegister(), useAtStart)); - lir->setOperand(n + 1, LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart)); + return LBoxAllocation(LUse(reg1, mir->virtualRegister(), useAtStart), + LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart)); } LAllocation @@ -108,10 +107,9 @@ LIRGeneratorARM::visitUnbox(MUnbox* unbox) ensureDefined(inner); if (IsFloatingPointType(unbox->type())) { - LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(unbox->type()); + LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(useBox(inner), unbox->type()); if (unbox->fallible()) assignSnapshot(lir, unbox->bailoutKind()); - useBox(lir, LUnboxFloatingPoint::Input, inner); define(lir, unbox); return; } @@ -345,7 +343,8 @@ LIRGeneratorARM::newLTableSwitch(const LAllocation& in, const LDefinition& input LTableSwitchV* LIRGeneratorARM::newLTableSwitchV(MTableSwitch* tableswitch) { - return new(alloc()) LTableSwitchV(temp(), tempDouble(), tableswitch); + return new(alloc()) LTableSwitchV(useBox(tableswitch->getOperand(0)), + temp(), tempDouble(), tableswitch); } void diff --git a/js/src/jit/arm/Lowering-arm.h b/js/src/jit/arm/Lowering-arm.h index cf1a338975..44e3a8539c 100644 --- a/js/src/jit/arm/Lowering-arm.h +++ b/js/src/jit/arm/Lowering-arm.h @@ -20,10 +20,9 @@ class LIRGeneratorARM : public LIRGeneratorShared { } protected: - // Adds a box input to an instruction, setting operand |n| to the type and - // |n+1| to the payload. - void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2, - bool useAtStart = false); + // Returns a box allocation with type set to reg1 and payload set to reg2. + LBoxAllocation useBoxFixed(MDefinition* mir, Register reg1, Register reg2, + bool useAtStart = false); // x86 has constraints on what registers can be formatted for 1-byte // stores and loads; on ARM all registers are okay. diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 9deead6bd9..de1adb1b7b 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -13,6 +13,21 @@ namespace js { namespace jit { //{{{ check_macroassembler_style + +void +MacroAssembler::move64(Register64 src, Register64 dest) +{ + move32(src.low, dest.low); + move32(src.high, dest.high); +} + +void +MacroAssembler::move64(Imm64 imm, Register64 dest) +{ + move32(Imm32(imm.value & 0xFFFFFFFFL), dest.low); + move32(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high); +} + // =============================================================== // Logical instructions diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 327ede9a24..68cd6fb94a 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -1016,10 +1016,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void movePtr(ImmPtr imm, Register dest); void movePtr(wasm::SymbolicAddress imm, Register dest); void movePtr(ImmGCPtr imm, Register dest); - void move64(Register64 src, Register64 dest) { - move32(src.low, dest.low); - move32(src.high, dest.high); - } void load8SignExtend(const Address& address, Register dest); void load8SignExtend(const BaseIndex& src, Register dest); diff --git a/js/src/jit/arm64/LIR-arm64.h b/js/src/jit/arm64/LIR-arm64.h index dc729bfd75..a10e2d6eff 100644 --- a/js/src/jit/arm64/LIR-arm64.h +++ b/js/src/jit/arm64/LIR-arm64.h @@ -282,9 +282,10 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 2> public: LIR_HEADER(TableSwitchV); - LTableSwitchV(const LDefinition& inputCopy, const LDefinition& floatCopy, - MTableSwitch* ins) + LTableSwitchV(const LBoxAllocation& input, const LDefinition& inputCopy, + const LDefinition& floatCopy, MTableSwitch* ins) { + setBoxOperand(InputValue, input); setTemp(0, inputCopy); setTemp(1, floatCopy); setMir(ins); diff --git a/js/src/jit/arm64/Lowering-arm64.cpp b/js/src/jit/arm64/Lowering-arm64.cpp index 7d329834e4..b1a9136837 100644 --- a/js/src/jit/arm64/Lowering-arm64.cpp +++ b/js/src/jit/arm64/Lowering-arm64.cpp @@ -17,8 +17,8 @@ using namespace js::jit; using mozilla::FloorLog2; -void -LIRGeneratorARM64::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register, bool useAtStart) +LBoxAllocation +LIRGeneratorARM64::useBoxFixed(MDefinition* mir, Register reg1, Register, bool useAtStart) { MOZ_CRASH("useBoxFixed"); } diff --git a/js/src/jit/arm64/Lowering-arm64.h b/js/src/jit/arm64/Lowering-arm64.h index a23eacd7d6..71407515ca 100644 --- a/js/src/jit/arm64/Lowering-arm64.h +++ b/js/src/jit/arm64/Lowering-arm64.h @@ -20,10 +20,9 @@ class LIRGeneratorARM64 : public LIRGeneratorShared { } protected: - // Adds a box input to an instruction, setting operand |n| to the type and - // |n+1| to the payload. - void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2, - bool useAtStart = false); + // Returns a box allocation. reg2 is ignored on 64-bit platforms. + LBoxAllocation useBoxFixed(MDefinition* mir, Register reg1, Register reg2, + bool useAtStart = false); LAllocation useByteOpRegister(MDefinition* mir); LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition* mir); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 84589aa3a6..0ae3ff114a 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -13,6 +13,19 @@ namespace js { namespace jit { //{{{ check_macroassembler_style + +void +MacroAssembler::move64(Register64 src, Register64 dest) +{ + movePtr(src.reg, dest.reg); +} + +void +MacroAssembler::move64(Imm64 imm, Register64 dest) +{ + movePtr(ImmWord(imm.value), dest.reg); +} + // =============================================================== // Logical instructions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 8678314752..b5ca6a4c7d 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -763,9 +763,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler BufferOffset load = movePatchablePtr(ImmPtr(imm.value), dest); writeDataRelocation(imm, load); } - void move64(Register64 src, Register64 dest) { - movePtr(src.reg, dest.reg); - } void mov(ImmWord imm, Register dest) { movePtr(imm, dest); diff --git a/js/src/jit/mips-shared/LIR-mips-shared.h b/js/src/jit/mips-shared/LIR-mips-shared.h index 8ddbaa9cd6..a43e5455e0 100644 --- a/js/src/jit/mips-shared/LIR-mips-shared.h +++ b/js/src/jit/mips-shared/LIR-mips-shared.h @@ -182,9 +182,11 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 3> public: LIR_HEADER(TableSwitchV); - LTableSwitchV(const LDefinition& inputCopy, const LDefinition& floatCopy, - const LDefinition& jumpTablePointer, MTableSwitch* ins) + LTableSwitchV(const LBoxAllocation& input, const LDefinition& inputCopy, + const LDefinition& floatCopy, const LDefinition& jumpTablePointer, + MTableSwitch* ins) { + setBoxOperand(InputValue, input); setTemp(0, inputCopy); setTemp(1, floatCopy); setTemp(2, jumpTablePointer); diff --git a/js/src/jit/mips-shared/Lowering-mips-shared.cpp b/js/src/jit/mips-shared/Lowering-mips-shared.cpp index 1295f2d1cb..6c7c16c70b 100644 --- a/js/src/jit/mips-shared/Lowering-mips-shared.cpp +++ b/js/src/jit/mips-shared/Lowering-mips-shared.cpp @@ -106,7 +106,7 @@ LIRGeneratorMIPSShared::lowerDivI(MDiv* div) // Division instructions are slow. Division by constant denominators can be // rewritten to use other instructions. if (div->rhs()->isConstant()) { - int32_t rhs = div->rhs()->toConstant()->value().toInt32(); + int32_t rhs = div->rhs()->toConstant()->toInt32(); // Check for division by a positive power of two, which is an easy and // important case to optimize. Note that other optimizations are also // possible; division by negative powers of two can be optimized in a @@ -147,7 +147,7 @@ LIRGeneratorMIPSShared::lowerModI(MMod* mod) } if (mod->rhs()->isConstant()) { - int32_t rhs = mod->rhs()->toConstant()->value().toInt32(); + int32_t rhs = mod->rhs()->toConstant()->toInt32(); int32_t shift = FloorLog2(rhs); if (rhs > 0 && 1 << shift == rhs) { LModPowTwoI* lir = new(alloc()) LModPowTwoI(useRegister(mod->lhs()), shift); @@ -193,7 +193,8 @@ LIRGeneratorMIPSShared::newLTableSwitch(const LAllocation& in, const LDefinition LTableSwitchV* LIRGeneratorMIPSShared::newLTableSwitchV(MTableSwitch* tableswitch) { - return new(alloc()) LTableSwitchV(temp(), tempDouble(), temp(), tableswitch); + return new(alloc()) LTableSwitchV(useBox(tableswitch->getOperand(0)), + temp(), tempDouble(), temp(), tableswitch); } void @@ -301,10 +302,10 @@ LIRGeneratorMIPSShared::visitAsmJSLoadHeap(MAsmJSLoadHeap* ins) // For MIPS it is best to keep the 'ptr' in a register if a bounds check // is needed. - if (ptr->isConstantValue() && !ins->needsBoundsCheck()) { + if (ptr->isConstant() && !ins->needsBoundsCheck()) { // A bounds check is only skipped for a positive index. - MOZ_ASSERT(ptr->constantValue().toInt32() >= 0); - ptrAlloc = LAllocation(ptr->constantVp()); + MOZ_ASSERT(ptr->toConstant()->toInt32() >= 0); + ptrAlloc = LAllocation(ptr->toConstant()); } else ptrAlloc = useRegisterAtStart(ptr); @@ -318,9 +319,9 @@ LIRGeneratorMIPSShared::visitAsmJSStoreHeap(MAsmJSStoreHeap* ins) MOZ_ASSERT(ptr->type() == MIRType_Int32); LAllocation ptrAlloc; - if (ptr->isConstantValue() && !ins->needsBoundsCheck()) { - MOZ_ASSERT(ptr->constantValue().toInt32() >= 0); - ptrAlloc = LAllocation(ptr->constantVp()); + if (ptr->isConstant() && !ins->needsBoundsCheck()) { + MOZ_ASSERT(ptr->toConstant()->toInt32() >= 0); + ptrAlloc = LAllocation(ptr->toConstant()); } else ptrAlloc = useRegisterAtStart(ptr); diff --git a/js/src/jit/mips32/LIR-mips32.h b/js/src/jit/mips32/LIR-mips32.h index 765deffc4c..c920148c22 100644 --- a/js/src/jit/mips32/LIR-mips32.h +++ b/js/src/jit/mips32/LIR-mips32.h @@ -60,9 +60,11 @@ class LUnboxFloatingPoint : public LInstructionHelper<1, 2, 0> static const size_t Input = 0; - LUnboxFloatingPoint(MIRType type) + LUnboxFloatingPoint(const LBoxAllocation& input, MIRType type) : type_(type) - { } + { + setBoxOperand(Input, input); + } MUnbox* mir() const { return mir_->toUnbox(); diff --git a/js/src/jit/mips32/Lowering-mips32.cpp b/js/src/jit/mips32/Lowering-mips32.cpp index aa9a55795b..515acfdbdb 100644 --- a/js/src/jit/mips32/Lowering-mips32.cpp +++ b/js/src/jit/mips32/Lowering-mips32.cpp @@ -15,16 +15,15 @@ using namespace js; using namespace js::jit; -void -LIRGeneratorMIPS::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, - Register reg2, bool useAtStart) +LBoxAllocation +LIRGeneratorMIPS::useBoxFixed(MDefinition* mir, Register reg1, Register reg2, bool useAtStart) { MOZ_ASSERT(mir->type() == MIRType_Value); MOZ_ASSERT(reg1 != reg2); ensureDefined(mir); - lir->setOperand(n, LUse(reg1, mir->virtualRegister(), useAtStart)); - lir->setOperand(n + 1, LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart)); + return LBoxAllocation(LUse(reg1, mir->virtualRegister(), useAtStart), + LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart)); } void @@ -45,7 +44,7 @@ LIRGeneratorMIPS::visitBox(MBox* box) } if (inner->isConstant()) { - defineBox(new(alloc()) LValue(inner->toConstant()->value()), box); + defineBox(new(alloc()) LValue(inner->toConstant()->toJSValue()), box); return; } @@ -88,10 +87,9 @@ LIRGeneratorMIPS::visitUnbox(MUnbox* unbox) ensureDefined(inner); if (IsFloatingPointType(unbox->type())) { - LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(unbox->type()); + LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(useBox(inner), unbox->type()); if (unbox->fallible()) assignSnapshot(lir, unbox->bailoutKind()); - useBox(lir, LUnboxFloatingPoint::Input, inner); define(lir, unbox); return; } diff --git a/js/src/jit/mips32/Lowering-mips32.h b/js/src/jit/mips32/Lowering-mips32.h index 2871e83624..9d1d330f42 100644 --- a/js/src/jit/mips32/Lowering-mips32.h +++ b/js/src/jit/mips32/Lowering-mips32.h @@ -20,10 +20,9 @@ class LIRGeneratorMIPS : public LIRGeneratorMIPSShared { } protected: - // Adds a box input to an instruction, setting operand |n| to the type and - // |n+1| to the payload. - void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2, - bool useAtStart = false); + // Returns a box allocation with type set to reg1 and payload set to reg2. + LBoxAllocation useBoxFixed(MDefinition* mir, Register reg1, Register reg2, + bool useAtStart = false); inline LDefinition tempToUnbox() { return LDefinition::BogusTemp(); diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 327d26a0c2..4697fc0615 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -15,6 +15,21 @@ namespace js { namespace jit { //{{{ check_macroassembler_style + +void +MacroAssembler::move64(Register64 src, Register64 dest) +{ + move32(src.low, dest.low); + move32(src.high, dest.high); +} + +void +MacroAssembler::move64(Imm64 imm, Register64 dest) +{ + move32(Imm32(imm.value & 0xFFFFFFFFL), dest.low); + move32(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high); +} + // =============================================================== // Logical instructions diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 9116002eba..bfc110c1be 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -936,10 +936,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void move32(Imm32 imm, Register dest); void move32(Register src, Register dest); - void move64(Register64 src, Register64 dest) { - move32(src.low, dest.low); - move32(src.high, dest.high); - } void movePtr(Register src, Register dest); void movePtr(ImmWord imm, Register dest); diff --git a/js/src/jit/mips64/CodeGenerator-mips64.cpp b/js/src/jit/mips64/CodeGenerator-mips64.cpp index 91094ef034..88847a6e12 100644 --- a/js/src/jit/mips64/CodeGenerator-mips64.cpp +++ b/js/src/jit/mips64/CodeGenerator-mips64.cpp @@ -222,7 +222,7 @@ CodeGeneratorMIPS64::visitCompareB(LCompareB* lir) // Load boxed boolean in ScratchRegister. if (rhs->isConstant()) - masm.moveValue(*rhs->toConstant(), ScratchRegister); + masm.moveValue(rhs->toConstant()->toJSValue(), ScratchRegister); else masm.boxValue(JSVAL_TYPE_BOOLEAN, ToRegister(rhs), ScratchRegister); @@ -241,7 +241,7 @@ CodeGeneratorMIPS64::visitCompareBAndBranch(LCompareBAndBranch* lir) // Load boxed boolean in ScratchRegister. if (rhs->isConstant()) - masm.moveValue(*rhs->toConstant(), ScratchRegister); + masm.moveValue(rhs->toConstant()->toJSValue(), ScratchRegister); else masm.boxValue(JSVAL_TYPE_BOOLEAN, ToRegister(rhs), ScratchRegister); diff --git a/js/src/jit/mips64/Lowering-mips64.cpp b/js/src/jit/mips64/Lowering-mips64.cpp index f407bfbee7..df01c0b602 100644 --- a/js/src/jit/mips64/Lowering-mips64.cpp +++ b/js/src/jit/mips64/Lowering-mips64.cpp @@ -15,14 +15,13 @@ using namespace js; using namespace js::jit; -void -LIRGeneratorMIPS64::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, - Register reg2, bool useAtStart) +LBoxAllocation +LIRGeneratorMIPS64::useBoxFixed(MDefinition* mir, Register reg1, Register reg2, bool useAtStart) { MOZ_ASSERT(mir->type() == MIRType_Value); ensureDefined(mir); - lir->setOperand(n, LUse(reg1, mir->virtualRegister(), useAtStart)); + return LBoxAllocation(LUse(reg1, mir->virtualRegister(), useAtStart)); } void @@ -37,7 +36,7 @@ LIRGeneratorMIPS64::visitBox(MBox* box) } if (opd->isConstant()) { - define(new(alloc()) LValue(opd->toConstant()->value()), box, LDefinition(LDefinition::BOX)); + define(new(alloc()) LValue(opd->toConstant()->toJSValue()), box, LDefinition(LDefinition::BOX)); } else { LBox* ins = new(alloc()) LBox(useRegister(opd), opd->type()); define(ins, box, LDefinition(LDefinition::BOX)); diff --git a/js/src/jit/mips64/Lowering-mips64.h b/js/src/jit/mips64/Lowering-mips64.h index 77eba96ab1..0510d7edfc 100644 --- a/js/src/jit/mips64/Lowering-mips64.h +++ b/js/src/jit/mips64/Lowering-mips64.h @@ -20,10 +20,9 @@ class LIRGeneratorMIPS64 : public LIRGeneratorMIPSShared { } protected: - // Adds a box input to an instruction, setting operand |n| to the type and - // |n+1| to the payload. - void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2, - bool useAtStart = false); + // Returns a box allocation. reg2 is ignored on 64-bit platforms. + LBoxAllocation useBoxFixed(MDefinition* mir, Register reg1, Register reg2, + bool useAtStart = false); inline LDefinition tempToUnbox() { return temp(); diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index ae923aba8e..b9a7e357e8 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -15,6 +15,19 @@ namespace js { namespace jit { //{{{ check_macroassembler_style + +void +MacroAssembler::move64(Register64 src, Register64 dest) +{ + movePtr(src.reg, dest.reg); +} + +void +MacroAssembler::move64(Imm64 imm, Register64 dest) +{ + movePtr(ImmWord(imm.value), dest.reg); +} + // =============================================================== // Logical instructions diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index a2448565bd..7833e041fd 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -950,9 +950,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void move32(Imm32 imm, Register dest); void move32(Register src, Register dest); - void move64(Register64 src, Register64 dest) { - movePtr(src.reg, dest.reg); - } void movePtr(Register src, Register dest); void movePtr(ImmWord imm, Register dest); diff --git a/js/src/jit/none/Lowering-none.h b/js/src/jit/none/Lowering-none.h index 64e6565b98..f1a0910342 100644 --- a/js/src/jit/none/Lowering-none.h +++ b/js/src/jit/none/Lowering-none.h @@ -21,7 +21,7 @@ class LIRGeneratorNone : public LIRGeneratorShared MOZ_CRASH(); } - void useBoxFixed(LInstruction*, size_t, MDefinition*, Register, Register, bool useAtStart = false) { MOZ_CRASH(); } + LBoxAllocation useBoxFixed(MDefinition*, Register, Register, bool useAtStart = false) { MOZ_CRASH(); } LAllocation useByteOpRegister(MDefinition*) { MOZ_CRASH(); } LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition*) { MOZ_CRASH(); } diff --git a/js/src/jit/shared/CodeGenerator-shared-inl.h b/js/src/jit/shared/CodeGenerator-shared-inl.h index 2283653442..cbb5e326b4 100644 --- a/js/src/jit/shared/CodeGenerator-shared-inl.h +++ b/js/src/jit/shared/CodeGenerator-shared-inl.h @@ -50,6 +50,18 @@ ToRegister(const LDefinition* def) return ToRegister(*def->output()); } +static inline Register64 +ToOutRegister64(LInstruction* ins) +{ +#if JS_BITS_PER_WORD == 32 + Register loReg = ToRegister(ins->getDef(0)); + Register hiReg = ToRegister(ins->getDef(1)); + return Register64(hiReg, loReg); +#else + return Register64(ToRegister(ins->getDef(0))); +#endif +} + static inline Register ToTempRegisterOrInvalid(const LDefinition* def) { diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index 58b5555504..c29ab2ee0c 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -578,13 +578,17 @@ class LSimdBinaryBitwiseX4 : public LInstructionHelper<1, 2, 0> } }; -class LSimdShift : public LInstructionHelper<1, 2, 0> +// Shift a SIMD vector by a scalar amount. +// The temp register is only required if the shift amount is a dynamical +// value. If it is a constant, use a BogusTemp instead. +class LSimdShift : public LInstructionHelper<1, 2, 1> { public: LIR_HEADER(SimdShift) - LSimdShift(const LAllocation& vec, const LAllocation& val) { + LSimdShift(const LAllocation& vec, const LAllocation& val, const LDefinition& temp) { setOperand(0, vec); setOperand(1, val); + setTemp(0, temp); } const LAllocation* vector() { return getOperand(0); @@ -592,6 +596,9 @@ class LSimdShift : public LInstructionHelper<1, 2, 0> const LAllocation* value() { return getOperand(1); } + const LDefinition* temp() { + return getTemp(0); + } MSimdShift::Operation operation() const { return mir_->toSimdShift()->operation(); } @@ -674,6 +681,23 @@ class LInteger : public LInstructionHelper<1, 0, 0> } }; +// Constant 64-bit integer. +class LInteger64 : public LInstructionHelper +{ + int64_t i64_; + + public: + LIR_HEADER(Integer64) + + explicit LInteger64(int64_t i64) + : i64_(i64) + { } + + int64_t getValue() const { + return i64_; + } +}; + // Constant pointer. class LPointer : public LInstructionHelper<1, 0, 0> { @@ -1087,8 +1111,10 @@ class LInitElem : public LCallInstructionHelper<0, 1 + 2*BOX_PIECES, 0> public: LIR_HEADER(InitElem) - explicit LInitElem(const LAllocation& object) { + LInitElem(const LAllocation& object, const LBoxAllocation& id, const LBoxAllocation& value) { setOperand(0, object); + setBoxOperand(IdIndex, id); + setBoxOperand(ValueIndex, value); } static const size_t IdIndex = 1; @@ -1107,9 +1133,11 @@ class LInitElemGetterSetter : public LCallInstructionHelper<0, 2 + BOX_PIECES, 0 public: LIR_HEADER(InitElemGetterSetter) - LInitElemGetterSetter(const LAllocation& object, const LAllocation& value) { + LInitElemGetterSetter(const LAllocation& object, const LBoxAllocation& id, + const LAllocation& value) { setOperand(0, object); setOperand(1, value); + setBoxOperand(IdIndex, id); } static const size_t IdIndex = 2; @@ -1131,8 +1159,9 @@ class LMutateProto : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0> public: LIR_HEADER(MutateProto) - explicit LMutateProto(const LAllocation& object) { + LMutateProto(const LAllocation& object, const LBoxAllocation& value) { setOperand(0, object); + setBoxOperand(ValueIndex, value); } static const size_t ValueIndex = 1; @@ -1151,8 +1180,9 @@ class LInitProp : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0> public: LIR_HEADER(InitProp) - explicit LInitProp(const LAllocation& object) { + LInitProp(const LAllocation& object, const LBoxAllocation& value) { setOperand(0, object); + setBoxOperand(ValueIndex, value); } static const size_t ValueIndex = 1; @@ -1306,7 +1336,8 @@ class LTypeOfV : public LInstructionHelper<1, BOX_PIECES, 1> public: LIR_HEADER(TypeOfV) - explicit LTypeOfV(const LDefinition& tempToUnbox) { + LTypeOfV(const LBoxAllocation& input, const LDefinition& tempToUnbox) { + setBoxOperand(Input, input); setTemp(0, tempToUnbox); } @@ -1326,12 +1357,13 @@ class LToIdV : public LInstructionHelper public: LIR_HEADER(ToIdV) - explicit LToIdV(const LDefinition& temp) + LToIdV(const LBoxAllocation& input, const LDefinition& temp) { + setBoxOperand(Input, input); setTemp(0, temp); } - static const size_t Index = 0; + static const size_t Input = 0; MToId* mir() const { return mir_->toToId(); @@ -1465,9 +1497,11 @@ class LSetArgumentsObjectArg : public LInstructionHelper<0, 1 + BOX_PIECES, 1> public: LIR_HEADER(SetArgumentsObjectArg) - LSetArgumentsObjectArg(const LAllocation& argsObj, const LDefinition& temp) + LSetArgumentsObjectArg(const LAllocation& argsObj, const LBoxAllocation& value, + const LDefinition& temp) { setOperand(0, argsObj); + setBoxOperand(ValueIndex, value); setTemp(0, temp); } @@ -1489,14 +1523,14 @@ class LReturnFromCtor : public LInstructionHelper<1, BOX_PIECES + 1, 0> public: LIR_HEADER(ReturnFromCtor) - explicit LReturnFromCtor(const LAllocation& object) + LReturnFromCtor(const LBoxAllocation& value, const LAllocation& object) { - // Value set by useBox() during lowering. - setOperand(LReturnFromCtor::ObjectIndex, object); + setBoxOperand(ValueIndex, value); + setOperand(ObjectIndex, object); } const LAllocation* getObject() { - return getOperand(LReturnFromCtor::ObjectIndex); + return getOperand(ObjectIndex); } static const size_t ValueIndex = 0; @@ -1510,6 +1544,10 @@ class LComputeThis : public LInstructionHelper static const size_t ValueIndex = 0; + explicit LComputeThis(const LBoxAllocation& value) { + setBoxOperand(ValueIndex, value); + } + const LDefinition* output() { return getDef(0); } @@ -1553,9 +1591,11 @@ class LStackArgV : public LInstructionHelper<0, BOX_PIECES, 0> public: LIR_HEADER(StackArgV) - explicit LStackArgV(uint32_t argslot) + LStackArgV(uint32_t argslot, const LBoxAllocation& value) : argslot_(argslot) - { } + { + setBoxOperand(0, value); + } uint32_t argslot() const { return argslot_; @@ -1803,10 +1843,13 @@ class LSetDOMProperty : public LDOMPropertyInstructionHelper<0, BOX_PIECES> LIR_HEADER(SetDOMProperty) LSetDOMProperty(const LDefinition& JSContextReg, const LAllocation& ObjectReg, - const LDefinition& PrivReg, const LDefinition& ValueReg) + const LBoxAllocation& value, const LDefinition& PrivReg, + const LDefinition& ValueReg) : LDOMPropertyInstructionHelper<0, BOX_PIECES>(JSContextReg, ObjectReg, PrivReg, ValueReg) - { } + { + setBoxOperand(Value, value); + } static const size_t Value = 1; @@ -1823,10 +1866,12 @@ class LApplyArgsGeneric : public LCallInstructionHelper } }; -class LCallDirectEval : public LCallInstructionHelper +class LCallDirectEval : public LCallInstructionHelper { public: LIR_HEADER(CallDirectEval) - LCallDirectEval(const LAllocation& scopeChain, const LAllocation& string) + LCallDirectEval(const LAllocation& scopeChain, const LAllocation& string, + const LBoxAllocation& newTarget) { setOperand(0, scopeChain); setOperand(1, string); + setBoxOperand(NewTarget, newTarget); } - static const size_t ThisValue = 2; - static const size_t NewTarget = 2 + BOX_PIECES; + static const size_t NewTarget = 2; MCallDirectEval* mir() const { return mir_->toCallDirectEval(); @@ -2096,11 +2144,12 @@ class LTestVAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 3> public: LIR_HEADER(TestVAndBranch) - LTestVAndBranch(MBasicBlock* ifTruthy, MBasicBlock* ifFalsy, const LDefinition& temp0, - const LDefinition& temp1, const LDefinition& temp2) + LTestVAndBranch(MBasicBlock* ifTruthy, MBasicBlock* ifFalsy, const LBoxAllocation& input, + const LDefinition& temp0, const LDefinition& temp1, const LDefinition& temp2) { setSuccessor(0, ifTruthy); setSuccessor(1, ifFalsy); + setBoxOperand(Input, input); setTemp(0, temp0); setTemp(1, temp1); setTemp(2, temp2); @@ -2396,7 +2445,8 @@ class LCompareStrictS : public LInstructionHelper<1, BOX_PIECES + 1, 1> { public: LIR_HEADER(CompareStrictS) - LCompareStrictS(const LAllocation& rhs, const LDefinition& temp) { + LCompareStrictS(const LBoxAllocation& lhs, const LAllocation& rhs, const LDefinition& temp) { + setBoxOperand(Lhs, lhs); setOperand(BOX_PIECES, rhs); setTemp(0, temp); } @@ -2422,7 +2472,8 @@ class LCompareB : public LInstructionHelper<1, BOX_PIECES + 1, 0> public: LIR_HEADER(CompareB) - explicit LCompareB(const LAllocation& rhs) { + LCompareB(const LBoxAllocation& lhs, const LAllocation& rhs) { + setBoxOperand(Lhs, lhs); setOperand(BOX_PIECES, rhs); } @@ -2444,10 +2495,11 @@ class LCompareBAndBranch : public LControlInstructionHelper<2, BOX_PIECES + 1, 0 public: LIR_HEADER(CompareBAndBranch) - LCompareBAndBranch(MCompare* cmpMir, const LAllocation& rhs, + LCompareBAndBranch(MCompare* cmpMir, const LBoxAllocation& lhs, const LAllocation& rhs, MBasicBlock* ifTrue, MBasicBlock* ifFalse) : cmpMir_(cmpMir) { + setBoxOperand(Lhs, lhs); setOperand(BOX_PIECES, rhs); setSuccessor(0, ifTrue); setSuccessor(1, ifFalse); @@ -2481,6 +2533,11 @@ class LCompareBitwise : public LInstructionHelper<1, 2 * BOX_PIECES, 0> static const size_t LhsInput = 0; static const size_t RhsInput = BOX_PIECES; + LCompareBitwise(const LBoxAllocation& lhs, const LBoxAllocation& rhs) { + setBoxOperand(LhsInput, lhs); + setBoxOperand(RhsInput, rhs); + } + MCompare* mir() const { return mir_->toCompare(); } @@ -2496,11 +2553,14 @@ class LCompareBitwiseAndBranch : public LControlInstructionHelper<2, 2 * BOX_PIE static const size_t LhsInput = 0; static const size_t RhsInput = BOX_PIECES; - LCompareBitwiseAndBranch(MCompare* cmpMir, MBasicBlock* ifTrue, MBasicBlock* ifFalse) + LCompareBitwiseAndBranch(MCompare* cmpMir, MBasicBlock* ifTrue, MBasicBlock* ifFalse, + const LBoxAllocation& lhs, const LBoxAllocation& rhs) : cmpMir_(cmpMir) { setSuccessor(0, ifTrue); setSuccessor(1, ifFalse); + setBoxOperand(LhsInput, lhs); + setBoxOperand(RhsInput, rhs); } MBasicBlock* ifTrue() const { @@ -2525,6 +2585,11 @@ class LCompareVM : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0> static const size_t LhsInput = 0; static const size_t RhsInput = BOX_PIECES; + LCompareVM(const LBoxAllocation& lhs, const LBoxAllocation& rhs) { + setBoxOperand(LhsInput, lhs); + setBoxOperand(RhsInput, rhs); + } + MCompare* mir() const { return mir_->toCompare(); } @@ -2562,8 +2627,10 @@ class LIsNullOrLikeUndefinedV : public LInstructionHelper<1, BOX_PIECES, 2> public: LIR_HEADER(IsNullOrLikeUndefinedV) - LIsNullOrLikeUndefinedV(const LDefinition& temp, const LDefinition& tempToUnbox) + LIsNullOrLikeUndefinedV(const LBoxAllocation& value, const LDefinition& temp, + const LDefinition& tempToUnbox) { + setBoxOperand(Value, value); setTemp(0, temp); setTemp(1, tempToUnbox); } @@ -2608,11 +2675,13 @@ class LIsNullOrLikeUndefinedAndBranchV : public LControlInstructionHelper<2, BOX LIR_HEADER(IsNullOrLikeUndefinedAndBranchV) LIsNullOrLikeUndefinedAndBranchV(MCompare* cmpMir, MBasicBlock* ifTrue, MBasicBlock* ifFalse, - const LDefinition& temp, const LDefinition& tempToUnbox) + const LBoxAllocation& value, const LDefinition& temp, + const LDefinition& tempToUnbox) : cmpMir_(cmpMir) { setSuccessor(0, ifTrue); setSuccessor(1, ifFalse); + setBoxOperand(Value, value); setTemp(0, temp); setTemp(1, tempToUnbox); } @@ -2738,8 +2807,10 @@ class LNotV : public LInstructionHelper<1, BOX_PIECES, 3> LIR_HEADER(NotV) static const size_t Input = 0; - LNotV(const LDefinition& temp0, const LDefinition& temp1, const LDefinition& temp2) + LNotV(const LBoxAllocation& input, const LDefinition& temp0, const LDefinition& temp1, + const LDefinition& temp2) { + setBoxOperand(Input, input); setTemp(0, temp0); setTemp(1, temp1); setTemp(2, temp2); @@ -2777,6 +2848,10 @@ class LBitNotV : public LCallInstructionHelper<1, BOX_PIECES, 0> LIR_HEADER(BitNotV) static const size_t Input = 0; + + explicit LBitNotV(const LBoxAllocation& input) { + setBoxOperand(Input, input); + } }; // Binary bitwise operation, taking two 32-bit integers as inputs and returning @@ -2811,9 +2886,12 @@ class LBitOpV : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0> public: LIR_HEADER(BitOpV) - explicit LBitOpV(JSOp jsop) + LBitOpV(JSOp jsop, const LBoxAllocation& lhs, const LBoxAllocation& rhs) : jsop_(jsop) - { } + { + setBoxOperand(LhsInput, lhs); + setBoxOperand(RhsInput, rhs); + } JSOp jsop() const { return jsop_; @@ -2882,6 +2960,10 @@ class LThrow : public LCallInstructionHelper<0, BOX_PIECES, 0> LIR_HEADER(Throw) static const size_t Value = 0; + + explicit LThrow(const LBoxAllocation& value) { + setBoxOperand(Value, value); + } }; class LMinMaxBase : public LInstructionHelper<1, 2, 0> @@ -3314,9 +3396,12 @@ class LBinaryV : public LCallInstructionHelper public: LIR_HEADER(BinaryV) - explicit LBinaryV(JSOp jsop) + LBinaryV(JSOp jsop, const LBoxAllocation& lhs, const LBoxAllocation& rhs) : jsop_(jsop) - { } + { + setBoxOperand(LhsInput, lhs); + setBoxOperand(RhsInput, rhs); + } JSOp jsop() const { return jsop_; @@ -3547,6 +3632,10 @@ class LValueToDouble : public LInstructionHelper<1, BOX_PIECES, 0> LIR_HEADER(ValueToDouble) static const size_t Input = 0; + explicit LValueToDouble(const LBoxAllocation& input) { + setBoxOperand(Input, input); + } + MToDouble* mir() { return mir_->toToDouble(); } @@ -3559,6 +3648,10 @@ class LValueToFloat32 : public LInstructionHelper<1, BOX_PIECES, 0> LIR_HEADER(ValueToFloat32) static const size_t Input = 0; + explicit LValueToFloat32(const LBoxAllocation& input) { + setBoxOperand(Input, input); + } + MToFloat32* mir() { return mir_->toToFloat32(); } @@ -3585,9 +3678,11 @@ class LValueToInt32 : public LInstructionHelper<1, BOX_PIECES, 2> public: LIR_HEADER(ValueToInt32) - LValueToInt32(const LDefinition& temp0, const LDefinition& temp1, Mode mode) + LValueToInt32(const LBoxAllocation& input, const LDefinition& temp0, const LDefinition& temp1, + Mode mode) : mode_(mode) { + setBoxOperand(Input, input); setTemp(0, temp0); setTemp(1, temp1); } @@ -3755,8 +3850,9 @@ class LValueToString : public LInstructionHelper<1, BOX_PIECES, 1> public: LIR_HEADER(ValueToString) - explicit LValueToString(const LDefinition& tempToUnbox) + LValueToString(const LBoxAllocation& input, const LDefinition& tempToUnbox) { + setBoxOperand(Input, input); setTemp(0, tempToUnbox); } @@ -3777,8 +3873,9 @@ class LValueToObjectOrNull : public LInstructionHelper<1, BOX_PIECES, 0> public: LIR_HEADER(ValueToObjectOrNull) - explicit LValueToObjectOrNull() - {} + explicit LValueToObjectOrNull(const LBoxAllocation& input) { + setBoxOperand(Input, input); + } static const size_t Input = 0; @@ -4093,6 +4190,11 @@ class LBinarySharedStub : public LCallInstructionHelpertoBinarySharedStub(); } @@ -4106,6 +4208,10 @@ class LUnarySharedStub : public LCallInstructionHelpertoUnarySharedStub(); } @@ -4157,8 +4263,9 @@ class LLambdaArrow : public LInstructionHelper<1, 1 + BOX_PIECES, 0> static const size_t NewTargetValue = 1; - explicit LLambdaArrow(const LAllocation& scopeChain) { + LLambdaArrow(const LAllocation& scopeChain, const LBoxAllocation& newTarget) { setOperand(0, scopeChain); + setBoxOperand(NewTargetValue, newTarget); } const LAllocation* scopeChain() { return getOperand(0); @@ -4795,9 +4902,11 @@ class LStoreElementV : public LInstructionHelper<0, 2 + BOX_PIECES, 0> public: LIR_HEADER(StoreElementV) - LStoreElementV(const LAllocation& elements, const LAllocation& index) { + LStoreElementV(const LAllocation& elements, const LAllocation& index, + const LBoxAllocation& value) { setOperand(0, elements); setOperand(1, index); + setBoxOperand(Value, value); } const char* extraName() const { @@ -4857,10 +4966,12 @@ class LStoreElementHoleV : public LInstructionHelper<0, 3 + BOX_PIECES, 1> LIR_HEADER(StoreElementHoleV) LStoreElementHoleV(const LAllocation& object, const LAllocation& elements, - const LAllocation& index, const LDefinition& temp) { + const LAllocation& index, const LBoxAllocation& value, + const LDefinition& temp) { setOperand(0, object); setOperand(1, elements); setOperand(2, index); + setBoxOperand(Value, value); setTemp(0, temp); } @@ -5019,8 +5130,9 @@ class LArrayPushV : public LInstructionHelper<1, 1 + BOX_PIECES, 1> public: LIR_HEADER(ArrayPushV) - LArrayPushV(const LAllocation& object, const LDefinition& temp) { + LArrayPushV(const LAllocation& object, const LBoxAllocation& value, const LDefinition& temp) { setOperand(0, object); + setBoxOperand(Value, value); setTemp(0, temp); } @@ -5582,7 +5694,8 @@ class LClampVToUint8 : public LInstructionHelper<1, BOX_PIECES, 1> public: LIR_HEADER(ClampVToUint8) - explicit LClampVToUint8(const LDefinition& tempFloat) { + LClampVToUint8(const LBoxAllocation& input, const LDefinition& tempFloat) { + setBoxOperand(Input, input); setTemp(0, tempFloat); } @@ -5644,8 +5757,9 @@ class LStoreFixedSlotV : public LInstructionHelper<0, 1 + BOX_PIECES, 0> public: LIR_HEADER(StoreFixedSlotV) - explicit LStoreFixedSlotV(const LAllocation& obj) { + LStoreFixedSlotV(const LAllocation& obj, const LBoxAllocation& value) { setOperand(0, obj); + setBoxOperand(Value, value); } static const size_t Value = 1; @@ -5716,8 +5830,9 @@ class LGetPropertyCacheV : public LInstructionHelpertoGetPropertyCache(); @@ -5733,8 +5848,9 @@ class LGetPropertyCacheT : public LInstructionHelper<1, 1 + BOX_PIECES, 0> static const size_t Id = 1; - explicit LGetPropertyCacheT(const LAllocation& object) { + LGetPropertyCacheT(const LAllocation& object, const LBoxAllocation& id) { setOperand(0, object); + setBoxOperand(Id, id); } const MGetPropertyCache* mir() const { return mir_->toGetPropertyCache(); @@ -5788,8 +5904,10 @@ class LSetPropertyPolymorphicV : public LInstructionHelper<0, 1 + BOX_PIECES, 1> public: LIR_HEADER(SetPropertyPolymorphicV) - LSetPropertyPolymorphicV(const LAllocation& obj, const LDefinition& temp) { + LSetPropertyPolymorphicV(const LAllocation& obj, const LBoxAllocation& value, + const LDefinition& temp) { setOperand(0, obj); + setBoxOperand(Value, value); setTemp(0, temp); } @@ -5918,8 +6036,9 @@ class LStoreSlotV : public LInstructionHelper<0, 1 + BOX_PIECES, 0> public: LIR_HEADER(StoreSlotV) - explicit LStoreSlotV(const LAllocation& slots) { + LStoreSlotV(const LAllocation& slots, const LBoxAllocation& value) { setOperand(0, slots); + setBoxOperand(Value, value); } static const size_t Value = 1; @@ -6076,6 +6195,10 @@ class LCallGetProperty : public LCallInstructionHelpertoCallGetProperty(); } @@ -6090,6 +6213,11 @@ class LCallGetElement : public LCallInstructionHelpertoCallGetElement(); } @@ -6104,6 +6232,13 @@ class LCallSetElement : public LCallInstructionHelper<0, 1 + 2 * BOX_PIECES, 0> static const size_t Index = 1; static const size_t Value = 1 + BOX_PIECES; + LCallSetElement(const LAllocation& obj, const LBoxAllocation& index, + const LBoxAllocation& value) { + setOperand(0, obj); + setBoxOperand(Index, index); + setBoxOperand(Value, value); + } + const MCallSetElement* mir() const { return mir_->toCallSetElement(); } @@ -6117,6 +6252,11 @@ public: static const size_t Value = 1; + LCallInitElementArray(const LAllocation& obj, const LBoxAllocation& value) { + setOperand(0, obj); + setBoxOperand(Value, value); + } + const MCallInitElementArray* mir() const { return mir_->toCallInitElementArray(); } @@ -6128,8 +6268,9 @@ class LCallSetProperty : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0> public: LIR_HEADER(CallSetProperty) - explicit LCallSetProperty(const LAllocation& obj) { + LCallSetProperty(const LAllocation& obj, const LBoxAllocation& value) { setOperand(0, obj); + setBoxOperand(Value, value); } static const size_t Value = 1; @@ -6146,6 +6287,10 @@ class LCallDeleteProperty : public LCallInstructionHelper<1, BOX_PIECES, 0> static const size_t Value = 0; + explicit LCallDeleteProperty(const LBoxAllocation& value) { + setBoxOperand(Value, value); + } + MDeleteProperty* mir() const { return mir_->toDeleteProperty(); } @@ -6159,6 +6304,11 @@ class LCallDeleteElement : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0> static const size_t Value = 0; static const size_t Index = BOX_PIECES; + LCallDeleteElement(const LBoxAllocation& value, const LBoxAllocation& index) { + setBoxOperand(Value, value); + setBoxOperand(Index, index); + } + MDeleteElement* mir() const { return mir_->toDeleteElement(); } @@ -6170,10 +6320,13 @@ class LSetPropertyCache : public LInstructionHelper<0, 1 + 2 * BOX_PIECES, 4> public: LIR_HEADER(SetPropertyCache) - LSetPropertyCache(const LAllocation& object, const LDefinition& temp, + LSetPropertyCache(const LAllocation& object, const LBoxAllocation& id, + const LBoxAllocation& value, const LDefinition& temp, const LDefinition& tempToUnboxIndex, const LDefinition& tempDouble, const LDefinition& tempFloat32) { setOperand(0, object); + setBoxOperand(Id, id); + setBoxOperand(Value, value); setTemp(0, temp); setTemp(1, tempToUnboxIndex); setTemp(2, tempDouble); @@ -6273,9 +6426,10 @@ class LIsNoIterAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 0> public: LIR_HEADER(IsNoIterAndBranch) - LIsNoIterAndBranch(MBasicBlock* ifTrue, MBasicBlock* ifFalse) { + LIsNoIterAndBranch(MBasicBlock* ifTrue, MBasicBlock* ifFalse, const LBoxAllocation& input) { setSuccessor(0, ifTrue); setSuccessor(1, ifFalse); + setBoxOperand(Input, input); } static const size_t Input = 0; @@ -6380,7 +6534,9 @@ class LSetFrameArgumentV : public LInstructionHelper<0, BOX_PIECES, 0> public: LIR_HEADER(SetFrameArgumentV) - LSetFrameArgumentV() {} + explicit LSetFrameArgumentV(const LBoxAllocation& input) { + setBoxOperand(Input, input); + } static const size_t Input = 0; @@ -6479,7 +6635,8 @@ class LTypeBarrierV : public LInstructionHelper<0, BOX_PIECES, 1> public: LIR_HEADER(TypeBarrierV) - explicit LTypeBarrierV(const LDefinition& temp) { + LTypeBarrierV(const LBoxAllocation& input, const LDefinition& temp) { + setBoxOperand(Input, input); setTemp(0, temp); } @@ -6520,7 +6677,8 @@ class LMonitorTypes : public LInstructionHelper<0, BOX_PIECES, 1> public: LIR_HEADER(MonitorTypes) - explicit LMonitorTypes(const LDefinition& temp) { + LMonitorTypes(const LBoxAllocation& input, const LDefinition& temp) { + setBoxOperand(Input, input); setTemp(0, temp); } @@ -6567,8 +6725,10 @@ class LPostWriteBarrierV : public LInstructionHelper<0, 1 + BOX_PIECES, 1> public: LIR_HEADER(PostWriteBarrierV) - LPostWriteBarrierV(const LAllocation& obj, const LDefinition& temp) { + LPostWriteBarrierV(const LAllocation& obj, const LBoxAllocation& value, + const LDefinition& temp) { setOperand(0, obj); + setBoxOperand(Input, value); setTemp(0, temp); } @@ -6629,9 +6789,10 @@ class LPostWriteElementBarrierV : public LInstructionHelper<0, 2 + BOX_PIECES, 1 LIR_HEADER(PostWriteElementBarrierV) LPostWriteElementBarrierV(const LAllocation& obj, const LAllocation& index, - const LDefinition& temp) { + const LBoxAllocation& value, const LDefinition& temp) { setOperand(0, obj); setOperand(1, index); + setBoxOperand(Input, value); setTemp(0, temp); } @@ -6715,7 +6876,8 @@ class LIn : public LCallInstructionHelper<1, BOX_PIECES+1, 0> { public: LIR_HEADER(In) - explicit LIn(const LAllocation& rhs) { + LIn(const LBoxAllocation& lhs, const LAllocation& rhs) { + setBoxOperand(LHS, lhs); setOperand(RHS, rhs); } @@ -6751,7 +6913,8 @@ class LInstanceOfV : public LInstructionHelper<1, BOX_PIECES, 0> { public: LIR_HEADER(InstanceOfV) - LInstanceOfV() { + explicit LInstanceOfV(const LBoxAllocation& lhs) { + setBoxOperand(LHS, lhs); } MInstanceOf* mir() const { @@ -6769,7 +6932,8 @@ class LCallInstanceOf : public LCallInstructionHelper<1, BOX_PIECES+1, 0> { public: LIR_HEADER(CallInstanceOf) - explicit LCallInstanceOf(const LAllocation& rhs) { + LCallInstanceOf(const LBoxAllocation& lhs, const LAllocation& rhs) { + setBoxOperand(LHS, lhs); setOperand(RHS, rhs); } @@ -6808,6 +6972,11 @@ class LIsObject : public LInstructionHelper<1, BOX_PIECES, 0> public: LIR_HEADER(IsObject); static const size_t Input = 0; + + explicit LIsObject(const LBoxAllocation& input) { + setBoxOperand(Input, input); + } + MIsObject* mir() const { return mir_->toIsObject(); } @@ -6818,9 +6987,10 @@ class LIsObjectAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 0> public: LIR_HEADER(IsObjectAndBranch) - LIsObjectAndBranch(MBasicBlock* ifTrue, MBasicBlock* ifFalse) { + LIsObjectAndBranch(MBasicBlock* ifTrue, MBasicBlock* ifFalse, const LBoxAllocation& input) { setSuccessor(0, ifTrue); setSuccessor(1, ifFalse); + setBoxOperand(Input, input); } static const size_t Input = 0; @@ -7339,9 +7509,10 @@ class LAssertRangeV : public LInstructionHelper<0, BOX_PIECES, 3> public: LIR_HEADER(AssertRangeV) - LAssertRangeV(const LDefinition& temp, const LDefinition& floatTemp1, - const LDefinition& floatTemp2) + LAssertRangeV(const LBoxAllocation& input, const LDefinition& temp, + const LDefinition& floatTemp1, const LDefinition& floatTemp2) { + setBoxOperand(Input, input); setTemp(0, temp); setTemp(1, floatTemp1); setTemp(2, floatTemp2); @@ -7387,6 +7558,10 @@ class LAssertResultV : public LInstructionHelper<0, BOX_PIECES, 0> LIR_HEADER(AssertResultV) static const size_t Input = 0; + + explicit LAssertResultV(const LBoxAllocation& input) { + setBoxOperand(Input, input); + } }; class LRecompileCheck : public LInstructionHelper<0, 0, 1> @@ -7411,6 +7586,10 @@ class LLexicalCheck : public LInstructionHelper<0, BOX_PIECES, 0> public: LIR_HEADER(LexicalCheck) + explicit LLexicalCheck(const LBoxAllocation& input) { + setBoxOperand(Input, input); + } + MLexicalCheck* mir() { return mir_->toLexicalCheck(); } @@ -7545,26 +7724,39 @@ class LRandom : public LInstructionHelper<1, 0, LRANDOM_NUM_TEMPS> class LCheckReturn : public LCallInstructionHelper { public: + LIR_HEADER(CheckReturn) + + LCheckReturn(const LBoxAllocation& retVal, const LBoxAllocation& thisVal) { + setBoxOperand(ReturnValue, retVal); + setBoxOperand(ThisValue, thisVal); + } + static const size_t ReturnValue = 0; static const size_t ThisValue = BOX_PIECES; - - LIR_HEADER(CheckReturn) }; class LCheckObjCoercible : public LCallInstructionHelper { public: + LIR_HEADER(CheckObjCoercible) + static const size_t CheckValue = 0; - LIR_HEADER(CheckObjCoercible) + explicit LCheckObjCoercible(const LBoxAllocation& value) { + setBoxOperand(CheckValue, value); + } }; class LDebugCheckSelfHosted : public LCallInstructionHelper { public: + LIR_HEADER(DebugCheckSelfHosted) + static const size_t CheckValue = 0; - LIR_HEADER(DebugCheckSelfHosted) + explicit LDebugCheckSelfHosted(const LBoxAllocation& value) { + setBoxOperand(CheckValue, value); + } }; } // namespace jit diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h index a08d03527f..2fd432f1d4 100644 --- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -14,6 +14,7 @@ _(OsiPoint) \ _(MoveGroup) \ _(Integer) \ + _(Integer64) \ _(Pointer) \ _(Double) \ _(Float32) \ diff --git a/js/src/jit/shared/Lowering-shared-inl.h b/js/src/jit/shared/Lowering-shared-inl.h index 4729bf1e5d..17da19417a 100644 --- a/js/src/jit/shared/Lowering-shared-inl.h +++ b/js/src/jit/shared/Lowering-shared-inl.h @@ -108,6 +108,28 @@ LIRGeneratorShared::defineBox(LInstructionHelper* lir, M add(lir); } +template void +LIRGeneratorShared::defineInt64(LInstructionHelper* lir, MDefinition* mir, + LDefinition::Policy policy) +{ + // Call instructions should use defineReturn. + MOZ_ASSERT(!lir->isCall()); + + uint32_t vreg = getVirtualRegister(); + +#if JS_BITS_PER_WORD == 32 + lir->setDef(0, LDefinition(vreg, LDefinition::GENERAL, policy)); + lir->setDef(1, LDefinition(vreg + 1, LDefinition::GENERAL, policy)); + getVirtualRegister(); +#else + lir->setDef(0, LDefinition(vreg, LDefinition::GENERAL, policy)); +#endif + lir->setMir(mir); + + mir->setVirtualRegister(vreg); + add(lir); +} + void LIRGeneratorShared::defineSharedStubReturn(LInstruction* lir, MDefinition* mir) { @@ -298,8 +320,7 @@ LIRGeneratorShared::redefine(MDefinition* def, MDefinition* as) break; } case MIRType_Value: { - LAssertResultV* check = new(alloc()) LAssertResultV(); - useBox(check, LAssertRangeV::Input, def); + LAssertResultV* check = new(alloc()) LAssertResultV(useBox(def)); add(check, def->toInstruction()); break; } @@ -606,35 +627,40 @@ LIRGeneratorShared::useRegisterForTypedLoad(MDefinition* mir, MIRType type) return useRegisterAtStart(mir); } -void -LIRGeneratorShared::useBox(LInstruction* lir, size_t n, MDefinition* mir, - LUse::Policy policy, bool useAtStart) +LBoxAllocation +LIRGeneratorShared::useBox(MDefinition* mir, LUse::Policy policy, bool useAtStart) { MOZ_ASSERT(mir->type() == MIRType_Value); ensureDefined(mir); - lir->setOperand(n, LUse(mir->virtualRegister(), policy, useAtStart)); + #if defined(JS_NUNBOX32) - lir->setOperand(n + 1, LUse(VirtualRegisterOfPayload(mir), policy, useAtStart)); + return LBoxAllocation(LUse(mir->virtualRegister(), policy, useAtStart), + LUse(VirtualRegisterOfPayload(mir), policy, useAtStart)); +#else + return LBoxAllocation(LUse(mir->virtualRegister(), policy, useAtStart)); #endif } -void -LIRGeneratorShared::useBoxOrTypedOrConstant(LInstruction* lir, size_t n, MDefinition* mir, - bool useConstant) +LBoxAllocation +LIRGeneratorShared::useBoxOrTypedOrConstant(MDefinition* mir, bool useConstant) { - if (mir->type() == MIRType_Value) { - useBox(lir, n, mir); - return; + if (mir->type() == MIRType_Value) + return useBox(mir); + + + if (useConstant && mir->isConstant()) { +#if defined(JS_NUNBOX32) + return LBoxAllocation(LAllocation(mir->toConstant()), LAllocation()); +#else + return LBoxAllocation(LAllocation(mir->toConstant())); +#endif } - if (useConstant && mir->isConstant()) - lir->setOperand(n, LAllocation(mir->toConstant())); - else - lir->setOperand(n, useRegister(mir)); - #if defined(JS_NUNBOX32) - lir->setOperand(n + 1, LAllocation()); + return LBoxAllocation(useRegister(mir), LAllocation()); +#else + return LBoxAllocation(useRegister(mir)); #endif } diff --git a/js/src/jit/shared/Lowering-shared.cpp b/js/src/jit/shared/Lowering-shared.cpp index 1116fc2b4c..27013c685b 100644 --- a/js/src/jit/shared/Lowering-shared.cpp +++ b/js/src/jit/shared/Lowering-shared.cpp @@ -92,6 +92,9 @@ LIRGeneratorShared::visitConstant(MConstant* ins) case MIRType_Int32: define(new(alloc()) LInteger(ins->toInt32()), ins); break; + case MIRType_Int64: + defineInt64(new(alloc()) LInteger64(ins->toInt64()), ins); + break; case MIRType_String: define(new(alloc()) LPointer(ins->toString()), ins); break; diff --git a/js/src/jit/shared/Lowering-shared.h b/js/src/jit/shared/Lowering-shared.h index bee73f5c3f..b4e5950a67 100644 --- a/js/src/jit/shared/Lowering-shared.h +++ b/js/src/jit/shared/Lowering-shared.h @@ -142,6 +142,10 @@ class LIRGeneratorShared : public MDefinitionVisitor inline void defineBox(LInstructionHelper* lir, MDefinition* mir, LDefinition::Policy policy = LDefinition::REGISTER); + template + inline void defineInt64(LInstructionHelper* lir, MDefinition* mir, + LDefinition::Policy policy = LDefinition::REGISTER); + template inline void defineSinCos(LInstructionHelper<2, Ops, Temps> *lir, MDefinition *mir, LDefinition::Policy policy = LDefinition::REGISTER); @@ -159,14 +163,13 @@ class LIRGeneratorShared : public MDefinitionVisitor template inline void defineReuseInput(LInstructionHelper<1, Ops, Temps>* lir, MDefinition* mir, uint32_t operand); - // Adds a use at operand |n| of a value-typed insturction. - inline void useBox(LInstruction* lir, size_t n, MDefinition* mir, - LUse::Policy policy = LUse::REGISTER, bool useAtStart = false); + // Returns a box allocation for a Value-typed instruction. + inline LBoxAllocation useBox(MDefinition* mir, LUse::Policy policy = LUse::REGISTER, + bool useAtStart = false); - // Adds a use at operand |n|. The use is either typed, a Value, or a - // constant (if useConstant is true). - inline void useBoxOrTypedOrConstant(LInstruction* lir, size_t n, MDefinition* mir, - bool useConstant); + // Returns a box allocation. The use is either typed, a Value, or + // a constant (if useConstant is true). + inline LBoxAllocation useBoxOrTypedOrConstant(MDefinition* mir, bool useConstant); // Rather than defining a new virtual register, sets |ins| to have the same // virtual register as |as|. diff --git a/js/src/jit/x64/Assembler-x64.cpp b/js/src/jit/x64/Assembler-x64.cpp index be3a0cd538..fc7d8e2b79 100644 --- a/js/src/jit/x64/Assembler-x64.cpp +++ b/js/src/jit/x64/Assembler-x64.cpp @@ -45,6 +45,7 @@ ABIArgGenerator::next(MIRType type) } switch (type) { case MIRType_Int32: + case MIRType_Int64: case MIRType_Pointer: current_ = ABIArg(IntArgRegs[regIndex_++]); break; @@ -69,6 +70,7 @@ ABIArgGenerator::next(MIRType type) #else switch (type) { case MIRType_Int32: + case MIRType_Int64: case MIRType_Pointer: if (intRegIndex_ == NumIntArgRegs) { current_ = ABIArg(stackOffset_); diff --git a/js/src/jit/x64/Lowering-x64.cpp b/js/src/jit/x64/Lowering-x64.cpp index eac6421be4..e0864e81a5 100644 --- a/js/src/jit/x64/Lowering-x64.cpp +++ b/js/src/jit/x64/Lowering-x64.cpp @@ -14,13 +14,13 @@ using namespace js; using namespace js::jit; -void -LIRGeneratorX64::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register, bool useAtStart) +LBoxAllocation +LIRGeneratorX64::useBoxFixed(MDefinition* mir, Register reg1, Register, bool useAtStart) { MOZ_ASSERT(mir->type() == MIRType_Value); ensureDefined(mir); - lir->setOperand(n, LUse(reg1, mir->virtualRegister(), useAtStart)); + return LBoxAllocation(LUse(reg1, mir->virtualRegister(), useAtStart)); } LAllocation diff --git a/js/src/jit/x64/Lowering-x64.h b/js/src/jit/x64/Lowering-x64.h index 398ff287b4..f8617a7b75 100644 --- a/js/src/jit/x64/Lowering-x64.h +++ b/js/src/jit/x64/Lowering-x64.h @@ -23,8 +23,8 @@ class LIRGeneratorX64 : public LIRGeneratorX86Shared void lowerUntypedPhiInput(MPhi* phi, uint32_t inputPosition, LBlock* block, size_t lirIndex); void defineUntypedPhi(MPhi* phi, size_t lirIndex); - // Adds a use at operand |n| of a value-typed insturction. - void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register, bool useAtStart = false); + // Returns a box allocation. reg2 is ignored on 64-bit platforms. + LBoxAllocation useBoxFixed(MDefinition* mir, Register reg1, Register, bool useAtStart = false); // x86 has constraints on what registers can be formatted for 1-byte // stores and loads; on x64 all registers are okay. diff --git a/js/src/jit/x64/MacroAssembler-x64-inl.h b/js/src/jit/x64/MacroAssembler-x64-inl.h index a52227c385..8ca67393af 100644 --- a/js/src/jit/x64/MacroAssembler-x64-inl.h +++ b/js/src/jit/x64/MacroAssembler-x64-inl.h @@ -17,6 +17,18 @@ namespace jit { //{{{ check_macroassembler_style // =============================================================== +void +MacroAssembler::move64(Imm64 imm, Register64 dest) +{ + movq(ImmWord(imm.value), dest.reg); +} + +void +MacroAssembler::move64(Register64 src, Register64 dest) +{ + movq(src.reg, dest.reg); +} + void MacroAssembler::andPtr(Register src, Register dest) { diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 3d1d37a7d0..f603b49cd6 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -573,9 +573,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared void movePtr(ImmGCPtr imm, Register dest) { movq(imm, dest); } - void move64(Register64 src, Register64 dest) { - movq(src.reg, dest.reg); - } void loadPtr(AbsoluteAddress address, Register dest) { if (X86Encoding::IsAddressImmediate(address.addr)) { movq(Operand(address), dest); diff --git a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp index 425235d438..ba6e25dcb7 100644 --- a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp @@ -2408,7 +2408,11 @@ CodeGeneratorX86Shared::visitFloat32x4ToUint32x4(LFloat32x4ToUint32x4* ins) masm.vcmpleps(Operand(in), scratch, scratch); masm.vmovmskps(scratch, temp); masm.cmp32(temp, Imm32(15)); - bailoutIf(Assembler::NotEqual, ins->snapshot()); + + if (gen->compilingAsmJS()) + masm.j(Assembler::NotEqual, wasm::JumpTarget::ConversionError); + else + bailoutIf(Assembler::NotEqual, ins->snapshot()); // TODO: If the majority of lanes are A-lanes, it could be faster to compute // A first, use vmovmskps to check for any non-A-lanes and handle them in @@ -2443,7 +2447,11 @@ CodeGeneratorX86Shared::visitFloat32x4ToUint32x4(LFloat32x4ToUint32x4* ins) // the remaining negative lanes in B. masm.vmovmskps(scratch, temp); masm.cmp32(temp, Imm32(0)); - bailoutIf(Assembler::NotEqual, ins->snapshot()); + + if (gen->compilingAsmJS()) + masm.j(Assembler::NotEqual, wasm::JumpTarget::ConversionError); + else + bailoutIf(Assembler::NotEqual, ins->snapshot()); } void @@ -3425,24 +3433,11 @@ CodeGeneratorX86Shared::visitSimdShift(LSimdShift* ins) FloatRegister out = ToFloatRegister(ins->output()); MOZ_ASSERT(ToFloatRegister(ins->vector()) == out); // defineReuseInput(0); - // If the shift count is greater than 31, this will just zero all lanes by - // default for lsh and ursh, and for rsh extend the sign bit to all bits, - // per the SIMD.js spec (as of March 19th 2015). + // If the shift count is out of range, only use the low 5 bits. const LAllocation* val = ins->value(); if (val->isConstant()) { - uint32_t c = uint32_t(ToInt32(val)); - if (c > 31) { - switch (ins->operation()) { - case MSimdShift::lsh: - case MSimdShift::ursh: - masm.zeroInt32x4(out); - return; - default: - c = 31; - break; - } - } - Imm32 count(c); + MOZ_ASSERT(ins->temp()->isBogusTemp()); + Imm32 count(uint32_t(ToInt32(val)) % 32); switch (ins->operation()) { case MSimdShift::lsh: masm.packedLeftShiftByScalar(count, out); @@ -3457,9 +3452,13 @@ CodeGeneratorX86Shared::visitSimdShift(LSimdShift* ins) MOZ_CRASH("unexpected SIMD bitwise op"); } + // Truncate val to 5 bits. We should have a temp register for that. MOZ_ASSERT(val->isRegister()); + Register count = ToRegister(ins->temp()); + masm.mov(ToRegister(val), count); + masm.andl(Imm32(31), count); ScratchFloat32Scope scratch(masm); - masm.vmovd(ToRegister(val), scratch); + masm.vmovd(count, scratch); switch (ins->operation()) { case MSimdShift::lsh: diff --git a/js/src/jit/x86-shared/LIR-x86-shared.h b/js/src/jit/x86-shared/LIR-x86-shared.h index aca128ece1..3f5dbef974 100644 --- a/js/src/jit/x86-shared/LIR-x86-shared.h +++ b/js/src/jit/x86-shared/LIR-x86-shared.h @@ -254,9 +254,11 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 3> public: LIR_HEADER(TableSwitchV) - LTableSwitchV(const LDefinition& inputCopy, const LDefinition& floatCopy, - const LDefinition& jumpTablePointer, MTableSwitch* ins) + LTableSwitchV(const LBoxAllocation& input, const LDefinition& inputCopy, + const LDefinition& floatCopy, const LDefinition& jumpTablePointer, + MTableSwitch* ins) { + setBoxOperand(InputValue, input); setTemp(0, inputCopy); setTemp(1, floatCopy); setTemp(2, jumpTablePointer); diff --git a/js/src/jit/x86-shared/Lowering-x86-shared.cpp b/js/src/jit/x86-shared/Lowering-x86-shared.cpp index 200df822a8..8874bf266f 100644 --- a/js/src/jit/x86-shared/Lowering-x86-shared.cpp +++ b/js/src/jit/x86-shared/Lowering-x86-shared.cpp @@ -29,7 +29,8 @@ LIRGeneratorX86Shared::newLTableSwitch(const LAllocation& in, const LDefinition& LTableSwitchV* LIRGeneratorX86Shared::newLTableSwitchV(MTableSwitch* tableswitch) { - return new(alloc()) LTableSwitchV(temp(), tempDouble(), temp(), tableswitch); + return new(alloc()) LTableSwitchV(useBox(tableswitch->getOperand(0)), + temp(), tempDouble(), temp(), tableswitch); } void diff --git a/js/src/jit/x86/LIR-x86.h b/js/src/jit/x86/LIR-x86.h index 5a3ec0e8b7..c598170d63 100644 --- a/js/src/jit/x86/LIR-x86.h +++ b/js/src/jit/x86/LIR-x86.h @@ -61,9 +61,11 @@ class LUnboxFloatingPoint : public LInstructionHelper<1, 2, 0> static const size_t Input = 0; - LUnboxFloatingPoint(MIRType type) + LUnboxFloatingPoint(const LBoxAllocation& input, MIRType type) : type_(type) - { } + { + setBoxOperand(Input, input); + } MUnbox* mir() const { return mir_->toUnbox(); diff --git a/js/src/jit/x86/Lowering-x86.cpp b/js/src/jit/x86/Lowering-x86.cpp index d16dcce143..96f3aa7f2e 100644 --- a/js/src/jit/x86/Lowering-x86.cpp +++ b/js/src/jit/x86/Lowering-x86.cpp @@ -14,16 +14,15 @@ using namespace js; using namespace js::jit; -void -LIRGeneratorX86::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, - Register reg2, bool useAtStart) +LBoxAllocation +LIRGeneratorX86::useBoxFixed(MDefinition* mir, Register reg1, Register reg2, bool useAtStart) { MOZ_ASSERT(mir->type() == MIRType_Value); MOZ_ASSERT(reg1 != reg2); ensureDefined(mir); - lir->setOperand(n, LUse(reg1, mir->virtualRegister(), useAtStart)); - lir->setOperand(n + 1, LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart)); + return LBoxAllocation(LUse(reg1, mir->virtualRegister(), useAtStart), + LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart)); } LAllocation @@ -105,10 +104,9 @@ LIRGeneratorX86::visitUnbox(MUnbox* unbox) ensureDefined(inner); if (IsFloatingPointType(unbox->type())) { - LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(unbox->type()); + LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(useBox(inner), unbox->type()); if (unbox->fallible()) assignSnapshot(lir, unbox->bailoutKind()); - useBox(lir, LUnboxFloatingPoint::Input, inner); define(lir, unbox); return; } diff --git a/js/src/jit/x86/Lowering-x86.h b/js/src/jit/x86/Lowering-x86.h index 43fbec429a..da46f4de73 100644 --- a/js/src/jit/x86/Lowering-x86.h +++ b/js/src/jit/x86/Lowering-x86.h @@ -20,10 +20,9 @@ class LIRGeneratorX86 : public LIRGeneratorX86Shared { } protected: - // Adds a box input to an instruction, setting operand |n| to the type and - // |n+1| to the payload. - void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2, - bool useAtStart = false); + // Returns a box allocation with type set to reg1 and payload set to reg2. + LBoxAllocation useBoxFixed(MDefinition* mir, Register reg1, Register reg2, + bool useAtStart = false); // It's a trap! On x86, the 1-byte store can only use one of // {al,bl,cl,dl,ah,bh,ch,dh}. That means if the register allocator diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index a5e4e088c2..a7afdfaa68 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -15,6 +15,21 @@ namespace js { namespace jit { //{{{ check_macroassembler_style + +void +MacroAssembler::move64(Imm64 imm, Register64 dest) +{ + movl(Imm32(imm.value & 0xFFFFFFFFL), dest.low); + movl(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high); +} + +void +MacroAssembler::move64(Register64 src, Register64 dest) +{ + movl(src.low, dest.low); + movl(src.high, dest.high); +} + // =============================================================== // Logical functions diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index c18a9b2618..8da217010a 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -601,10 +601,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared void movePtr(ImmGCPtr imm, Register dest) { movl(imm, dest); } - void move64(Register64 src, Register64 dest) { - movl(src.low, dest.low); - movl(src.high, dest.high); - } void loadPtr(const Address& address, Register dest) { movl(Operand(address), dest); } diff --git a/js/src/tests/ecma_7/SIMD/shifts.js b/js/src/tests/ecma_7/SIMD/shifts.js index f9e58adbc2..1d81f7483a 100644 --- a/js/src/tests/ecma_7/SIMD/shifts.js +++ b/js/src/tests/ecma_7/SIMD/shifts.js @@ -14,68 +14,68 @@ var Uint32x4 = SIMD.Uint32x4; // Int8 shifts. function lsh8(a, b) { - return (b >>> 0) >= 8 ? 0 : (a << b) << 24 >> 24; + return (a << (b & 7)) << 24 >> 24; } function rsha8(a, b) { - return (a >> Math.min(b >>> 0, 7)) << 24 >> 24; + return (a >> (b & 7)) << 24 >> 24; } function rshl8(a, b) { - return (b >>> 0) >= 8 ? 0 : (a >>> b) << 24 >> 24; + return (a >>> (b & 7)) << 24 >> 24; } // Int16 shifts. function lsh16(a, b) { - return (b >>> 0) >= 16 ? 0 : (a << b) << 16 >> 16; + return (a << (b & 15)) << 16 >> 16; } function rsha16(a, b) { - return (a >> Math.min(b >>> 0, 15)) << 16 >> 16; + return (a >> (b & 15)) << 16 >> 16; } function rshl16(a, b) { - return (b >>> 0) >= 16 ? 0 : (a >>> b) << 16 >> 16; + return (a >>> (b & 15)) << 16 >> 16; } // Int32 shifts. function lsh32(a, b) { - return (b >>> 0) >= 32 ? 0 : (a << b) | 0; + return (a << (b & 31)) | 0; } function rsha32(a, b) { - return (a >> Math.min(b >>> 0, 31)) | 0; + return (a >> (b & 31)) | 0; } function rshl32(a, b) { - return (b >>> 0) >= 32 ? 0 : (a >>> b) | 0; + return (a >>> (b & 31)) | 0; } // Uint8 shifts. function ulsh8(a, b) { - return (b >>> 0) >= 8 ? 0 : (a << b) << 24 >>> 24; + return (a << (b & 7)) << 24 >>> 24; } function ursha8(a, b) { - return ((a << 24 >> 24) >> Math.min(b >>> 0, 7)) << 24 >>> 24; + return ((a << 24 >> 24) >> (b & 7)) << 24 >>> 24; } function urshl8(a, b) { - return (b >>> 0) >= 8 ? 0 : (a >>> b) << 24 >>> 24; + return (a >>> (b & 7)) << 24 >>> 24; } // Uint16 shifts. function ulsh16(a, b) { - return (b >>> 0) >= 16 ? 0 : (a << b) << 16 >>> 16; + return (a << (b & 15)) << 16 >>> 16; } function ursha16(a, b) { - return ((a << 16 >> 16) >> Math.min(b >>> 0, 15)) << 16 >>> 16; + return ((a << 16 >> 16) >> (b & 15)) << 16 >>> 16; } function urshl16(a, b) { - return (b >>> 0) >= 16 ? 0 : (a >>> b) << 16 >>> 16; + return (a >>> (b & 15)) << 16 >>> 16; } // Uint32 shifts. function ulsh32(a, b) { - return (b >>> 0) >= 32 ? 0 : (a << b) >>> 0; + return (a << (b & 31)) >>> 0; } function ursha32(a, b) { - return ((a | 0) >> Math.min(b >>> 0, 31)) >>> 0; + return ((a | 0) >> (b & 31)) >>> 0; } function urshl32(a, b) { - return (b >>> 0) >= 32 ? 0 : (a >>> b) >>> 0; + return (a >>> (b & 31)) >>> 0; } function test() { @@ -92,8 +92,6 @@ function test() { for (var bits = -2; bits < 12; bits++) { testBinaryScalarFunc(v, bits, Int8x16.shiftLeftByScalar, lsh8); testBinaryScalarFunc(v, bits, Int8x16.shiftRightByScalar, rsha8); - testBinaryScalarFunc(v, bits, Int8x16.shiftRightArithmeticByScalar, rsha8); - testBinaryScalarFunc(v, bits, Int8x16.shiftRightLogicalByScalar, rshl8); } // Test that the shift count is coerced to an int32. testBinaryScalarFunc(v, undefined, Int8x16.shiftLeftByScalar, lsh8); @@ -108,8 +106,6 @@ function test() { for (var bits = -2; bits < 20; bits++) { testBinaryScalarFunc(v, bits, Int16x8.shiftLeftByScalar, lsh16); testBinaryScalarFunc(v, bits, Int16x8.shiftRightByScalar, rsha16); - testBinaryScalarFunc(v, bits, Int16x8.shiftRightArithmeticByScalar, rsha16); - testBinaryScalarFunc(v, bits, Int16x8.shiftRightLogicalByScalar, rshl16); } // Test that the shift count is coerced to an int32. testBinaryScalarFunc(v, undefined, Int16x8.shiftLeftByScalar, lsh16); @@ -124,8 +120,6 @@ function test() { for (var bits = -2; bits < 36; bits++) { testBinaryScalarFunc(v, bits, Int32x4.shiftLeftByScalar, lsh32); testBinaryScalarFunc(v, bits, Int32x4.shiftRightByScalar, rsha32); - testBinaryScalarFunc(v, bits, Int32x4.shiftRightArithmeticByScalar, rsha32); - testBinaryScalarFunc(v, bits, Int32x4.shiftRightLogicalByScalar, rshl32); } // Test that the shift count is coerced to an int32. testBinaryScalarFunc(v, undefined, Int32x4.shiftLeftByScalar, lsh32); @@ -141,8 +135,6 @@ function test() { for (var bits = -2; bits < 12; bits++) { testBinaryScalarFunc(v, bits, Uint8x16.shiftLeftByScalar, ulsh8); testBinaryScalarFunc(v, bits, Uint8x16.shiftRightByScalar, urshl8); - testBinaryScalarFunc(v, bits, Uint8x16.shiftRightArithmeticByScalar, ursha8); - testBinaryScalarFunc(v, bits, Uint8x16.shiftRightLogicalByScalar, urshl8); } // Test that the shift count is coerced to an int32. testBinaryScalarFunc(v, undefined, Uint8x16.shiftLeftByScalar, ulsh8); @@ -157,8 +149,6 @@ function test() { for (var bits = -2; bits < 20; bits++) { testBinaryScalarFunc(v, bits, Uint16x8.shiftLeftByScalar, ulsh16); testBinaryScalarFunc(v, bits, Uint16x8.shiftRightByScalar, urshl16); - testBinaryScalarFunc(v, bits, Uint16x8.shiftRightArithmeticByScalar, ursha16); - testBinaryScalarFunc(v, bits, Uint16x8.shiftRightLogicalByScalar, urshl16); } // Test that the shift count is coerced to an int32. testBinaryScalarFunc(v, undefined, Uint16x8.shiftLeftByScalar, ulsh16); @@ -174,8 +164,6 @@ function test() { for (var bits = -2; bits < 36; bits++) { testBinaryScalarFunc(v, bits, Uint32x4.shiftLeftByScalar, ulsh32); testBinaryScalarFunc(v, bits, Uint32x4.shiftRightByScalar, urshl32); - testBinaryScalarFunc(v, bits, Uint32x4.shiftRightArithmeticByScalar, ursha32); - testBinaryScalarFunc(v, bits, Uint32x4.shiftRightLogicalByScalar, urshl32); } // Test that the shift count is coerced to an int32. testBinaryScalarFunc(v, undefined, Uint32x4.shiftLeftByScalar, ulsh32); @@ -186,38 +174,26 @@ function test() { var v = SIMD.Int8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); assertThrowsInstanceOf(() => SIMD.Int8x16.shiftLeftByScalar(v, bad), TestError); assertThrowsInstanceOf(() => SIMD.Int8x16.shiftRightByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Int8x16.shiftRightArithmeticByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Int8x16.shiftRightLogicalByScalar(v, bad), TestError); var v = SIMD.Int16x8(1,2,3,4,5,6,7,8); assertThrowsInstanceOf(() => SIMD.Int16x8.shiftLeftByScalar(v, bad), TestError); assertThrowsInstanceOf(() => SIMD.Int16x8.shiftRightByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Int16x8.shiftRightArithmeticByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Int16x8.shiftRightLogicalByScalar(v, bad), TestError); var v = SIMD.Int32x4(1,2,3,4); assertThrowsInstanceOf(() => SIMD.Int32x4.shiftLeftByScalar(v, bad), TestError); assertThrowsInstanceOf(() => SIMD.Int32x4.shiftRightByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Int32x4.shiftRightArithmeticByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Int32x4.shiftRightLogicalByScalar(v, bad), TestError); var v = SIMD.Uint8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); assertThrowsInstanceOf(() => SIMD.Uint8x16.shiftLeftByScalar(v, bad), TestError); assertThrowsInstanceOf(() => SIMD.Uint8x16.shiftRightByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Uint8x16.shiftRightArithmeticByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Uint8x16.shiftRightLogicalByScalar(v, bad), TestError); var v = SIMD.Uint16x8(1,2,3,4,5,6,7,8); assertThrowsInstanceOf(() => SIMD.Uint16x8.shiftLeftByScalar(v, bad), TestError); assertThrowsInstanceOf(() => SIMD.Uint16x8.shiftRightByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Uint16x8.shiftRightArithmeticByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Uint16x8.shiftRightLogicalByScalar(v, bad), TestError); var v = SIMD.Uint32x4(1,2,3,4); assertThrowsInstanceOf(() => SIMD.Uint32x4.shiftLeftByScalar(v, bad), TestError); assertThrowsInstanceOf(() => SIMD.Uint32x4.shiftRightByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Uint32x4.shiftRightArithmeticByScalar(v, bad), TestError); - assertThrowsInstanceOf(() => SIMD.Uint32x4.shiftRightLogicalByScalar(v, bad), TestError); if (typeof reportCompare === "function") reportCompare(true, true); diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 2d80921e55..a58d2e2cd1 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -527,7 +527,7 @@ random-if(cocoaWidget) == 350506-1.html 350506-1-ref.html == 356774-1.html 356774-1-ref.html == 356775-1.html 356775-1-ref.html == 359869-1.html 359869-1-ref.html -fails-if(OSX) != 359903-1.html 359903-1-ref.html # erosion of padding removed in bug 1010675 # failure is bug 1145589 +!= 359903-1.html 359903-1-ref.html # erosion of padding removed in bug 1010675 != 359903-2.html 359903-2-ref.html # erosion of padding removed in bug 1010675 == 360065-1.html 360065-1-ref.html == 360746-1.html 360746-1-ref.html diff --git a/layout/reftests/forms/input/file/reftest.list b/layout/reftests/forms/input/file/reftest.list index 157909b4ed..d3edd59165 100644 --- a/layout/reftests/forms/input/file/reftest.list +++ b/layout/reftests/forms/input/file/reftest.list @@ -1,8 +1,8 @@ # B2G failures: bug 855352. -fails-if(B2G||Mulet||Android) fuzzy-if(OSX==1006,8,128) skip-if((B2G&&browserIsRemote)||Mulet) == simple.html simple-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop -fails-if(B2G||Mulet||Android) fuzzy-if(OSX==1006,8,64) skip-if((B2G&&browserIsRemote)||Mulet) == rtl.html rtl-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop -fails-if(B2G||Mulet||Android) fuzzy-if(OSX==1006,8,128) skip-if((B2G&&browserIsRemote)||Mulet) == size.html simple-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop -fails-if(B2G||Mulet||Android) fuzzy-if(OSX==1006,8,64) skip-if((B2G&&browserIsRemote)||Mulet) == background.html background-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop +fails-if(B2G||Mulet||Android) fuzzy-if(OSX==1006,8,152) skip-if((B2G&&browserIsRemote)||Mulet) == simple.html simple-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop +fails-if(B2G||Mulet||Android) fuzzy-if(OSX==1006,8,76) skip-if((B2G&&browserIsRemote)||Mulet) == rtl.html rtl-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop +fails-if(B2G||Mulet||Android) fuzzy-if(OSX==1006,8,152) skip-if((B2G&&browserIsRemote)||Mulet) == size.html simple-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop +fails-if(B2G||Mulet||Android) fuzzy-if(OSX==1006,8,76) skip-if((B2G&&browserIsRemote)||Mulet) == background.html background-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop fails-if(B2G||Mulet||Android) skip-if((B2G&&browserIsRemote)||Mulet) == style.html style-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop != width-clip.html width-clip-ref.html fails-if(B2G||Mulet||Android) == color-inherit.html color-inherit-ref.html # Initial mulet triage: parity with B2G/B2G Desktop diff --git a/layout/reftests/reftest-sanity/reftest.list b/layout/reftests/reftest-sanity/reftest.list index ecf354d21d..675fa1766c 100644 --- a/layout/reftests/reftest-sanity/reftest.list +++ b/layout/reftests/reftest-sanity/reftest.list @@ -3,8 +3,8 @@ != data:text/plain,HELLO about:blank # these tests make sure async reftests work: -skip-if(B2G||Mulet) == test-async.xul test-async-ref.xul # bug 785074 # Initial mulet triage: parity with B2G/B2G Desktop -skip-if(B2G||Mulet) == test-async.html test-async-ref.html # bug 785074 # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) == test-async.xul test-async-ref.xul # bug 785074 # Initial mulet triage: parity with B2G +skip-if(B2G||Mulet) == test-async.html test-async-ref.html # bug 785074 # Initial mulet triage: parity with B2G # test that zoom works (and really zooms, not just scales) == test-zoom.html test-zoom-ref.html @@ -36,15 +36,15 @@ HTTP == data:text/html,
Text
default.html != blank.html default.html HTTP != blank.html default.html -skip-if(B2G||Mulet) HTTP(..) == filter-1.xhtml filter-1-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop -skip-if(B2G||Mulet) HTTP(..) == filter-2.xhtml filter-2-ref.xhtml # bug 773482 # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) HTTP(..) == filter-1.xhtml filter-1-ref.xhtml # Initial mulet triage: parity with B2G +skip-if(B2G||Mulet) HTTP(..) == filter-2.xhtml filter-2-ref.xhtml # bug 773482 # Initial mulet triage: parity with B2G # test that the MozReftestInvalidate event fires == invalidation.html about:blank == zoom-invalidation.html zoom-invalidation-ref.html # bug 773482 # test that xulRuntime.OS works -skip-if(B2G||B2GDT||Mulet) fails-if(xulRuntime.OS!="Linux"&&!Android) == data:text/html,Linux data:text/html, # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) fails-if(xulRuntime.OS!="Linux"&&!Android) == data:text/html,Linux data:text/html, # Initial mulet triage: parity with B2G fails-if(xulRuntime.OS!="WINNT") == data:text/html,Win data:text/html, fails-if(xulRuntime.OS!="Darwin") == data:text/html,Mac data:text/html, @@ -76,9 +76,9 @@ skip-if(Android&&AndroidVersion==15) != corners-4.html corners-4-ref.html # s # Test that the harness gives the correct page dimensions. != page-width-3.9in.html page-width-4in.html -skip-if(B2G||B2GDT||Mulet) == page-width-4.1in.html page-width-4in.html # bug 774396 # Initial mulet triage: parity with B2G/B2G Desktop -skip-if(B2G||B2GDT||Mulet) == page-width-auto.html page-width-4in.html # bug 774396 # Initial mulet triage: parity with B2G/B2G Desktop -skip-if(B2G||B2GDT||Mulet) != page-height-2in.html page-height-2.1in.html # bug 774396 # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) == page-width-4.1in.html page-width-4in.html # bug 774396 # Initial mulet triage: parity with B2G +skip-if(B2G||Mulet) == page-width-auto.html page-width-4in.html # bug 774396 # Initial mulet triage: parity with B2G +skip-if(B2G||Mulet) != page-height-2in.html page-height-2.1in.html # bug 774396 # Initial mulet triage: parity with B2G == page-height-2in.html page-height-nobreak.html == page-height-2.1in.html page-height-forcebreak.html @@ -91,8 +91,8 @@ needs-focus == data:text/plain, about:blank # Sanity check of viewport+displayport overrides pref(dom.meta-viewport.enabled,true) skip-if(!browserIsRemote) != test-displayport-2.html test-displayport-ref.html # bug 593168 -skip-if(!browserIsRemote) fails-if(OSX&&layersGPUAccelerated) fuzzy-if(layersOMTC,1,1390) random-if(Android&&AndroidVersion<15) random-if(B2G||B2GDT||Mulet) random-if(transparentScrollbars) == 647192-1.html 647192-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop -skip-if(!browserIsRemote||((B2G&&browserIsRemote)||Mulet)) == 656041-1.html 656041-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(!browserIsRemote) fails-if(OSX&&layersGPUAccelerated) fuzzy-if(layersOMTC,1,1390) random-if(Android&&AndroidVersion<15) random-if(B2G||Mulet) random-if(transparentScrollbars) == 647192-1.html 647192-1-ref.html # Initial mulet triage: parity with B2G +skip-if(!browserIsRemote||((B2G&&browserIsRemote)||Mulet)) == 656041-1.html 656041-1-ref.html # Initial mulet triage: parity with B2G pref(dom.meta-viewport.enabled,true) skip-if(!browserIsRemote||layersOMTC) == test-displayport-bg.html test-displayport-ref.html # bug 694706 # IPC Position-fixed frames/layers test diff --git a/layout/style/forms.css b/layout/style/forms.css index 432e136446..cf40f62c49 100644 --- a/layout/style/forms.css +++ b/layout/style/forms.css @@ -694,10 +694,12 @@ input[type="color"]:-moz-system-metric(color-picker-available):active:hover, input[type="reset"]:active:hover, input[type="button"]:active:hover, input[type="submit"]:active:hover { +%ifndef XP_MACOSX padding-block-start: 0px; -moz-padding-end: 5px; padding-block-end: 0px; -moz-padding-start: 7px; +%endif border-style: inset; background-color: ButtonFace; } diff --git a/layout/tools/reftest/Makefile.in b/layout/tools/reftest/Makefile.in index f64b2351a2..21c56c4eb2 100644 --- a/layout/tools/reftest/Makefile.in +++ b/layout/tools/reftest/Makefile.in @@ -10,8 +10,9 @@ _HARNESS_FILES = \ $(srcdir)/reftestcommandline.py \ $(srcdir)/remotereftest.py \ $(srcdir)/runreftestb2g.py \ - $(srcdir)/b2g_desktop.py \ + $(srcdir)/runreftestmulet.py \ $(srcdir)/gaia_lock_screen.js \ + $(srcdir)/output.py \ automation.py \ $(topsrcdir)/testing/mozbase/mozdevice/mozdevice/devicemanager.py \ $(topsrcdir)/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py \ diff --git a/layout/tools/reftest/jar.mn b/layout/tools/reftest/jar.mn index 8a38a910c5..776e9f77c6 100644 --- a/layout/tools/reftest/jar.mn +++ b/layout/tools/reftest/jar.mn @@ -2,6 +2,7 @@ reftest.jar: % content reftest %content/ * content/reftest-content.js (reftest-content.js) content/httpd.jsm (../../../netwerk/test/httpserver/httpd.js) + content/StructuredLog.jsm (../../../testing/modules/StructuredLog.jsm) #ifdef BOOTSTRAP * content/reftest.jsm (reftest.js) #else diff --git a/layout/tools/reftest/mach_commands.py b/layout/tools/reftest/mach_commands.py index 7237e05bfd..d12c753213 100644 --- a/layout/tools/reftest/mach_commands.py +++ b/layout/tools/reftest/mach_commands.py @@ -4,7 +4,6 @@ from __future__ import absolute_import, unicode_literals -import mozpack.path as mozpath import os import re import sys @@ -18,7 +17,6 @@ from mozbuild.base import ( ) from mach.decorators import ( - CommandArgument, CommandProvider, Command, ) @@ -33,8 +31,8 @@ If you have a B2G build, this can be found in '''.lstrip() GAIA_PROFILE_NOT_FOUND = ''' -The %s command requires a non-debug gaia profile. Either pass in --profile, -or set the GAIA_PROFILE environment variable. +The reftest command requires a non-debug gaia profile on Mulet. +Either pass in --profile, or set the GAIA_PROFILE environment variable. If you do not have a non-debug gaia profile, you can build one: $ git clone https://github.com/mozilla-b2g/gaia @@ -45,8 +43,8 @@ The profile should be generated in a directory called 'profile'. '''.lstrip() GAIA_PROFILE_IS_DEBUG = ''' -The %s command requires a non-debug gaia profile. The specified profile, -%s, is a debug profile. +The reftest command requires a non-debug gaia profile on Mulet. +The specified profile, %s, is a debug profile. If you do not have a non-debug gaia profile, you can build one: $ git clone https://github.com/mozilla-b2g/gaia @@ -57,12 +55,13 @@ The profile should be generated in a directory called 'profile'. '''.lstrip() MARIONETTE_DISABLED = ''' -The %s command requires a marionette enabled build. +The reftest command requires a marionette enabled build on Mulet. Add 'ENABLE_MARIONETTE=1' to your mozconfig file and re-build the application. Your currently active mozconfig is %s. '''.lstrip() + class ReftestRunner(MozbuildObject): """Easily run reftests. @@ -83,13 +82,28 @@ class ReftestRunner(MozbuildObject): def _make_shell_string(self, s): return "'%s'" % re.sub("'", r"'\''", s) + def _setup_objdir(self, **kwargs): + # reftest imports will happen from the objdir + sys.path.insert(0, self.reftest_dir) + + if not kwargs["tests"]: + test_subdir = { + "reftest": os.path.join('layout', 'reftests'), + "crashtest": os.path.join('layout', 'crashtest'), + }[kwargs['suite']] + kwargs["tests"] = [test_subdir] + + tests = os.path.join(self.reftest_dir, 'tests') + if not os.path.isdir(tests): + os.symlink(self.topsrcdir, tests) + def run_b2g_test(self, b2g_home=None, xre_path=None, **kwargs): """Runs a b2g reftest. filter is a regular expression (in JS syntax, as could be passed to the RegExp constructor) to select which reftests to run from the manifest. - test_file is a path to a test file. It can be a relative path from the + tests is a list of paths. It can be a relative path from the top source directory, an absolute filename, or a directory containing test files. @@ -99,21 +113,8 @@ class ReftestRunner(MozbuildObject): if kwargs["suite"] not in ('reftest', 'crashtest'): raise Exception('None or unrecognized reftest suite type.') - sys.path.insert(0, self.reftest_dir) - - test_subdir = {"reftest": os.path.join('layout', 'reftests'), - "crashtest": os.path.join('layout', 'crashtest')}[kwargs["suite"]] - - # Find the manifest file - if not kwargs["tests"]: - if not os.path.exists(os.path.join(self.topsrcdir, test_subdir)): - test_file = mozpath.relpath(os.path.abspath(test_subdir), - self.topsrcdir) - kwargs["tests"] = [test_subdir] - - tests = os.path.join(self.reftest_dir, 'tests') - if not os.path.isdir(tests): - os.symlink(self.topsrcdir, tests) + self._setup_objdir(**kwargs) + import runreftestb2g for i, path in enumerate(kwargs["tests"]): # Non-absolute paths are relative to the packaged directory, which @@ -122,45 +123,6 @@ class ReftestRunner(MozbuildObject): path = os.path.relpath(path, os.path.join(self.topsrcdir)) kwargs["tests"][i] = os.path.join('tests', path) - if conditions.is_b2g_desktop(self): - return self.run_b2g_desktop(**kwargs) - - return self.run_b2g_remote(b2g_home, xre_path, **kwargs) - - def run_b2g_desktop(self, **kwargs): - if self.substs.get('ENABLE_MARIONETTE') != '1': - print(MARIONETTE_DISABLED % ('mochitest-b2g-desktop', - self.mozconfig['path'])) - return 1 - - if not kwargs["profile"]: - gaia_profile = os.environ.get('GAIA_PROFILE') - if not gaia_profile: - print(GAIA_PROFILE_NOT_FOUND % 'reftest-b2g-desktop') - return 1 - kwargs["profile"] = gaia_profile - - - if os.path.isfile(os.path.join(kwargs["profile"], 'extensions', - 'httpd@gaiamobile.org')): - print(GAIA_PROFILE_IS_DEBUG % ('mochitest-b2g-desktop', - kwargs["profile"])) - return 1 - - kwargs["desktop"] = True - kwargs["app"] = self.get_binary_path() - if kwargs["oop"]: - options.browser_arg = '-oop' - if not kwargs["app"].endswith('-bin'): - kwargs["app"] = '%s-bin' % options.app - if not os.path.isfile(kwargs["app"]): - options.app = kwargs["app"][:-len('-bin')] - - return runreftestb2g.run(**kwargs) - - def run_b2g_remote(self, b2g_home, xre_path, **kwargs): - import runreftestb2g - try: which.which('adb') except which.WhichError: @@ -177,10 +139,44 @@ class ReftestRunner(MozbuildObject): if kwargs["suite"] == 'reftest': kwargs["oop"] = True - return runreftestb2g.run_remote(**kwargs) + return runreftestb2g.run(**kwargs) + + def run_mulet_test(self, **kwargs): + """Runs a mulet reftest.""" + self._setup_objdir(**kwargs) + import runreftestmulet + + if self.substs.get('ENABLE_MARIONETTE') != '1': + print(MARIONETTE_DISABLED % self.mozconfig['path']) + return 1 + + if not kwargs["profile"]: + gaia_profile = os.environ.get('GAIA_PROFILE') + if not gaia_profile: + print(GAIA_PROFILE_NOT_FOUND) + return 1 + kwargs["profile"] = gaia_profile + + if os.path.isfile(os.path.join(kwargs["profile"], 'extensions', + 'httpd@gaiamobile.org')): + print(GAIA_PROFILE_IS_DEBUG % kwargs["profile"]) + return 1 + + kwargs['app'] = self.get_binary_path() + kwargs['mulet'] = True + kwargs['oop'] = True + + if kwargs['oop']: + kwargs['browser_arg'] = '-oop' + if not kwargs['app'].endswith('-bin'): + kwargs['app'] = '%s-bin' % kwargs['app'] + if not os.path.isfile(kwargs['app']): + kwargs['app'] = kwargs['app'][:-len('-bin')] + + return runreftestmulet.run(**kwargs) def run_desktop_test(self, **kwargs): - """Runs a reftest.""" + """Runs a reftest, in desktop Firefox.""" import runreftest if kwargs["suite"] not in ('reftest', 'crashtest', 'jstestbrowser'): @@ -193,7 +189,7 @@ class ReftestRunner(MozbuildObject): "jstests.list") } - kwargs["extraProfileFiles"] = [os.path.join(self.topobjdir, "dist", "plugins")] + kwargs["extraProfileFiles"].append(os.path.join(self.topobjdir, "dist", "plugins")) kwargs["symbolsPath"] = os.path.join(self.topobjdir, "crashreporter-symbols") if not kwargs["tests"]: @@ -207,20 +203,121 @@ class ReftestRunner(MozbuildObject): if not kwargs["runTestsInParallel"]: kwargs["logFile"] = "%s.log" % kwargs["suite"] - #Remove the stdout handler from the internal logger and let mach deal with it - runreftest.log.removeHandler(runreftest.log.handlers[0]) self.log_manager.enable_unstructured() - rv = runreftest.run(**kwargs) - self.log_manager.disable_unstructured() + try: + rv = runreftest.run(**kwargs) + finally: + self.log_manager.disable_unstructured() return rv + def run_android_test(self, **kwargs): + """Runs a reftest, in Firefox for Android.""" + import runreftest + + if kwargs["suite"] not in ('reftest', 'crashtest', 'jstestbrowser'): + raise Exception('None or unrecognized reftest suite type.') + if "ipc" in kwargs.keys(): + raise Exception('IPC tests not supported on Android.') + + default_manifest = { + "reftest": (self.topsrcdir, "layout", "reftests", "reftest.list"), + "crashtest": (self.topsrcdir, "testing", "crashtest", "crashtests.list"), + "jstestbrowser": ("jsreftest", "tests", "jstests.list") + } + + if not kwargs["tests"]: + kwargs["tests"] = [os.path.join(*default_manifest[kwargs["suite"]])] + + kwargs["extraProfileFiles"].append( + os.path.join(self.topobjdir, "dist", "bin", "res", "fonts")) + + if not kwargs["httpdPath"]: + kwargs["httpdPath"] = os.path.join(self.tests_dir, "modules") + if not kwargs["symbolsPath"]: + kwargs["symbolsPath"] = os.path.join(self.topobjdir, "crashreporter-symbols") + if not kwargs["xrePath"]: + kwargs["xrePath"] = os.environ.get("MOZ_HOST_BIN") + if not kwargs["app"]: + kwargs["app"] = self.substs["ANDROID_PACKAGE_NAME"] + kwargs["dm_trans"] = "adb" + kwargs["ignoreWindowSize"] = True + kwargs["printDeviceInfo"] = False + + # A symlink and some path manipulations are required so that test + # manifests can be found both locally and remotely (via a url) + # using the same relative path. + if kwargs["suite"] == "jstestbrowser": + staged_js_dir = os.path.join(self.topobjdir, "dist", "test-stage", "jsreftest") + tests = os.path.join(self.reftest_dir, 'jsreftest') + if not os.path.isdir(tests): + os.symlink(staged_js_dir, tests) + kwargs["extraProfileFiles"].append(os.path.join(staged_js_dir, "tests", "user.js")) + else: + tests = os.path.join(self.reftest_dir, "tests") + if not os.path.isdir(tests): + os.symlink(self.topsrcdir, tests) + for i, path in enumerate(kwargs["tests"]): + # Non-absolute paths are relative to the packaged directory, which + # has an extra tests/ at the start + if os.path.exists(os.path.abspath(path)): + path = os.path.relpath(path, os.path.join(self.topsrcdir)) + kwargs["tests"][i] = os.path.join('tests', path) + + # Need to chdir to reftest_dir otherwise imports fail below. + os.chdir(self.reftest_dir) + + # The imp module can spew warnings if the modules below have + # already been imported, ignore them. + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + + import imp + path = os.path.join(self.reftest_dir, 'remotereftest.py') + with open(path, 'r') as fh: + imp.load_module('reftest', fh, path, ('.py', 'r', imp.PY_SOURCE)) + import reftest + + # Remove the stdout handler from the internal logger and let mach deal with it + runreftest.log.removeHandler(runreftest.log.handlers[0]) + self.log_manager.enable_unstructured() + try: + rv = reftest.run(**kwargs) + finally: + self.log_manager.disable_unstructured() + + return rv + + +def process_test_objects(kwargs): + """|mach test| works by providing a test_objects argument, from + which the test path must be extracted and converted into a normal + reftest tests argument.""" + + if "test_objects" in kwargs: + if kwargs["tests"] is None: + kwargs["tests"] = [] + kwargs["tests"].extend(item["path"] for item in kwargs["test_objects"]) + del kwargs["test_objects"] + + +def get_parser(): + here = os.path.abspath(os.path.dirname(__file__)) + build_obj = MozbuildObject.from_environment(cwd=here) + if conditions.is_android(build_obj): + return reftestcommandline.RemoteArgumentsParser() + elif conditions.is_mulet(build_obj): + return reftestcommandline.B2GArgumentParser() + else: + return reftestcommandline.DesktopArgumentsParser() + + @CommandProvider class MachCommands(MachCommandBase): @Command('reftest', category='testing', description='Run reftests (layout and graphics correctness).', - parser=reftestcommandline.DesktopArgumentsParser) + parser=get_parser) def run_reftest(self, **kwargs): kwargs["suite"] = "reftest" return self._run_reftest(**kwargs) @@ -228,7 +325,7 @@ class MachCommands(MachCommandBase): @Command('jstestbrowser', category='testing', description='Run js/src/tests in the browser.', - parser=reftestcommandline.DesktopArgumentsParser) + parser=get_parser) def run_jstestbrowser(self, **kwargs): self._mach_context.commands.dispatch("build", self._mach_context, @@ -239,7 +336,7 @@ class MachCommands(MachCommandBase): @Command('reftest-ipc', category='testing', description='Run IPC reftests (layout and graphics correctness, separate process).', - parser=reftestcommandline.DesktopArgumentsParser) + parser=get_parser) def run_ipc(self, **kwargs): kwargs["ipc"] = True kwargs["suite"] = "reftest" @@ -248,7 +345,7 @@ class MachCommands(MachCommandBase): @Command('crashtest', category='testing', description='Run crashtests (Check if crashes on a page).', - parser=reftestcommandline.DesktopArgumentsParser) + parser=get_parser) def run_crashtest(self, **kwargs): kwargs["suite"] = "crashtest" return self._run_reftest(**kwargs) @@ -256,14 +353,21 @@ class MachCommands(MachCommandBase): @Command('crashtest-ipc', category='testing', description='Run IPC crashtests (Check if crashes on a page, separate process).', - parser=reftestcommandline.DesktopArgumentsParser) + parser=get_parser) def run_crashtest_ipc(self, **kwargs): kwargs["ipc"] = True kwargs["suite"] = "crashtest" return self._run_reftest(**kwargs) def _run_reftest(self, **kwargs): + process_test_objects(kwargs) reftest = self._spawn(ReftestRunner) + if conditions.is_android(self): + from mozrunner.devices.android_device import verify_android_device + verify_android_device(self, install=True, xre=True) + return reftest.run_android_test(**kwargs) + elif conditions.is_mulet(self): + return reftest.run_mulet_test(**kwargs) return reftest.run_desktop_test(**kwargs) @@ -290,14 +394,6 @@ class B2GCommands(MachCommandBase): kwargs["suite"] = "reftest" return self._run_reftest(**kwargs) - @Command('reftest-b2g-desktop', category='testing', - description='Run a b2g desktop reftest (b2g desktop layout and graphics correctness).', - conditions=[conditions.is_b2g_desktop], - parser=reftestcommandline.B2GArgumentParser) - def run_reftest_b2g_desktop(self, **kwargs): - kwargs["suite"] = "reftest" - return self._run_reftest(**kwargs) - @Command('crashtest-remote', category='testing', description='Run a remote crashtest (Check if b2g crashes on a page, remote device).', conditions=[conditions.is_b2g, is_emulator], @@ -307,6 +403,7 @@ class B2GCommands(MachCommandBase): return self._run_reftest(**kwargs) def _run_reftest(self, **kwargs): + process_test_objects(kwargs) if self.device_name: if self.device_name.startswith('emulator'): emulator = 'arm' diff --git a/layout/tools/reftest/output.py b/layout/tools/reftest/output.py new file mode 100644 index 0000000000..dd5eb99c52 --- /dev/null +++ b/layout/tools/reftest/output.py @@ -0,0 +1,144 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import json +import os +import threading + +from mozlog.formatters import TbplFormatter +from mozrunner.utils import get_stack_fixer_function + + +class ReftestFormatter(TbplFormatter): + """ + Formatter designed to preserve the legacy "tbpl" format in reftest. + + This is needed for both the reftest-analyzer and mozharness log parsing. + We can change this format when both reftest-analyzer and mozharness have + been changed to read structured logs. + """ + + def __call__(self, data): + if 'component' in data and data['component'] == 'mozleak': + # Output from mozleak requires that no prefix be added + # so that mozharness will pick up these failures. + return "%s\n" % data['message'] + + formatted = TbplFormatter.__call__(self, data) + if data['action'] == 'process_output': + return formatted + return 'REFTEST %s' % formatted + + def log(self, data): + prefix = "%s |" % data['level'].upper() + return "%s %s\n" % (prefix, data['message']) + + def test_end(self, data): + extra = data.get('extra', {}) + status = data['status'] + + status_msg = "TEST-" + if 'expected' in data: + status_msg += "UNEXPECTED-%s" % status + else: + if status != "PASS": + status_msg += "KNOWN-" + status_msg += status + if extra.get('status_msg') == 'Random': + status_msg += "(EXPECTED RANDOM)" + test = self.id_str(data['test']) + if 'message' in data: + status_details = data['message'] + elif isinstance(data['test'], tuple): + status_details = 'image comparison ({})'.format(data['test'][1]) + else: + status_details = '(LOAD ONLY)' + + output_text = "%s | %s | %s" % (status_msg, test, status_details) + if 'differences' in extra: + diff_msg = (", max difference: %(max_difference)s" + ", number of differing pixels: %(differences)s") % extra + diagnostic_data = ("REFTEST IMAGE 1 (TEST): %(image1)s\n" + "REFTEST IMAGE 2 (REFERENCE): %(image2)s") % extra + output_text += '%s\n%s' % (diff_msg, diagnostic_data) + elif "image1" in extra: + diagnostic_data = "REFTEST IMAGE: %(image1)s" % extra + output_text += '\n%s' % diagnostic_data + + output_text += "\nREFTEST TEST-END | %s" % test + return "%s\n" % output_text + + def process_output(self, data): + return "%s\n" % data["data"] + + def suite_end(self, data): + lines = [] + summary = data['extra']['results'] + summary['success'] = summary['Pass'] + summary['LoadOnly'] + lines.append("Successful: %(success)s (%(Pass)s pass, %(LoadOnly)s load only)" % + summary) + summary['unexpected'] = (summary['Exception'] + summary['FailedLoad'] + + summary['UnexpectedFail'] + summary['UnexpectedPass'] + + summary['AssertionUnexpected'] + + summary['AssertionUnexpectedFixed']) + lines.append(("Unexpected: %(unexpected)s (%(UnexpectedFail)s unexpected fail, " + "%(UnexpectedPass)s unexpected pass, " + "%(AssertionUnexpected)s unexpected asserts, " + "%(FailedLoad)s failed load, " + "%(Exception)s exception)") % summary) + summary['known'] = (summary['KnownFail'] + summary['AssertionKnown'] + + summary['Random'] + summary['Skip'] + summary['Slow']) + lines.append(("Known problems: %(known)s (" + + "%(KnownFail)s known fail, " + + "%(AssertionKnown)s known asserts, " + + "%(Random)s random, " + + "%(Skip)s skipped, " + + "%(Slow)s slow)") % summary) + lines = ["REFTEST INFO | %s" % s for s in lines] + lines.append("REFTEST SUITE-END | Shutdown") + return "INFO | Result summary:\n{}\n".format('\n'.join(lines)) + + def id_str(self, test_id): + if isinstance(test_id, basestring): + return test_id + return test_id[0] + + +class OutputHandler(object): + """Process the output of a process during a test run and translate + raw data logged from reftest.js to an appropriate structured log action, + where applicable. + """ + + def __init__(self, log, utilityPath, symbolsPath=None): + self.stack_fixer_function = get_stack_fixer_function(utilityPath, symbolsPath) + self.log = log + # needed for b2gautomation.py + self.suite_finished = False + + def __call__(self, line): + # need to return processed messages to appease remoteautomation.py + if not line.strip(): + return [] + + try: + data = json.loads(line) + except ValueError: + self.verbatim(line) + return [line] + + if isinstance(data, dict) and 'action' in data: + if data['action'] == 'suite_end': + self.suite_finished = True + + self.log.log_raw(data) + else: + self.verbatim(json.dumps(data)) + + return [data] + + def verbatim(self, line): + if self.stack_fixer_function: + line = self.stack_fixer_function(line) + self.log.process_output(threading.current_thread().name, line) diff --git a/layout/tools/reftest/reftest.js b/layout/tools/reftest/reftest.js index 6b614fba0c..6a48112fb1 100644 --- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest.js @@ -9,7 +9,7 @@ this.EXPORTED_SYMBOLS = ["OnRefTestLoad"]; #endif -const CC = Components.classes; +var CC = Components.classes; const CI = Components.interfaces; const CR = Components.results; const CU = Components.utils; @@ -38,13 +38,17 @@ const NS_OBSERVER_SERVICE_CONTRACTID = CU.import("resource://gre/modules/FileUtils.jsm"); CU.import("chrome://reftest/content/httpd.jsm", this); +CU.import("chrome://reftest/content/StructuredLog.jsm", this); CU.import("resource://gre/modules/Services.jsm"); +CU.import("resource://gre/modules/NetUtil.jsm"); var gLoadTimeout = 0; var gTimeoutHook = null; var gRemote = false; var gIgnoreWindowSize = false; var gShuffle = false; +var gRepeat = null; +var gRunUntilFailure = false; var gTotalChunks = 0; var gThisChunk = 0; var gContainingWindow = null; @@ -96,6 +100,7 @@ var gTotalTests = 0; var gState; var gCurrentURL; var gTestLog = []; +var gLogLevel; var gServer; var gCount = 0; var gAssertionCount = 0; @@ -160,33 +165,41 @@ var gNoCanvasCache = false; var gRecycledCanvases = new Array(); -// By default we just log to stdout -var gDumpLog = dump; -var gVerbose = false; - // Only dump the sandbox once, because it doesn't depend on the // manifest URL (yet!). var gDumpedConditionSandbox = false; -function LogWarning(str) +function HasUnexpectedResult() { - gDumpLog("REFTEST INFO | " + str + "\n"); + return gTestResults.Exception > 0 || + gTestResults.FailedLoad > 0 || + gTestResults.UnexpectedFail > 0 || + gTestResults.UnexpectedPass > 0 || + gTestResults.AssertionUnexpected > 0 || + gTestResults.AssertionUnexpectedFixed > 0; +} + +// By default we just log to stdout +var gDumpFn = dump; +var gDumpRawLog = function(record) { + // Dump JSON representation of data on a single line + var line = JSON.stringify(record); + gDumpFn("\n" + line + "\n"); +} +var logger = new StructuredLogger('reftest', gDumpRawLog); + +function TestBuffer(str) +{ + logger.debug(str); gTestLog.push(str); } -function LogInfo(str) +function FlushTestBuffer() { - if (gVerbose) - gDumpLog("REFTEST INFO | " + str + "\n"); - gTestLog.push(str); -} - -function FlushTestLog() -{ - if (!gVerbose) { - // In verbose mode, we've dumped all these messages already. + // In debug mode, we've dumped all these messages already. + if (gLogLevel !== 'debug') { for (var i = 0; i < gTestLog.length; ++i) { - gDumpLog("REFTEST INFO | Saved log: " + gTestLog[i] + "\n"); + logger.info("Saved log: " + gTestLog[i]); } } gTestLog = []; @@ -231,7 +244,7 @@ function getTestPlugin(aName) { return tags[i]; } - LogWarning("Failed to find the test-plugin."); + logger.warning("Failed to find the test-plugin."); return null; } @@ -244,7 +257,6 @@ this.OnRefTestLoad = function OnRefTestLoad(win) var env = CC["@mozilla.org/process/environment;1"]. getService(CI.nsIEnvironment); - gVerbose = !!env.get("MOZ_REFTEST_VERBOSE"); var prefs = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefBranch); @@ -266,6 +278,12 @@ this.OnRefTestLoad = function OnRefTestLoad(win) gBrowserIsIframe = false; } + try { + gLogLevel = prefs.getCharPref("reftest.logLevel"); + } catch (e) { + gLogLevel ='info'; + } + if (win === undefined || win == null) { win = window; } @@ -309,7 +327,7 @@ this.OnRefTestLoad = function OnRefTestLoad(win) plugin1.enabledState = CI.nsIPluginTag.STATE_ENABLED; plugin2.enabledState = CI.nsIPluginTag.STATE_ENABLED; } else { - LogWarning("Could not get test plugin tags."); + logger.warning("Could not get test plugin tags."); } gBrowserMessageManager = gBrowser.QueryInterface(CI.nsIFrameLoaderOwner) @@ -326,7 +344,7 @@ function InitAndStartRefTests() var prefs = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefBranch); } catch(e) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + e + "\n"); + logger.error("EXCEPTION: " + e); } try { @@ -348,7 +366,7 @@ function InitAndStartRefTests() var f = FileUtils.File(logFile); var mfl = FileUtils.openFileOutputStream(f, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE); // Set to mirror to stdout as well as the file - gDumpLog = function (msg) { + gDumpFn = function (msg) { #ifdef BOOTSTRAP #ifdef REFTEST_B2G dump(msg); @@ -363,7 +381,7 @@ function InitAndStartRefTests() } catch(e) { // If there is a problem, just use stdout - gDumpLog = dump; + gDumpFn = dump; } } } catch(e) {} @@ -414,7 +432,7 @@ function InitAndStartRefTests() } catch (ex) { //gBrowser.loadURI('data:text/plain,' + ex); ++gTestResults.Exception; - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n"); + logger.error("EXCEPTION: " + ex); DoneTests(); } @@ -452,7 +470,7 @@ function StartTests() var prefs = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefBranch); } catch(e) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + e + "\n"); + logger.error("EXCEPTION: " + e); } try { @@ -467,6 +485,22 @@ function StartTests() gShuffle = false; } + try { + gRunUntilFailure = prefs.getBoolPref("reftest.runUntilFailure"); + } catch (e) { + gRunUntilFailure = false; + } + + // When we repeat this function is called again, so really only want to set + // gRepeat once. + if (gRepeat == null) { + try { + gRepeat = prefs.getIntPref("reftest.repeat"); + } catch (e) { + gRepeat = 0; + } + } + try { gRunSlowTests = prefs.getIntPref("reftest.skipslowtests"); } catch(e) { @@ -478,12 +512,13 @@ function StartTests() } gURLs = []; + gManifestsLoaded = {}; try { var manifests = JSON.parse(prefs.getCharPref("reftest.manifests")); gURLFilterRegex = manifests[null]; } catch(e) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | Unable to find reftest.manifests pref. Please ensure your profile is setup properly\n"); + logger.error("Unable to find reftest.manifests pref. Please ensure your profile is setup properly"); DoneTests(); } @@ -495,7 +530,7 @@ function StartTests() // process includes before reading the included manifest again manifestURLs.sort(function(a,b) {return a.length - b.length}) manifestURLs.forEach(function(manifestURL) { - gDumpLog("Readings manifest" + manifestURL + "\n"); + logger.info("Reading manifest " + manifestURL); var filter = manifests[manifestURL] ? new RegExp(manifests[manifestURL]) : null; ReadTopManifest(manifestURL, [globalFilter, filter, false]); }); @@ -504,6 +539,7 @@ function StartTests() // Filter tests which will be skipped to get a more even distribution when chunking // tURLs is a temporary array containing all active tests var tURLs = new Array(); + var tIDs = new Array(); for (var i = 0; i < gURLs.length; ++i) { if (gURLs[i].expected == EXPECTED_DEATH) continue; @@ -515,9 +551,10 @@ function StartTests() continue; tURLs.push(gURLs[i]); + tIDs.push(gURLs[i].identifier); } - gDumpLog("REFTEST INFO | Discovered " + gURLs.length + " tests, after filtering SKIP tests, we have " + tURLs.length + "\n"); + logger.suiteStart(tIDs, {"skipped": gURLs.length - tURLs.length}); if (gTotalChunks > 0 && gThisChunk > 0) { // Calculate start and end indices of this chunk if tURLs array were @@ -532,8 +569,8 @@ function StartTests() end = gThisChunk == gTotalChunks ? gURLs.length : gURLs.indexOf(tURLs[end + 1]) - 1; gURLs = gURLs.slice(start, end); - gDumpLog("REFTEST INFO | Running chunk " + gThisChunk + " out of " + gTotalChunks + " chunks. "); - gDumpLog("tests " + (start+1) + "-" + end + "/" + gURLs.length + "\n"); + logger.info("Running chunk " + gThisChunk + " out of " + gTotalChunks + " chunks. " + + "tests " + (start+1) + "-" + end + "/" + gURLs.length); } if (gShuffle) { @@ -550,7 +587,7 @@ function StartTests() } catch (ex) { //gBrowser.loadURI('data:text/plain,' + ex); ++gTestResults.Exception; - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n"); + logger.error("EXCEPTION: " + ex); DoneTests(); } } @@ -563,7 +600,7 @@ function OnRefTestUnload() plugin1.enabledState = gTestPluginEnabledStates[0]; plugin2.enabledState = gTestPluginEnabledStates[1]; } else { - LogWarning("Failed to get test plugin tags."); + logger.warning("Failed to get test plugin tags."); } } @@ -635,7 +672,6 @@ function BuildConditionSandbox(aURL) { // Shortcuts for widget toolkits. sandbox.B2G = xr.widgetToolkit == "gonk"; - sandbox.B2GDT = appInfo.name.toLowerCase() == "b2g" && !sandbox.B2G; sandbox.Android = xr.OS == "Android" && !sandbox.B2G; sandbox.cocoaWidget = xr.widgetToolkit == "cocoa"; sandbox.gtkWidget = xr.widgetToolkit == "gtk2" @@ -751,8 +787,8 @@ function BuildConditionSandbox(aURL) { } if (!gDumpedConditionSandbox) { - dump("REFTEST INFO | Dumping JSON representation of sandbox \n"); - dump("REFTEST INFO | " + JSON.stringify(CU.waiveXrays(sandbox)) + " \n"); + logger.info("Dumping JSON representation of sandbox"); + logger.info(JSON.stringify(CU.waiveXrays(sandbox))); gDumpedConditionSandbox = true; } @@ -813,6 +849,12 @@ function AddTestItem(aTest, aFilter) if (gFocusFilterMode == FOCUS_FILTER_NON_NEEDS_FOCUS_TESTS && aTest.needsFocus) return; + + if (aTest.url2 !== null) + aTest.identifier = [aTest.prettyPath, aTest.type, aTest.url2.spec]; + else + aTest.identifier = aTest.prettyPath; + gURLs.push(aTest); } @@ -835,17 +877,11 @@ function ReadManifest(aURL, inherited_status, aFilter) .getService(CI.nsIScriptSecurityManager); var listURL = aURL; - var channel = gIOService.newChannelFromURI2(aURL, - null, // aLoadingNode - Services.scriptSecurityManager.getSystemPrincipal(), - null, // aTriggeringPrincipal - CI.nsILoadInfo.SEC_NORMAL, - CI.nsIContentPolicy.TYPE_OTHER); - var inputStream = channel.open(); + var channel = NetUtil.newChannel({uri: aURL, loadUsingSystemPrincipal: true}); + var inputStream = channel.open2(); if (channel instanceof Components.interfaces.nsIHttpChannel && channel.responseStatus != 200) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | HTTP ERROR : " + - channel.responseStatus + "\n"); + logger.error("HTTP ERROR : " + channel.responseStatus); } var streamBuf = getStreamContent(inputStream); inputStream.close(); @@ -1245,31 +1281,35 @@ function StartCurrentTest() // make sure we don't run tests that are expected to kill the browser while (gURLs.length > 0) { var test = gURLs[0]; + logger.testStart(test.identifier); if (test.expected == EXPECTED_DEATH) { ++gTestResults.Skip; - gDumpLog("REFTEST TEST-KNOWN-FAIL | " + test.url1.spec + " | (SKIP)\n"); + logger.testEnd(test.identifier, "SKIP"); gURLs.shift(); } else if (test.needsFocus && !Focus()) { // FIXME: Marking this as a known fail is dangerous! What // if it starts failing all the time? ++gTestResults.Skip; - gDumpLog("REFTEST TEST-KNOWN-FAIL | " + test.url1.spec + " | (SKIPPED; COULDN'T GET FOCUS)\n"); + logger.testEnd(test.identifier, "SKIP", null, "(COULDN'T GET FOCUS)"); gURLs.shift(); } else if (test.slow && !gRunSlowTests) { ++gTestResults.Slow; - gDumpLog("REFTEST TEST-KNOWN-SLOW | " + test.url1.spec + " | (SLOW)\n"); + logger.testEnd(test.identifier, "SKIP", null, "(SLOW)"); gURLs.shift(); } else { break; } } - if (gURLs.length == 0) { + if ((gURLs.length == 0 && gRepeat == 0) || + (gRunUntilFailure && HasUnexpectedResult())) { RestoreChangedPreferences(); DoneTests(); - } - else { - gDumpLog("REFTEST TEST-START | " + gURLs[0].prettyPath + "\n"); + } else if (gURLs.length == 0 && gRepeat > 0) { + // Repeat + gRepeat--; + StartTests(); + } else { if (gURLs[0].chaosMode) { gWindowUtils.enterChaosMode(); } @@ -1335,32 +1375,30 @@ function StartCurrentURI(aState) } else if (ps.type == PREF_INTEGER) { prefs.setIntPref(ps.name, value); } - gDumpLog("SET PREFERENCE pref(" + ps.name + "," + value + ")\n"); + logger.info("SET PREFERENCE pref(" + ps.name + "," + value + ")"); } }); } catch (e) { if (e == "bad pref") { var test = gURLs[0]; if (test.expected == EXPECTED_FAIL) { - gDumpLog("REFTEST TEST-KNOWN-FAIL | " + test.url1.spec + - " | (SKIPPED; " + badPref + " not known or wrong type)\n"); + logger.testEnd(test.identifier, "FAIL", "FAIL", + "(SKIPPED; " + badPref + " not known or wrong type)"); ++gTestResults.Skip; } else { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + test.url1.spec + - " | " + badPref + " not known or wrong type\n"); + logger.testEnd(test.identifier, "FAIL", "PASS", + badPref + " not known or wrong type"); ++gTestResults.UnexpectedFail; } + + // skip the test that had a bad preference + gURLs.shift(); + StartCurrentTest(); + return; } else { throw e; } } - if (badPref != undefined) { - // skip the test that had a bad preference - gURLs.shift(); - - StartCurrentTest(); - return; - } } if (prefSettings.length == 0 && @@ -1373,9 +1411,11 @@ function StartCurrentURI(aState) gContainingWindow.setTimeout(RecordResult, 0); } else { var currentTest = gTotalTests - gURLs.length; - gDumpLog("REFTEST TEST-LOAD | " + gCurrentURL + " | " + currentTest + " / " + gTotalTests + - " (" + Math.floor(100 * (currentTest / gTotalTests)) + "%)\n"); - LogInfo("START " + gCurrentURL); + // Log this to preserve the same overall log format, + // should be removed if the format is updated + gDumpFn("REFTEST TEST-LOAD | " + gCurrentURL + " | " + currentTest + " / " + gTotalTests + + " (" + Math.floor(100 * (currentTest / gTotalTests)) + "%)\n"); + TestBuffer("START " + gCurrentURL); var type = gURLs[0].type if (TYPE_SCRIPT == type) { SendLoadScriptTest(gCurrentURL, gLoadTimeout); @@ -1387,37 +1427,10 @@ function StartCurrentURI(aState) function DoneTests() { - gDumpLog("REFTEST FINISHED: Slowest test took " + gSlowestTestTime + - "ms (" + gSlowestTestURL + ")\n"); + logger.suiteEnd(extra={'results': gTestResults}); + logger.info("Slowest test took " + gSlowestTestTime + "ms (" + gSlowestTestURL + ")"); + logger.info("Total canvas count = " + gRecycledCanvases.length); - gDumpLog("REFTEST INFO | Result summary:\n"); - var count = gTestResults.Pass + gTestResults.LoadOnly; - gDumpLog("REFTEST INFO | Successful: " + count + " (" + - gTestResults.Pass + " pass, " + - gTestResults.LoadOnly + " load only)\n"); - count = gTestResults.Exception + gTestResults.FailedLoad + - gTestResults.UnexpectedFail + gTestResults.UnexpectedPass + - gTestResults.AssertionUnexpected + - gTestResults.AssertionUnexpectedFixed; - gDumpLog("REFTEST INFO | Unexpected: " + count + " (" + - gTestResults.UnexpectedFail + " unexpected fail, " + - gTestResults.UnexpectedPass + " unexpected pass, " + - gTestResults.AssertionUnexpected + " unexpected asserts, " + - gTestResults.AssertionUnexpectedFixed + " unexpected fixed asserts, " + - gTestResults.FailedLoad + " failed load, " + - gTestResults.Exception + " exception)\n"); - count = gTestResults.KnownFail + gTestResults.AssertionKnown + - gTestResults.Random + gTestResults.Skip + gTestResults.Slow; - gDumpLog("REFTEST INFO | Known problems: " + count + " (" + - gTestResults.KnownFail + " known fail, " + - gTestResults.AssertionKnown + " known asserts, " + - gTestResults.Random + " random, " + - gTestResults.Skip + " skipped, " + - gTestResults.Slow + " slow)\n"); - - gDumpLog("REFTEST INFO | Total canvas count = " + gRecycledCanvases.length + "\n"); - - gDumpLog("REFTEST TEST-START | Shutdown\n"); function onStopped() { let appStartup = CC["@mozilla.org/toolkit/app-startup;1"].getService(CI.nsIAppStartup); appStartup.quit(CI.nsIAppStartup.eForceQuit); @@ -1465,7 +1478,7 @@ function DoDrawWindow(ctx, x, y, w, h) // browser element flags |= ctx.DRAWWINDOW_USE_WIDGET_LAYERS; } else if (gBrowserIsRemote) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | can't drawWindow remote content\n"); + logger.error(gCurrentURL + " | can't drawWindow remote content"); ++gTestResults.Exception; } @@ -1478,22 +1491,21 @@ function DoDrawWindow(ctx, x, y, w, h) } else { // Output a special warning because we need to be able to detect // this whenever it happens. - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | WARNING: USE_WIDGET_LAYERS disabled\n"); + logger.error("WARNING: USE_WIDGET_LAYERS disabled"); } - gDumpLog("REFTEST INFO | drawWindow flags = " + flagsStr + - "; window size = " + gContainingWindow.innerWidth + "," + gContainingWindow.innerHeight + - "; test browser size = " + testRect.width + "," + testRect.height + - "\n"); + logger.info("drawWindow flags = " + flagsStr + + "; window size = " + gContainingWindow.innerWidth + "," + gContainingWindow.innerHeight + + "; test browser size = " + testRect.width + "," + testRect.height); } - LogInfo("DoDrawWindow " + x + "," + y + "," + w + "," + h); + TestBuffer("DoDrawWindow " + x + "," + y + "," + w + "," + h); ctx.drawWindow(gContainingWindow, x, y, w, h, "rgb(255,255,255)", gDrawWindowFlags); } function InitCurrentCanvasWithSnapshot() { - LogInfo("Initializing canvas snapshot"); + TestBuffer("Initializing canvas snapshot"); if (gURLs[0].type == TYPE_LOAD || gURLs[0].type == TYPE_SCRIPT) { // We don't want to snapshot this kind of test @@ -1511,7 +1523,7 @@ function InitCurrentCanvasWithSnapshot() function UpdateCurrentCanvasForInvalidation(rects) { - LogInfo("Updating canvas for invalidation"); + TestBuffer("Updating canvas for invalidation"); if (!gCurrentCanvas) { return; @@ -1541,7 +1553,7 @@ function UpdateCurrentCanvasForInvalidation(rects) function UpdateWholeCurrentCanvasForInvalidation() { - LogInfo("Updating entire canvas for invalidation"); + TestBuffer("Updating entire canvas for invalidation"); if (!gCurrentCanvas) { return; @@ -1553,7 +1565,7 @@ function UpdateWholeCurrentCanvasForInvalidation() function RecordResult(testRunTime, errorMsg, scriptResults) { - LogInfo("RecordResult fired"); + TestBuffer("RecordResult fired"); // Keep track of which test was slowest, and how long it took. if (testRunTime > gSlowestTestTime) { @@ -1563,26 +1575,26 @@ function RecordResult(testRunTime, errorMsg, scriptResults) // Not 'const ...' because of 'EXPECTED_*' value dependency. var outputs = {}; - const randomMsg = "(EXPECTED RANDOM)"; outputs[EXPECTED_PASS] = { - true: {s: "TEST-PASS" , n: "Pass"}, - false: {s: "TEST-UNEXPECTED-FAIL" , n: "UnexpectedFail"} + true: {s: ["PASS", "PASS"], n: "Pass"}, + false: {s: ["FAIL", "PASS"], n: "UnexpectedFail"} }; outputs[EXPECTED_FAIL] = { - true: {s: "TEST-UNEXPECTED-PASS" , n: "UnexpectedPass"}, - false: {s: "TEST-KNOWN-FAIL" , n: "KnownFail"} + true: {s: ["PASS", "FAIL"], n: "UnexpectedPass"}, + false: {s: ["FAIL", "FAIL"], n: "KnownFail"} }; outputs[EXPECTED_RANDOM] = { - true: {s: "TEST-PASS" + randomMsg , n: "Random"}, - false: {s: "TEST-KNOWN-FAIL" + randomMsg, n: "Random"} + true: {s: ["PASS", "PASS"], n: "Random"}, + false: {s: ["FAIL", "FAIL"], n: "Random"} }; outputs[EXPECTED_FUZZY] = outputs[EXPECTED_PASS]; var output; + var extra; if (gURLs[0].type == TYPE_LOAD) { ++gTestResults.LoadOnly; - gDumpLog("REFTEST TEST-PASS | " + gURLs[0].prettyPath + " | (LOAD ONLY)\n"); + logger.testEnd(gURLs[0].identifier, "PASS", "PASS", "(LOAD ONLY)"); gCurrentCanvas = null; FinishTestItem(); return; @@ -1600,17 +1612,14 @@ function RecordResult(testRunTime, errorMsg, scriptResults) if (!gURLs[0].allowSilentFail) errorMsg = "No test results reported. (SCRIPT)\n"; else - gDumpLog("REFTEST INFO | An expected silent failure occurred \n"); + logger.info("An expected silent failure occurred"); } if (errorMsg) { output = outputs[expected][false]; + extra = { status_msg: output.n }; ++gTestResults[output.n]; - var result = "REFTEST " + output.s + " | " + - gURLs[0].prettyPath + " | " + // the URL being tested - errorMsg; - - gDumpLog(result); + logger.testEnd(gURLs[0].identifier, output.s[0], output.s[1], errorMsg, null, extra); FinishTestItem(); return; } @@ -1630,16 +1639,15 @@ function RecordResult(testRunTime, errorMsg, scriptResults) var index = 0; scriptResults.forEach(function(result) { var output = outputPair[result.passed]; + var extra = { status_msg: output.n }; ++gTestResults[output.n]; - result = "REFTEST " + output.s + " | " + - gURLs[0].prettyPath + " | " + // the URL being tested - result.description + " item " + (++index) + "\n"; - gDumpLog(result); + logger.testEnd(gURLs[0].identifier, output.s[0], output.s[1], + result.description + " item " + (++index), null, extra); }); if (anyFailed && expected == EXPECTED_PASS) { - FlushTestLog(); + FlushTestBuffer(); } FinishTestItem(); @@ -1651,7 +1659,7 @@ function RecordResult(testRunTime, errorMsg, scriptResults) gCurrentCanvas = gURICanvases[gCurrentURL]; } if (gCurrentCanvas == null) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | program error managing snapshots\n"); + logger.error(gCurrentURL, "program error managing snapshots"); ++gTestResults.Exception; } if (gState == 1) { @@ -1694,7 +1702,7 @@ function RecordResult(testRunTime, errorMsg, scriptResults) throw "Inconsistent result from compareCanvases."; } equal = expected == EXPECTED_FUZZY; - gDumpLog("REFTEST fuzzy match\n"); + logger.info("REFTEST fuzzy match"); } var failedExtraCheck = gFailedNoPaint || gFailedOpaqueLayer || gFailedAssignedLayer; @@ -1703,6 +1711,7 @@ function RecordResult(testRunTime, errorMsg, scriptResults) var test_passed = (equal == (gURLs[0].type == TYPE_REFTEST_EQUAL)) && !failedExtraCheck; output = outputs[expected][test_passed]; + extra = { status_msg: output.n }; ++gTestResults[output.n]; @@ -1721,39 +1730,21 @@ function RecordResult(testRunTime, errorMsg, scriptResults) failures.push("failed reftest-assigned-layer: " + gFailedAssignedLayerMessages.join(", ")); } var failureString = failures.join(", "); - if (expected == EXPECTED_FAIL) { - gDumpLog("REFTEST TEST-KNOWN-FAIL | " + gURLs[0].prettyPath + " | " + failureString + "\n"); - } else { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gURLs[0].prettyPath + " | " + failureString + "\n"); - } + logger.testEnd(gURLs[0].identifier, output.s[0], output.s[1], failureString, null, extra); } else { - var result = "REFTEST " + output.s + " | " + - gURLs[0].prettyPath + " | "; // the URL being tested - switch (gURLs[0].type) { - case TYPE_REFTEST_NOTEQUAL: - result += "image comparison (!=)"; - break; - case TYPE_REFTEST_EQUAL: - result += "image comparison (==)"; - break; - } - if (!test_passed && expected == EXPECTED_PASS || !test_passed && expected == EXPECTED_FUZZY || test_passed && expected == EXPECTED_FAIL) { if (!equal) { - result += ", max difference: " + maxDifference.value + ", number of differing pixels: " + differences + "\n"; - result += "REFTEST IMAGE 1 (TEST): " + gCanvas1.toDataURL() + "\n"; - result += "REFTEST IMAGE 2 (REFERENCE): " + gCanvas2.toDataURL() + "\n"; + extra.max_difference = maxDifference.value; + extra.differences = differences; + extra.image1 = gCanvas1.toDataURL(); + extra.image2 = gCanvas2.toDataURL(); } else { - result += "\n"; - result += "REFTEST IMAGE: " + gCanvas1.toDataURL() + "\n"; + extra.image1 = gCanvas1.toDataURL(); } - } else { - result += "\n"; } - - gDumpLog(result); + logger.testEnd(gURLs[0].identifier, output.s[0], output.s[1], null, null, extra); if (gURLs[0].prefSettings1.length == 0) { UpdateCanvasCache(gURLs[0].url1, gCanvas1); @@ -1764,7 +1755,7 @@ function RecordResult(testRunTime, errorMsg, scriptResults) } if ((!test_passed && expected == EXPECTED_PASS) || (test_passed && expected == EXPECTED_FAIL)) { - FlushTestLog(); + FlushTestBuffer(); } CleanUpCrashDumpFiles(); @@ -1781,11 +1772,10 @@ function LoadFailed(why) // Once bug 896840 is fixed, this can go away, but for now it will give log // output that is TBPL starable for bug 789751 and bug 720452. if (!why) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | load failed with unknown reason\n"); + logger.error("load failed with unknown reason"); } - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + - gURLs[0]["url" + gState].spec + " | load failed: " + why + "\n"); - FlushTestLog(); + logger.testEnd(gURLs[0]["url" + gState].spec, "FAIL", "PASS", "load failed: " + why); + FlushTestBuffer(); FinishTestItem(); } @@ -1822,11 +1812,9 @@ function FindUnexpectedCrashDumpFiles() if (!foundCrashDumpFile) { ++gTestResults.UnexpectedFail; foundCrashDumpFile = true; - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + - " | This test left crash dumps behind, but we weren't expecting it to!\n"); + logger.testEnd(gCurrentURL, "FAIL", "PASS", "This test left crash dumps behind, but we weren't expecting it to!"); } - gDumpLog("REFTEST INFO | Found unexpected crash dump file " + path + - ".\n"); + logger.info("Found unexpected crash dump file " + path); gUnexpectedCrashDumpFiles[path] = true; } } @@ -1843,7 +1831,7 @@ function FinishTestItem() { // Replace document with BLANK_URL_FOR_CLEARING in case there are // assertions when unloading. - gDumpLog("REFTEST INFO | Loading a blank page\n"); + logger.debug("Loading a blank page"); // After clearing, content will notify us of the assertion count // and tests will continue. SendClear(); @@ -1878,26 +1866,25 @@ function DoAssertionCheck(numAsserts) if (numAsserts < minAsserts) { ++gTestResults.AssertionUnexpectedFixed; - gDumpLog("REFTEST TEST-UNEXPECTED-PASS | " + gURLs[0].prettyPath + - " | assertion count " + numAsserts + " is less than " + - expectedAssertions + "\n"); + gDumpFn("REFTEST TEST-UNEXPECTED-PASS | " + gURLs[0].prettyPath + + " | assertion count" + numAsserts + " is less than " + + expectedAssertions + "\n"); } else if (numAsserts > maxAsserts) { ++gTestResults.AssertionUnexpected; - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gURLs[0].prettyPath + - " | assertion count " + numAsserts + " is more than " + - expectedAssertions + "\n"); + gDumpFn("REFTEST TEST-UNEXPECTED-FAIL | " + gURLs[0].prettyPath + + " | assertion count " + numAsserts + " is more than " + + expectedAssertions + "\n"); } else if (numAsserts != 0) { ++gTestResults.AssertionKnown; - gDumpLog("REFTEST TEST-KNOWN-FAIL | " + gURLs[0].prettyPath + - " | assertion count " + numAsserts + " matches " + - expectedAssertions + "\n"); + gDumpFn("REFTEST TEST-KNOWN-FAIL | " + gURLs[0].prettyPath + + "assertion count " + numAsserts + " matches " + + expectedAssertions + "\n"); } } if (gURLs[0].chaosMode) { gWindowUtils.leaveChaosMode(); } - gDumpLog("REFTEST TEST-END | " + gURLs[0].prettyPath + "\n"); // And start the next test. gURLs.shift(); @@ -1926,7 +1913,7 @@ function RestoreChangedPreferences() } else if (ps.type == PREF_INTEGER) { prefs.setIntPref(ps.name, value); } - gDumpLog("RESTORE PREFERENCE pref(" + ps.name + "," + value + ")\n"); + logger.info("RESTORE PREFERENCE pref(" + ps.name + "," + value + ")"); }); gPrefsToRestore = []; } @@ -2007,7 +1994,7 @@ function RecvContentReady() function RecvException(what) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | " + what + "\n"); + logger.error(gCurrentURL + " | " + what); ++gTestResults.Exception; } @@ -2039,13 +2026,13 @@ function RecvInitCanvasWithSnapshot() function RecvLog(type, msg) { - msg = "[CONTENT] "+ msg; + msg = "[CONTENT] " + msg; if (type == "info") { - LogInfo(msg); + TestBuffer(msg); } else if (type == "warning") { - LogWarning(msg); + logger.warning(msg); } else { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | unknown log type " + type + "\n"); + logger.error("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | unknown log type " + type + "\n"); ++gTestResults.Exception; } } diff --git a/layout/tools/reftest/reftestcommandline.py b/layout/tools/reftest/reftestcommandline.py index b258f9d486..898bc3af0e 100644 --- a/layout/tools/reftest/reftestcommandline.py +++ b/layout/tools/reftest/reftestcommandline.py @@ -1,8 +1,11 @@ import argparse import os +import sys from collections import OrderedDict from urlparse import urlparse +import mozlog + here = os.path.abspath(os.path.dirname(__file__)) @@ -150,6 +153,20 @@ class ReftestArgumentsParser(argparse.ArgumentParser): dest="shuffle", help="run reftests in random order") + self.add_argument("--run-until-failure", + action="store_true", + default=False, + dest="runUntilFailure", + help="stop running on the first failure. Useful for RR recordings.") + + self.add_argument("--repeat", + action="store", + type=int, + default=0, + dest="repeat", + help="number of times the select test(s) will be executed. Useful for " + "finding intermittent failures.") + self.add_argument("--focus-filter-mode", action="store", type=str, @@ -193,6 +210,8 @@ class ReftestArgumentsParser(argparse.ArgumentParser): nargs="*", help="Path to test file, manifest file, or directory containing tests") + mozlog.commandline.add_logging_group(self) + def get_ip(self): import moznetwork if os.name != "nt": @@ -221,8 +240,6 @@ class ReftestArgumentsParser(argparse.ArgumentParser): self.error("Failed to determine test suite; supply --suite to set this explicitly") def validate(self, options, reftest): - import sys - if not options.tests: # Can't just set this in the argument parser because mach will set a default self.error("Must supply at least one path to a manifest file, test directory, or test file to run.") @@ -469,15 +486,9 @@ class B2GArgumentParser(ReftestArgumentsParser): action="store", type=str, dest="profile", - help="for desktop testing, the path to the " + help="for mulet testing, the path to the " "gaia profile to use") - self.add_argument("--desktop", - action="store_true", - dest="desktop", - default=False, - help="Run the tests on a B2G desktop build") - self.add_argument("--mulet", action="store_true", dest="mulet", @@ -664,6 +675,12 @@ class RemoteArgumentsParser(ReftestArgumentsParser): dest="httpdPath", help="path to the httpd.js file") + self.add_argument("--no-device-info", + action="store_false", + dest="printDeviceInfo", + default=True, + help="do not display verbose diagnostics about the remote device") + def validate_remote(self, options, automation): # Ensure our defaults are set properly for everything we can infer if not options.remoteTestRoot: @@ -735,6 +752,6 @@ class RemoteArgumentsParser(ReftestArgumentsParser): 'screen')['screen'][0].split() width = int(parts[0].split(':')[1]) height = int(parts[1].split(':')[1]) - if (width < 1050 or height < 1050): + if (width < 1366 or height < 1050): self.error("ERROR: Invalid screen resolution %sx%s, please adjust to 1366x1050 or higher" % ( width, height)) diff --git a/layout/tools/reftest/remotereftest.py b/layout/tools/reftest/remotereftest.py index 7ca02b0ad4..840282df37 100644 --- a/layout/tools/reftest/remotereftest.py +++ b/layout/tools/reftest/remotereftest.py @@ -8,19 +8,21 @@ import time import tempfile import traceback -# We need to know our current directory so that we can serve our test files from it. -SCRIPT_DIRECTORY = os.path.abspath(os.path.realpath(os.path.dirname(__file__))) - -from runreftest import RefTest, ReftestResolver -from automation import Automation import devicemanager import droid import mozinfo import moznetwork +from automation import Automation from remoteautomation import RemoteAutomation, fennecLogcatFilters +from output import OutputHandler +from runreftest import RefTest, ReftestResolver import reftestcommandline +# We need to know our current directory so that we can serve our test files from it. +SCRIPT_DIRECTORY = os.path.abspath(os.path.realpath(os.path.dirname(__file__))) + + class RemoteReftestResolver(ReftestResolver): def absManifestPath(self, path): script_abs_path = os.path.join(SCRIPT_DIRECTORY, path) @@ -146,6 +148,13 @@ class RemoteReftest(RefTest): self.automation.deleteANRs() self.automation.deleteTombstones() + self._populate_logger(options) + outputHandler = OutputHandler(self.log, options.utilityPath, options.symbolsPath) + # RemoteAutomation.py's 'messageLogger' is also used by mochitest. Mimic a mochitest + # MessageLogger object to re-use this code path. + outputHandler.write = outputHandler.__call__ + self.automation._processArgs['messageLogger'] = outputHandler + def findPath(self, paths, filename = None): for path in paths: p = path @@ -336,11 +345,7 @@ class RemoteReftest(RefTest): except: print "Warning: cleaning up pidfile '%s' was unsuccessful from the test harness" % self.pidFile -def main(): - automation = RemoteAutomation(None) - parser = reftestcommandline.RemoteArgumentsParser() - options = parser.parse_args() - +def runTests(options, parser): if (options.dm_trans == 'sut' and options.deviceIP == None): print "Error: If --dm_trans = sut, you must provide a device IP to connect to via the --deviceIP option" return 1 @@ -359,6 +364,7 @@ def main(): print "Automation Error: exception while initializing devicemanager. Most likely the device is not in a testable state." return 1 + automation = RemoteAutomation(None) automation.setDeviceManager(dm) if (options.remoteProductName != None): @@ -396,7 +402,8 @@ def main(): if (dm.processExist(procName)): dm.killProcess(procName) - reftest.printDeviceInfo() + if options.printDeviceInfo: + reftest.printDeviceInfo() #an example manifest name to use on the cli # manifest = "http://" + options.remoteWebServer + "/reftests/layout/reftests/reftest-sanity/reftest.list" @@ -411,10 +418,25 @@ def main(): reftest.stopWebServer(options) - reftest.printDeviceInfo(printLogcat=True) + if options.printDeviceInfo: + reftest.printDeviceInfo(printLogcat=True) return retVal +def run(**kwargs): + # Mach gives us kwargs; this is a way to turn them back into an + # options object + parser = reftestcommandline.RemoteArgumentsParser() + parser.set_defaults(**kwargs) + options = parser.parse_args(kwargs["tests"]) + retVal = runTests(options, parser) + return retVal + +def main(): + parser = reftestcommandline.RemoteArgumentsParser() + options = parser.parse_args() + retVal = runTests(options, parser) + return retVal + if __name__ == "__main__": sys.exit(main()) - diff --git a/layout/tools/reftest/runreftest.py b/layout/tools/reftest/runreftest.py index a9aadbc325..e290dcd3f4 100644 --- a/layout/tools/reftest/runreftest.py +++ b/layout/tools/reftest/runreftest.py @@ -26,26 +26,23 @@ import mozcrash import mozdebug import mozinfo import mozleak +import mozlog import mozprocess import mozprofile import mozrunner from mozrunner.utils import get_stack_fixer_function, test_environment from mozscreenshot import printstatus, dump_screen +from output import OutputHandler, ReftestFormatter import reftestcommandline -# set up logging handler a la automation.py.in for compatability -import logging -log = logging.getLogger() +here = os.path.abspath(os.path.dirname(__file__)) - -def resetGlobalLog(): - while log.handlers: - log.removeHandler(log.handlers[0]) - handler = logging.StreamHandler(sys.stdout) - log.setLevel(logging.INFO) - log.addHandler(handler) -resetGlobalLog() +try: + from mozbuild.base import MozbuildObject + build_obj = MozbuildObject.from_environment(cwd=here) +except ImportError: + build_obj = None def categoriesToRegex(categoryList): @@ -202,6 +199,21 @@ class RefTest(object): self.lastTestSeen = 'reftest' self.haveDumpedScreen = False self.resolver = self.resolver_cls() + self.log = None + + def _populate_logger(self, options): + if self.log: + return + + mozlog.commandline.log_formatters["tbpl"] = (ReftestFormatter, + "Reftest specific formatter for the" + "benefit of legacy log parsers and" + "tools such as the reftest analyzer") + fmt_options = {} + if not options.log_tbpl_level and os.environ.get('MOZ_REFTEST_VERBOSE'): + options.log_tbpl_level = fmt_options['level'] = 'debug' + self.log = mozlog.commandline.setup_logging( + "reftest harness", options, {"tbpl": sys.stdout}, fmt_options) def update_mozinfo(self): """walk up directories to find mozinfo.json update the info""" @@ -249,7 +261,12 @@ class RefTest(object): prefs['reftest.ignoreWindowSize'] = True if options.shuffle: prefs['reftest.shuffle'] = True + if options.repeat: + prefs['reftest.repeat'] = options.repeat + if options.runUntilFailure: + prefs['reftest.runUntilFailure'] = True prefs['reftest.focusFilterMode'] = options.focusFilterMode + prefs['reftest.logLevel'] = options.log_tbpl_level or 'info' prefs['reftest.manifests'] = json.dumps(manifests) # Ensure that telemetry is disabled, so we don't connect to the telemetry @@ -323,7 +340,7 @@ class RefTest(object): return profile def environment(self, **kwargs): - kwargs['log'] = log + kwargs['log'] = self.log return test_environment(**kwargs) def buildBrowserEnv(self, options, profileDir): @@ -345,11 +362,11 @@ class RefTest(object): def killNamedOrphans(self, pname): """ Kill orphan processes matching the given command name """ - log.info("Checking for orphan %s processes..." % pname) + self.log.info("Checking for orphan %s processes..." % pname) def _psInfo(line): if pname in line: - log.info(line) + self.log.info(line) process = mozprocess.ProcessHandler(['ps', '-f'], processOutputLine=_psInfo) process.run() @@ -360,13 +377,13 @@ class RefTest(object): if len(parts) == 3 and parts[0].isdigit(): pid = int(parts[0]) if parts[2] == pname and parts[1] == '1': - log.info("killing %s orphan with pid %d" % (pname, pid)) + self.log.info("killing %s orphan with pid %d" % (pname, pid)) try: os.kill( pid, getattr(signal, "SIGKILL", signal.SIGTERM)) except Exception as e: - log.info("Failed to kill process %d: %s" % - (pid, str(e))) + self.log.info("Failed to kill process %d: %s" % + (pid, str(e))) process = mozprocess.ProcessHandler(['ps', '-o', 'pid,ppid,comm'], processOutputLine=_psKill) process.run() @@ -377,6 +394,8 @@ class RefTest(object): shutil.rmtree(profileDir, True) def runTests(self, tests, options, cmdlineArgs=None): + self._populate_logger(options) + # Despite our efforts to clean up servers started by this script, in practice # we still see infrequent cases where a process is orphaned and interferes # with future tests, typically because the old server is keeping the port in use. @@ -469,17 +488,16 @@ class RefTest(object): """handle process output timeout""" # TODO: bug 913975 : _processOutput should call self.processOutputLine # one more time one timeout (I think) - log.error("TEST-UNEXPECTED-FAIL | %s | application timed out after %d seconds with no output" % - (self.lastTestSeen, int(timeout))) + self.log.error("%s | application timed out after %d seconds with no output" % (self.lastTestSeen, int(timeout))) self.killAndGetStack( proc, utilityPath, debuggerInfo, dump_screen=not debuggerInfo) def dumpScreen(self, utilityPath): if self.haveDumpedScreen: - log.info("Not taking screenshot here: see the one that was previously logged") + self.log.info("Not taking screenshot here: see the one that was previously logged") return self.haveDumpedScreen = True - dump_screen(utilityPath, log) + dump_screen(utilityPath, self.log) def killAndGetStack(self, process, utilityPath, debuggerInfo, dump_screen=False): """ @@ -507,75 +525,11 @@ class RefTest(object): process.kill(sig=signal.SIGABRT) except OSError: # https://bugzilla.mozilla.org/show_bug.cgi?id=921509 - log.info("Can't trigger Breakpad, process no longer exists") + self.log.info("Can't trigger Breakpad, process no longer exists") return - log.info("Can't trigger Breakpad, just killing process") + self.log.info("Can't trigger Breakpad, just killing process") process.kill() - # output processing - - class OutputHandler(object): - - """line output handler for mozrunner""" - - def __init__(self, harness, utilityPath, symbolsPath=None, dump_screen_on_timeout=True): - """ - harness -- harness instance - dump_screen_on_timeout -- whether to dump the screen on timeout - """ - self.harness = harness - self.utilityPath = utilityPath - self.symbolsPath = symbolsPath - self.dump_screen_on_timeout = dump_screen_on_timeout - self.stack_fixer_function = self.stack_fixer() - - def processOutputLine(self, line): - """per line handler of output for mozprocess""" - for handler in self.output_handlers(): - line = handler(line) - __call__ = processOutputLine - - def output_handlers(self): - """returns ordered list of output handlers""" - return [self.fix_stack, - self.format, - self.record_last_test, - self.handle_timeout_and_dump_screen, - self.log, - ] - - def stack_fixer(self): - """ - return get_stack_fixer_function, if any, to use on the output lines - """ - return get_stack_fixer_function(self.utilityPath, self.symbolsPath) - - # output line handlers: - # these take a line and return a line - def fix_stack(self, line): - if self.stack_fixer_function: - return self.stack_fixer_function(line) - return line - - def format(self, line): - """format the line""" - return line.rstrip().decode("UTF-8", "ignore") - - def record_last_test(self, line): - """record last test on harness""" - if "TEST-START" in line and "|" in line: - self.harness.lastTestSeen = line.split("|")[1].strip() - return line - - def handle_timeout_and_dump_screen(self, line): - if self.dump_screen_on_timeout and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line: - self.harness.dumpScreen(self.utilityPath) - return line - - def log(self, line): - log.info(line) - return line - def runApp(self, profile, binary, cmdargs, env, timeout=None, debuggerInfo=None, symbolsPath=None, options=None, @@ -591,10 +545,14 @@ class RefTest(object): interactive = debuggerInfo.interactive debug_args = [debuggerInfo.path] + debuggerInfo.args - outputHandler = self.OutputHandler(harness=self, - utilityPath=options.utilityPath, - symbolsPath=symbolsPath, - dump_screen_on_timeout=not debuggerInfo) + def record_last_test(message): + """Records the last test seen by this harness for the benefit of crash logging.""" + if message['action'] == 'test_start': + self.lastTestSeen = message['test'] + + self.log.add_handler(record_last_test) + + outputHandler = OutputHandler(self.log, options.utilityPath, symbolsPath=symbolsPath) kp_kwargs = { 'kill_on_timeout': False, @@ -624,21 +582,18 @@ class RefTest(object): interactive=interactive, outputTimeout=timeout) proc = runner.process_handler + status = runner.wait() runner.process_handler = None - if timeout is None: - didTimeout = False - else: - didTimeout = proc.didTimeout if status: - log.info("TEST-UNEXPECTED-FAIL | %s | application terminated with exit code %s", - self.lastTestSeen, status) + self.log.error("TEST-UNEXPECTED-FAIL | %s | application terminated with exit code %s" % (self.lastTestSeen, status)) else: self.lastTestSeen = 'Main app process exited normally' - crashed = mozcrash.check_for_crashes(os.path.join(profile.profile, "minidumps"), - symbolsPath, test_name=self.lastTestSeen) + crashed = mozcrash.log_crashes(self.log, os.path.join(profile.profile, 'minidumps'), + symbolsPath, test=self.lastTestSeen) + runner.cleanup() if not status and crashed: status = 1 @@ -652,7 +607,7 @@ class RefTest(object): profileDir = None try: - if cmdlineArgs == None: + if cmdlineArgs is None: cmdlineArgs = [] profile = self.createReftestProfile(options, manifests) profileDir = profile.profile # name makes more sense @@ -660,7 +615,6 @@ class RefTest(object): # browser environment browserEnv = self.buildBrowserEnv(options, profileDir) - log.info("REFTEST INFO | runreftest.py | Running tests: start.\n") status = self.runApp(profile, binary=options.app, cmdargs=cmdlineArgs, @@ -673,11 +627,9 @@ class RefTest(object): debuggerInfo=debuggerInfo) mozleak.process_leak_log(self.leakLogFile, leak_thresholds=options.leakThresholds, - log=log, stack_fixer=get_stack_fixer_function(options.utilityPath, options.symbolsPath), ) - log.info("\nREFTEST INFO | runreftest.py | Running tests: end.") finally: self.cleanup(profileDir) return status @@ -697,31 +649,28 @@ class RefTest(object): dest = os.path.join(profileDir, os.path.basename(abspath)) shutil.copytree(abspath, dest) else: - log.warning( - "WARNING | runreftest.py | Failed to copy %s to profile", abspath) + self.log.warning( + "runreftest.py | Failed to copy %s to profile" % abspath) continue def run(**kwargs): + parser = reftestcommandline.DesktopArgumentsParser() + # Mach gives us kwargs; this is a way to turn them back into an # options object - parser = reftestcommandline.DesktopArgumentsParser() - reftest = RefTest() parser.set_defaults(**kwargs) - options = parser.parse_args(kwargs["tests"]) + + if 'tests' in kwargs: + options = parser.parse_args(kwargs["tests"]) + else: + options = parser.parse_args() + + reftest = RefTest() parser.validate(options, reftest) + return reftest.runTests(options.tests, options) -def main(): - parser = reftestcommandline.DesktopArgumentsParser() - reftest = RefTest() - - options = parser.parse_args() - parser.validate(options, reftest) - - sys.exit(reftest.runTests(options.tests, options)) - - if __name__ == "__main__": - main() + sys.exit(run()) diff --git a/layout/tools/reftest/runreftestb2g.py b/layout/tools/reftest/runreftestb2g.py index 6ec0069a82..41f3d72874 100644 --- a/layout/tools/reftest/runreftestb2g.py +++ b/layout/tools/reftest/runreftestb2g.py @@ -15,7 +15,8 @@ if here not in sys.path: from automation import Automation from b2gautomation import B2GRemoteAutomation -from b2g_desktop import run_desktop_reftests +from runreftestmulet import run_test_harness as run_mulet_reftests +from output import OutputHandler from remotereftest import RemoteReftestResolver, ReftestServer from runreftest import RefTest import reftestcommandline @@ -311,6 +312,8 @@ class B2GRemoteReftest(RefTest): timeout=None, debuggerInfo=None, symbolsPath=None, options=None, valgrindPath=None, valgrindArgs=None, valgrindSuppFiles=None): + + outputHandler = OutputHandler(self.log, options.utilityPath, options.symbolsPath) status = self.automation.runApp(None, env, binary, profile.profile, @@ -319,7 +322,8 @@ class B2GRemoteReftest(RefTest): xrePath=options.xrePath, debuggerInfo=debuggerInfo, symbolsPath=symbolsPath, - timeout=timeout) + timeout=timeout, + outputHandler=outputHandler) return status @@ -380,7 +384,6 @@ def run_remote_reftests(parser, options): auto.setProduct("b2g") auto.test_script = os.path.join(here, 'b2g_start_script.js') auto.test_script_args = [options.remoteWebServer, options.httpPort] - auto.logFinish = "REFTEST TEST-START | Shutdown" reftest = B2GRemoteReftest(auto, dm, options, here) parser.validate(options, reftest) @@ -418,23 +421,24 @@ def run_remote_reftests(parser, options): reftest.stopWebServer(options) return retVal -def run_remote(**kwargs): - # Tests need to be served from a subdirectory of the server. Symlink - # topsrcdir here to get around this. + +def run(**kwargs): + # Mach gives us kwargs; this is a way to turn them back into an + # options object parser = reftestcommandline.B2GArgumentParser() parser.set_defaults(**kwargs) options = parser.parse_args(kwargs["tests"]) return run_remote_reftests(parser, options) -def main(): - parser = reftestcommandline.B2GArgumentParser() - options = parser.parse_args() - if options.desktop or options.mulet: - return run_desktop_reftests(parser, options) +def main(args=sys.argv[1:]): + parser = reftestcommandline.B2GArgumentParser() + options = parser.parse_args(args) + + if options.mulet: + return run_mulet_reftests(parser, options) return run_remote_reftests(parser, options) if __name__ == "__main__": sys.exit(main()) - diff --git a/layout/tools/reftest/b2g_desktop.py b/layout/tools/reftest/runreftestmulet.py similarity index 83% rename from layout/tools/reftest/b2g_desktop.py rename to layout/tools/reftest/runreftestmulet.py index 20098c5536..d611b62902 100644 --- a/layout/tools/reftest/b2g_desktop.py +++ b/layout/tools/reftest/runreftestmulet.py @@ -9,8 +9,6 @@ import sys here = os.path.abspath(os.path.dirname(__file__)) -from runreftest import RefTest - from marionette_driver import expected from marionette_driver.by import By from marionette_driver.marionette import Marionette @@ -21,10 +19,13 @@ from mozrunner import FirefoxRunner import mozinfo import mozlog -log = mozlog.unstructured.getLogger('REFTEST') +from runreftest import RefTest +from output import OutputHandler +import reftestcommandline -class B2GDesktopReftest(RefTest): - build_type = "desktop" + +class MuletReftest(RefTest): + build_type = "mulet" marionette = None def __init__(self, marionette_args): @@ -57,7 +58,11 @@ class B2GDesktopReftest(RefTest): self.profile = self.create_profile(options, manifests, profile_to_clone=options.profile) env = self.buildBrowserEnv(options, self.profile.profile) - kp_kwargs = { 'processOutputLine': [self._on_output], + + self._populate_logger(options) + outputHandler = OutputHandler(self.log, options.utilityPath, symbolsPath=options.symbolsPath) + + kp_kwargs = { 'processOutputLine': [outputHandler], 'onTimeout': [self._on_timeout], 'kill_on_timeout': False } @@ -69,7 +74,7 @@ class B2GDesktopReftest(RefTest): options.timeout = 300 self.timeout = options.timeout + 30.0 - log.info("%s | Running tests: start.", os.path.basename(__file__)) + self.log.info("%s | Running tests: start." % os.path.basename(__file__)) cmd, args = self.build_command_line(options.app, ignore_window_size=options.ignoreWindowSize, browser_arg=options.browser_arg) @@ -84,9 +89,9 @@ class B2GDesktopReftest(RefTest): status = 0 try: self.runner.start(outputTimeout=self.timeout) - log.info("%s | Application pid: %d", + self.log.info("%s | Application pid: %d" % ( os.path.basename(__file__), - self.runner.process_handler.pid) + self.runner.process_handler.pid)) # kick starts the reftest harness self.run_marionette_script() @@ -96,13 +101,13 @@ class B2GDesktopReftest(RefTest): self.runner.cleanup() if status > 0: - log.testFail("%s | application terminated with exit code %s", - self.last_test, status) + self.log.testFail("%s | application terminated with exit code %s" % ( + self.last_test, status)) elif status < 0: - log.info("%s | application killed with signal %s", - self.last_test, -status) + self.log.info("%s | application killed with signal %s" % ( + self.last_test, -status)) - log.info("%s | Running tests: end.", os.path.basename(__file__)) + self.log.info("%s | Running tests: end." % os.path.basename(__file__)) return status def create_profile(self, options, manifests, profile_to_clone=None): @@ -157,22 +162,13 @@ class B2GDesktopReftest(RefTest): args += ['-chrome', 'chrome://b2g/content/shell.html'] return cmd, args - def _on_output(self, line): - print(line) - # TODO use structured logging - if "TEST-START" in line and "|" in line: - self.last_test = line.split("|")[1].strip() - def _on_timeout(self): msg = "%s | application timed out after %s seconds with no output" - log.testFail(msg % (self.last_test, self.timeout)) + self.log.testFail(msg % (self.last_test, self.timeout)) # kill process to get a stack self.runner.stop(sig=signal.SIGABRT) -class MuletReftest(B2GDesktopReftest): - build_type = "mulet" - def _unlockScreen(self): self.marionette.set_context(self.marionette.CONTEXT_CONTENT) self.marionette.import_script(os.path.abspath( @@ -181,22 +177,19 @@ class MuletReftest(B2GDesktopReftest): self.marionette.execute_async_script('GaiaLockScreen.unlock()') def _wait_for_homescreen(self, timeout): - log.info("Waiting for home screen to load") + self.log.info("Waiting for home screen to load") Wait(self.marionette, timeout).until(expected.element_present( By.CSS_SELECTOR, '#homescreen[loading-state=false]')) -def run_desktop_reftests(parser, options): + +def run_test_harness(parser, options): marionette_args = {} if options.marionette: host, port = options.marionette.split(':') marionette_args['host'] = host marionette_args['port'] = int(port) - if options.mulet: - reftest = MuletReftest(marionette_args) - else: - reftest = B2GDesktopReftest(marionette_args) - + reftest = MuletReftest(marionette_args) parser.validate(options, reftest) # add a -bin suffix if b2g-bin exists, but just b2g was specified @@ -207,7 +200,16 @@ def run_desktop_reftests(parser, options): if options.xrePath is None: options.xrePath = os.path.dirname(options.app) - if options.desktop and not options.profile: - raise Exception("must specify --profile when specifying --desktop") + if options.mulet and not options.profile: + raise Exception("must specify --profile when specifying --mulet") sys.exit(reftest.run_tests(options.tests, options)) + + +def run(**kwargs): + # Mach gives us kwargs; this is a way to turn them back into an + # options object + parser = reftestcommandline.B2GArgumentParser() + parser.set_defaults(**kwargs) + options = parser.parse_args(kwargs['tests']) + return run_test_harness(parser, options) diff --git a/netwerk/base/SimpleBuffer.cpp b/netwerk/base/SimpleBuffer.cpp new file mode 100644 index 0000000000..d0e311f77c --- /dev/null +++ b/netwerk/base/SimpleBuffer.cpp @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "SimpleBuffer.h" +#include + +namespace mozilla { +namespace net { + +SimpleBuffer::SimpleBuffer() + : mStatus(NS_OK) + , mAvailable(0) +{ + mOwningThread = PR_GetCurrentThread(); +} + +nsresult SimpleBuffer::Write(char *src, size_t len) +{ + MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread); + if (NS_FAILED(mStatus)) { + return mStatus; + } + + while (len > 0) { + SimpleBufferPage *p = mBufferList.getLast(); + if (p && (p->mWriteOffset == SimpleBufferPage::kSimpleBufferPageSize)) { + // no room.. make a new page + p = nullptr; + } + if (!p) { + p = new (fallible) SimpleBufferPage(); + if (!p) { + mStatus = NS_ERROR_OUT_OF_MEMORY; + return mStatus; + } + mBufferList.insertBack(p); + } + size_t roomOnPage = SimpleBufferPage::kSimpleBufferPageSize - p->mWriteOffset; + size_t toWrite = std::min(roomOnPage, len); + memcpy(p->mBuffer + p->mWriteOffset, src, toWrite); + src += toWrite; + len -= toWrite; + p->mWriteOffset += toWrite; + mAvailable += toWrite; + } + return NS_OK; +} + +size_t SimpleBuffer::Read(char *dest, size_t maxLen) +{ + MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread); + if (NS_FAILED(mStatus)) { + return 0; + } + + size_t rv = 0; + for (SimpleBufferPage *p = mBufferList.getFirst(); + p && (rv < maxLen); p = mBufferList.getFirst()) { + size_t avail = p->mWriteOffset - p->mReadOffset; + size_t toRead = std::min(avail, (maxLen - rv)); + memcpy(dest + rv, p->mBuffer + p->mReadOffset, toRead); + rv += toRead; + p->mReadOffset += toRead; + if (p->mReadOffset == p->mWriteOffset) { + p->remove(); + delete p; + } + } + + MOZ_ASSERT(mAvailable >= rv); + mAvailable -= rv; + return rv; +} + +size_t SimpleBuffer::Available() +{ + MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread); + return NS_SUCCEEDED(mStatus) ? mAvailable : 0; +} + +void SimpleBuffer::Clear() +{ + MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread); + SimpleBufferPage *p; + while ((p = mBufferList.popFirst())) { + delete p; + } + mAvailable = 0; +} + +} // namespace net +} // namespace mozilla diff --git a/netwerk/base/SimpleBuffer.h b/netwerk/base/SimpleBuffer.h new file mode 100644 index 0000000000..7652390013 --- /dev/null +++ b/netwerk/base/SimpleBuffer.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef SimpleBuffer_h__ +#define SimpleBuffer_h__ + +/* + This class is similar to a nsPipe except it does not have any locking, stores + an unbounded amount of data, can only be used on one thread, and has much + simpler result code semantics to deal with. +*/ + +#include "prtypes.h" +#include "mozilla/LinkedList.h" +#include "nsIThreadInternal.h" + +namespace mozilla { +namespace net { + +class SimpleBufferPage : public LinkedListElement +{ +public: + SimpleBufferPage() : mReadOffset(0), mWriteOffset(0) {} + static const size_t kSimpleBufferPageSize = 32000; + +private: + friend class SimpleBuffer; + char mBuffer[kSimpleBufferPageSize]; + size_t mReadOffset; + size_t mWriteOffset; +}; + +class SimpleBuffer +{ +public: + SimpleBuffer(); + ~SimpleBuffer() {} + + nsresult Write(char *stc, size_t len); // return OK or OUT_OF_MEMORY + size_t Read(char *dest, size_t maxLen); // return bytes read + size_t Available(); + void Clear(); + +private: + PRThread *mOwningThread; + nsresult mStatus; + AutoCleanLinkedList mBufferList; + size_t mAvailable; +}; + +} // namespace net +} // namespace mozilla + +#endif diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index 8a0b07730a..bbc4a31ea2 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -253,6 +253,7 @@ UNIFIED_SOURCES += [ 'ProxyAutoConfig.cpp', 'RedirectChannelRegistrar.cpp', 'SchedulingContextService.cpp', + 'SimpleBuffer.cpp', 'StreamingProtocolService.cpp', 'Tickler.cpp', 'TLSServerSocket.cpp', diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index da5ab38ee1..ae6ede538e 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -115,6 +115,7 @@ struct HttpChannelOpenArgs nsCString schedulingContextID; OptionalCorsPreflightArgs preflightArgs; uint32_t initialRwin; + bool blockAuthPrompt; bool suspendAfterSynthesizeResponse; bool allowStaleCacheContent; bool isFromProcessingFrameAttributes; diff --git a/netwerk/protocol/http/ASpdySession.h b/netwerk/protocol/http/ASpdySession.h index ba65f9636b..f5cf7f5c5c 100644 --- a/netwerk/protocol/http/ASpdySession.h +++ b/netwerk/protocol/http/ASpdySession.h @@ -68,7 +68,7 @@ public: // this could go either way, but because there are network instances of // it being a hard error we should consider it hard. - if (code == NS_ERROR_FAILURE) { + if (code == NS_ERROR_FAILURE || code == NS_ERROR_OUT_OF_MEMORY) { return false; } diff --git a/netwerk/protocol/http/Http2Stream.cpp b/netwerk/protocol/http/Http2Stream.cpp index ebda8ccd19..66f69d5d13 100644 --- a/netwerk/protocol/http/Http2Stream.cpp +++ b/netwerk/protocol/http/Http2Stream.cpp @@ -242,28 +242,12 @@ Http2Stream::ReadSegments(nsAHttpSegmentReader *reader, return rv; } -static bool -IsDataAvailable(nsIInputStream *stream) -{ - if (!stream) { - return false; - } - uint64_t avail; - if (NS_FAILED(stream->Available(&avail))) { - return false; - } - return (avail > 0); -} - uint64_t Http2Stream::LocalUnAcked() { // reduce unacked by the amount of undelivered data // to help assert flow control - uint64_t undelivered = 0; - if (mInputBufferIn) { - mInputBufferIn->Available(&undelivered); - } + uint64_t undelivered = mSimpleBuffer.Available(); if (undelivered > mLocalUnacked) { return 0; @@ -274,25 +258,20 @@ Http2Stream::LocalUnAcked() nsresult Http2Stream::BufferInput(uint32_t count, uint32_t *countWritten) { - static const uint32_t segmentSize = 32768; - char buf[segmentSize]; - - count = std::min(segmentSize, count); - if (!mInputBufferOut) { - NS_NewPipe(getter_AddRefs(mInputBufferIn), getter_AddRefs(mInputBufferOut), - segmentSize, UINT32_MAX); - if (!mInputBufferOut) { - return NS_ERROR_OUT_OF_MEMORY; - } + char buf[SimpleBufferPage::kSimpleBufferPageSize]; + if (SimpleBufferPage::kSimpleBufferPageSize < count) { + count = SimpleBufferPage::kSimpleBufferPageSize; } + mBypassInputBuffer = 1; nsresult rv = mSegmentWriter->OnWriteSegment(buf, count, countWritten); mBypassInputBuffer = 0; + if (NS_SUCCEEDED(rv)) { - uint32_t buffered; - rv = mInputBufferOut->Write(buf, *countWritten, &buffered); - if (NS_SUCCEEDED(rv) && (buffered != *countWritten)) { - rv = NS_ERROR_OUT_OF_MEMORY; + rv = mSimpleBuffer.Write(buf, *countWritten); + if (NS_FAILED(rv)) { + MOZ_ASSERT(rv == NS_ERROR_OUT_OF_MEMORY); + return NS_ERROR_OUT_OF_MEMORY; } } return rv; @@ -302,7 +281,7 @@ bool Http2Stream::DeferCleanup(nsresult status) { // do not cleanup a stream that has data buffered for the transaction - return (NS_SUCCEEDED(status) && IsDataAvailable(mInputBufferIn)); + return (NS_SUCCEEDED(status) && mSimpleBuffer.Available()); } // WriteSegments() is used to read data off the socket. Generally this is @@ -1429,16 +1408,12 @@ Http2Stream::OnWriteSegment(char *buf, // so that other streams can proceed when the gecko caller is not processing // data events fast enough and flow control hasn't caught up yet. This // gets the stored data out of that pipe - if (!mBypassInputBuffer && IsDataAvailable(mInputBufferIn)) { - nsresult rv = mInputBufferIn->Read(buf, count, countWritten); + if (!mBypassInputBuffer && mSimpleBuffer.Available()) { + *countWritten = mSimpleBuffer.Read(buf, count); + MOZ_ASSERT(*countWritten); LOG3(("Http2Stream::OnWriteSegment read from flow control buffer %p %x %d\n", this, mStreamID, *countWritten)); - if (!IsDataAvailable(mInputBufferIn)) { - // drop the pipe if we don't need it anymore - mInputBufferIn = nullptr; - mInputBufferOut = nullptr; - } - return rv; + return NS_OK; } // read from the network diff --git a/netwerk/protocol/http/Http2Stream.h b/netwerk/protocol/http/Http2Stream.h index bba42bee79..255c466f9c 100644 --- a/netwerk/protocol/http/Http2Stream.h +++ b/netwerk/protocol/http/Http2Stream.h @@ -16,6 +16,7 @@ #include "mozilla/UniquePtr.h" #include "nsAHttpTransaction.h" #include "nsISupportsPriority.h" +#include "SimpleBuffer.h" class nsStandardURL; class nsIInputStream; @@ -326,10 +327,9 @@ private: // For Http2Push Http2PushedStream *mPushSource; - // A pipe used to store stream data when the transaction cannot keep up + // Used to store stream data when the transaction channel cannot keep up // and flow control has not yet kicked in. - nsCOMPtr mInputBufferIn; - nsCOMPtr mInputBufferOut; + SimpleBuffer mSimpleBuffer; /// connect tunnels public: diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 990e8f8375..291891b1ce 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -87,6 +87,7 @@ HttpBaseChannel::HttpBaseChannel() , mAllRedirectsSameOrigin(true) , mAllRedirectsPassTimingAllowCheck(true) , mResponseCouldBeSynthesized(false) + , mBlockAuthPrompt(false) , mAllowStaleCacheContent(false) , mSuspendCount(0) , mInitialRwin(0) @@ -3166,6 +3167,26 @@ HttpBaseChannel::SetCorsPreflightParameters(const nsTArray& aUnsafeHe mUnsafeHeaders = aUnsafeHeaders; } +NS_IMETHODIMP +HttpBaseChannel::GetBlockAuthPrompt(bool* aValue) +{ + if (!aValue) { + return NS_ERROR_FAILURE; + } + + *aValue = mBlockAuthPrompt; + return NS_OK; +} + +NS_IMETHODIMP +HttpBaseChannel::SetBlockAuthPrompt(bool aValue) +{ + ENSURE_CALLED_BEFORE_CONNECT(); + + mBlockAuthPrompt = aValue; + return NS_OK; +} + // static nsresult HttpBaseChannel::GetSecureUpgradedURI(nsIURI* aURI, nsIURI** aUpgradedURI) diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index 5aefca7acb..860416d568 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -127,6 +127,8 @@ public: NS_IMETHOD SetContentLength(int64_t aContentLength) override; NS_IMETHOD Open(nsIInputStream **aResult) override; NS_IMETHOD Open2(nsIInputStream **aResult) override; + NS_IMETHOD GetBlockAuthPrompt(bool* aValue) override; + NS_IMETHOD SetBlockAuthPrompt(bool aValue) override; // nsIEncodedChannel NS_IMETHOD GetApplyConversion(bool *value) override; @@ -429,13 +431,15 @@ protected: // pass the Resource Timing timing-allow-check uint32_t mAllRedirectsPassTimingAllowCheck : 1; + // True if this channel was intercepted and could receive a synthesized response. + uint32_t mResponseCouldBeSynthesized : 1; + + uint32_t mBlockAuthPrompt : 1; + // If true, we behave as if the LOAD_FROM_CACHE flag has been set. // Used to enforce that flag's behavior but not expose it externally. uint32_t mAllowStaleCacheContent : 1; - // True if this channel was intercepted and could receive a synthesized response. - uint32_t mResponseCouldBeSynthesized : 1; - // Current suspension depth for this channel object uint32_t mSuspendCount; diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index b08fc1e240..8934e561b3 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -1964,6 +1964,8 @@ HttpChannelChild::ContinueAsyncOpen() } openArgs.cacheKey() = cacheKey; + openArgs.blockAuthPrompt() = mBlockAuthPrompt; + nsresult rv = mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &openArgs.loadInfo()); NS_ENSURE_SUCCESS(rv, rv); diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 50efaa2071..83c5853888 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -132,7 +132,7 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs) a.loadInfo(), a.synthesizedResponseHead(), a.synthesizedSecurityInfoSerialization(), a.cacheKey(), a.schedulingContextID(), a.preflightArgs(), - a.initialRwin(), + a.initialRwin(), a.blockAuthPrompt(), a.suspendAfterSynthesizeResponse(), a.allowStaleCacheContent()); } @@ -267,6 +267,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI, const nsCString& aSchedulingContextID, const OptionalCorsPreflightArgs& aCorsPreflightArgs, const uint32_t& aInitialRwin, + const bool& aBlockAuthPrompt, const bool& aSuspendAfterSynthesizeResponse, const bool& aAllowStaleCacheContent) { @@ -432,6 +433,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI, mChannel->SetAllowSpdy(allowSpdy); mChannel->SetAllowAltSvc(allowAltSvc); mChannel->SetInitialRwin(aInitialRwin); + mChannel->SetBlockAuthPrompt(aBlockAuthPrompt); nsCOMPtr appCacheChan = do_QueryObject(mChannel); diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h index a858181c51..2518befd51 100644 --- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -137,6 +137,7 @@ protected: const nsCString& aSchedulingContextID, const OptionalCorsPreflightArgs& aCorsPreflightArgs, const uint32_t& aInitialRwin, + const bool& aBlockAuthPrompt, const bool& aSuspendAfterSynthesizeResponse, const bool& aAllowStaleCacheContent); diff --git a/netwerk/protocol/http/NullHttpTransaction.cpp b/netwerk/protocol/http/NullHttpTransaction.cpp index 97c72febcb..965ffcc2c5 100644 --- a/netwerk/protocol/http/NullHttpTransaction.cpp +++ b/netwerk/protocol/http/NullHttpTransaction.cpp @@ -96,8 +96,8 @@ NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo *ci, uint32_t caps) : mStatus(NS_OK) , mCaps(caps | NS_HTTP_ALLOW_KEEPALIVE) - , mCapsToClear(0) , mRequestHead(nullptr) + , mCapsToClear(0) , mIsDone(false) , mClaimed(false) , mCallbacks(callbacks) diff --git a/netwerk/protocol/http/NullHttpTransaction.h b/netwerk/protocol/http/NullHttpTransaction.h index feba6c977d..04f80a9b3f 100644 --- a/netwerk/protocol/http/NullHttpTransaction.h +++ b/netwerk/protocol/http/NullHttpTransaction.h @@ -56,6 +56,7 @@ private: nsresult mStatus; protected: uint32_t mCaps; + nsHttpRequestHead *mRequestHead; private: // mCapsToClear holds flags that should be cleared in mCaps, e.g. unset // NS_HTTP_REFRESH_DNS when DNS refresh request has completed to avoid @@ -65,7 +66,6 @@ private: // bitfields should be allowed: 'lost races' will thus err on the // conservative side, e.g. by going ahead with a 2nd DNS refresh. Atomic mCapsToClear; - nsHttpRequestHead *mRequestHead; bool mIsDone; bool mClaimed; diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp index a23292f199..7bb4154060 100644 --- a/netwerk/protocol/http/TunnelUtils.cpp +++ b/netwerk/protocol/http/TunnelUtils.cpp @@ -1023,9 +1023,6 @@ SpdyConnectTransaction::SpdyConnectTransaction(nsHttpConnectionInfo *ci, SpdyConnectTransaction::~SpdyConnectTransaction() { LOG(("SpdyConnectTransaction dtor %p\n", this)); - if (mRequestHead) { - delete mRequestHead; - } if (mDrivingTransaction) { // requeue it I guess. This should be gone. diff --git a/netwerk/protocol/http/TunnelUtils.h b/netwerk/protocol/http/TunnelUtils.h index 2e064d0b1d..20cfaf7ee9 100644 --- a/netwerk/protocol/http/TunnelUtils.h +++ b/netwerk/protocol/http/TunnelUtils.h @@ -215,7 +215,6 @@ private: nsCString mConnectString; uint32_t mConnectStringOffset; - nsHttpRequestHead *mRequestHead; nsAHttpConnection *mSession; nsAHttpSegmentReader *mSegmentReader; diff --git a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp index 4573e0b3f0..f2f091bbe6 100644 --- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp +++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp @@ -12,6 +12,7 @@ #include "nsNetUtil.h" #include "nsHttpHandler.h" #include "nsIHttpAuthenticator.h" +#include "nsIHttpChannelInternal.h" #include "nsIAuthPrompt2.h" #include "nsIAuthPromptProvider.h" #include "nsIInterfaceRequestor.h" @@ -810,6 +811,18 @@ nsHttpChannelAuthProvider::GetCredentialsForChallenge(const char *challenge, bool nsHttpChannelAuthProvider::BlockPrompt() { + // Verify that it's ok to prompt for credentials here, per spec + // http://xhr.spec.whatwg.org/#the-send%28%29-method + + nsCOMPtr chanInternal = do_QueryInterface(mAuthChannel); + MOZ_ASSERT(chanInternal); + + bool skipAuthentication = false; + nsresult rv = chanInternal->GetBlockAuthPrompt(&skipAuthentication); + if (NS_SUCCEEDED(rv) && skipAuthentication) { + return true; + } + nsCOMPtr chan = do_QueryInterface(mAuthChannel); nsCOMPtr loadInfo; chan->GetLoadInfo(getter_AddRefs(loadInfo)); diff --git a/netwerk/protocol/http/nsIHttpChannelInternal.idl b/netwerk/protocol/http/nsIHttpChannelInternal.idl index b7d4132543..1e176d997b 100644 --- a/netwerk/protocol/http/nsIHttpChannelInternal.idl +++ b/netwerk/protocol/http/nsIHttpChannelInternal.idl @@ -39,7 +39,7 @@ interface nsIHttpUpgradeListener : nsISupports * using any feature exposed by this interface, be aware that this interface * will change and you will be broken. You have been warned. */ -[scriptable, uuid(f292a080-f2f6-41d6-8aa4-71337e477360)] +[scriptable, uuid(01b8296a-e206-4e5f-acab-82bd8b6a900c)] interface nsIHttpChannelInternal : nsISupports { /** @@ -264,4 +264,12 @@ interface nsIHttpChannelInternal : nsISupports */ [noscript, notxpcom, nostdcall] void setCorsPreflightParameters(in StringArrayRef unsafeHeaders); + + /** + * When set to true, the channel will not pop any authentication prompts up + * to the user. When provided or cached credentials lead to an + * authentication failure, that failure will be propagated to the channel + * listener. Must be called before opening the channel, otherwise throws. + */ + attribute boolean blockAuthPrompt; }; diff --git a/testing/mach_commands.py b/testing/mach_commands.py index b62c7579d9..eb16005762 100644 --- a/testing/mach_commands.py +++ b/testing/mach_commands.py @@ -98,7 +98,7 @@ TEST_SUITES = { 'reftest': { 'aliases': ('RR', 'rr', 'Rr'), 'mach_command': 'reftest', - 'kwargs': {'test_file': None}, + 'kwargs': {'tests': None}, }, 'reftest-ipc': { 'aliases': ('Ripc',), @@ -141,7 +141,10 @@ TEST_FLAVORS = { 'mach_command': 'mochitest', 'kwargs': {'flavor': 'mochitest', 'test_paths': []}, }, - 'reftest': { }, + 'reftest': { + 'mach_command': 'reftest', + 'kwargs': {'tests': []} + }, 'steeplechase': { }, 'web-platform-tests': { 'mach_command': 'web-platform-tests', diff --git a/testing/modules/StructuredLog.jsm b/testing/modules/StructuredLog.jsm index 830f59f78a..bfa51a2b57 100644 --- a/testing/modules/StructuredLog.jsm +++ b/testing/modules/StructuredLog.jsm @@ -87,17 +87,35 @@ StructuredLogger.prototype = { this._logData("test_end", data); }, - suiteStart: function (tests, runinfo=null) { + suiteStart: function (tests, runinfo=null, versioninfo=null, deviceinfo=null, extra=null) { var data = {tests: tests}; if (runinfo !== null) { data.runinfo = runinfo; } + if (versioninfo !== null) { + data.versioninfo = versioninfo; + } + + if (deviceinfo !== null) { + data.deviceinfo = deviceinfo; + } + + if (extra !== null) { + data.extra = extra; + } + this._logData("suite_start", data); }, - suiteEnd: function () { - this._logData("suite_end"); + suiteEnd: function (extra=null) { + var data = {}; + + if (extra !== null) { + data.extra = extra; + } + + this._logData("suite_end", data); }, @@ -142,6 +160,14 @@ StructuredLogger.prototype = { this.log("CRITICAL", message, extra); }, + processOutput: function(thread, message) { + this._logData('process_output', { + message: message, + thread: thread, + }); + }, + + _logData: function (action, data={}) { var allData = { action: action, diff --git a/testing/mozbase/mozleak/mozleak/leaklog.py b/testing/mozbase/mozleak/mozleak/leaklog.py index 9dee506188..73a25d6476 100644 --- a/testing/mozbase/mozleak/mozleak/leaklog.py +++ b/testing/mozbase/mozleak/mozleak/leaklog.py @@ -10,9 +10,114 @@ import sys import mozinfo import mozrunner.utils -def _raw_log(): - import logging - return logging.getLogger(__name__) + +def _get_default_logger(): + from mozlog import get_default_logger + log = get_default_logger(component='mozleak') + + if not log: + import logging + log = logging.getLogger(__name__) + return log + + +# Do not add anything to this list, unless one of the existing leaks below +# has started to leak additional objects. This function returns a dict +# mapping the names of objects as reported to the XPCOM leak checker to an +# upper bound on the number of leaked objects of that kind that are allowed +# to appear in a content process leak report. +def expectedTabProcessLeakCounts(): + leaks = {} + + def appendExpectedLeakCounts(leaks2): + for obj, count in leaks2.iteritems(): + leaks[obj] = leaks.get(obj, 0) + count + + # Bug 1117203 - ImageBridgeChild is not shut down in tab processes. + appendExpectedLeakCounts({ + 'AsyncTransactionTrackersHolder': 1, + 'CondVar': 2, + 'IPC::Channel': 1, + 'MessagePump': 1, + 'Mutex': 2, + 'PImageBridgeChild': 1, + 'RefCountedMonitor': 1, + 'RefCountedTask': 2, + 'StoreRef': 1, + 'WaitableEventKernel': 1, + 'WeakReference': 1, + 'base::Thread': 1, + 'ipc::MessageChannel': 1, + 'nsTArray_base': 7, + 'nsThread': 1, + }) + + # Bug 1215265 - CompositorChild is not shut down. + appendExpectedLeakCounts({ + 'CompositorChild': 1, + 'CondVar': 1, + 'IPC::Channel': 1, + 'Mutex': 1, + 'PCompositorChild': 1, + 'RefCountedMonitor': 1, + 'RefCountedTask': 2, + 'StoreRef': 1, + 'WeakReference': 1, + 'ipc::MessageChannel': 1, + 'nsTArray_base': 2, + }) + + # Bug 1215265 - Windows-specific graphics leaks, maybe related to + # CompositorChild and/or ImageBridgeChild not being shut down. + if mozinfo.isWin: + # Windows leaks comment to all content processes. + # 2696 bytes leaked total on Win7. + appendExpectedLeakCounts({ + 'AsyncTransactionTrackersHolder': 1, + 'CompositableChild': 1, + 'Mutex': 1, + 'PCompositableChild': 1, + 'PImageContainerChild': 1, + 'SyncObject': 1, + 'WeakReference': 2, + }) + + # Various additional graphics-related Windows leaks in Mochitests. + # M2 leaks in dom/media/tests/mochitest/ipc/ + # dt1 leaks in devtools/client/animationinspector/test/browser_animation_animated_properties_displayed.js + # dt1 leaks in devtools/client/debugger/test/mochitest/ (additional leaks are intermittent?) + # dt2 leaks in devtools/client/inspector/computed/test/ + # dt8 leaks in devtools/shared/worker/tests/browser/ (additional leaks are intermittent?) + # gl leaks in dom/canvas/test/webgl-mochitest/ + appendExpectedLeakCounts({ + 'AsyncTransactionTracker': 1, + 'AsyncTransactionTrackersHolder': 4, + 'AsyncTransactionWaiter': 1, + 'CompositableChild': 3, + 'CompositableClient': 3, + 'CondVar': 5, + 'DXGID3D9TextureData': 1, + 'FdObj': 2, + 'GfxTextureWasteTracker': 1, + 'IPC::Message': 1, + 'ITextureClientRecycleAllocator': 1, + 'LayerTransactionChild': 5, + 'Mutex': 7, + 'PCompositableChild': 3, + 'PImageContainerChild': 3, + 'PLayerTransactionChild': 5, + 'PTextureChild': 5, + 'RemoveTextureFromCompositableTracker': 1, + 'SharedMemory': 5, + 'SyncObject': 5, + 'TextureChild': 5, + 'TextureClientHolder': 1, + 'TextureData': 5, + 'WeakReference': 10, + 'nsTArray_base': 17, + }) + + return leaks def process_single_leak_file(leakLogFileName, processType, leakThreshold, @@ -31,9 +136,10 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold, r"\s*-?\d+\s+(?P-?\d+)") # The class name can contain spaces. We remove trailing whitespace later. - log = log or _raw_log() + log = log or _get_default_logger() processString = "%s process:" % processType + expectedLeaks = expectedTabProcessLeakCounts() if processType == 'tab' else {} crashedOnPurpose = False totalBytesLeaked = None logAsWarning = False @@ -85,9 +191,17 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold, logAsWarning = True continue if name != "TOTAL" and numLeaked != 0 and recordLeakedObjects: - leakedObjectNames.append(name) - leakedObjectAnalysis.append("TEST-INFO | leakcheck | %s leaked %d %s (%s bytes)" - % (processString, numLeaked, name, bytesLeaked)) + currExpectedLeak = expectedLeaks.get(name, 0) + if not expectedLeaks or numLeaked <= currExpectedLeak: + if not expectedLeaks: + leakedObjectNames.append(name) + leakedObjectAnalysis.append("TEST-INFO | leakcheck | %s leaked %d %s" + % (processString, numLeaked, name)) + else: + leakedObjectNames.append(name) + leakedObjectAnalysis.append("WARNING | leakcheck | %s leaked too many %s (expected %d, got %d)" + % (processString, name, currExpectedLeak, numLeaked)) + leakAnalysis.extend(leakedObjectAnalysis) if logAsWarning: @@ -117,8 +231,7 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold, processString) return - # totalBytesLeaked was seen and is non-zero. - if totalBytesLeaked > leakThreshold: + if totalBytesLeaked > leakThreshold or (expectedLeaks and leakedObjectNames): logAsWarning = True # Fail the run if we're over the threshold (which defaults to 0) prefix = "TEST-UNEXPECTED-FAIL" @@ -132,6 +245,8 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold, if len(leakedObjectNames) > maxSummaryObjects: leakedObjectSummary += ', ...' + # totalBytesLeaked will include any expected leaks, so it can be off + # by a few thousand bytes. if logAsWarning: log.warning("%s | leakcheck | %s %d bytes leaked (%s)" % (prefix, processString, totalBytesLeaked, leakedObjectSummary)) @@ -167,7 +282,7 @@ def process_leak_log(leak_log_file, leak_thresholds=None, in the list ignore_missing_leaks. """ - log = log or _raw_log() + log = log or _get_default_logger() leakLogFile = leak_log_file if not os.path.exists(leakLogFile): diff --git a/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py b/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py index ec5abc569c..ca450adf4c 100644 --- a/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py +++ b/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py @@ -5,6 +5,7 @@ from .base import BaseFormatter from .process import strstatus + class TbplFormatter(BaseFormatter): """Formatter that formats logs in the legacy formatting format used by TBPL This is intended to be used to preserve backward compatibility with existing tools @@ -102,12 +103,12 @@ class TbplFormatter(BaseFormatter): def test_end(self, data): test_id = self.test_id(data["test"]) - time_msg = "" + duration_msg = "" if test_id in self.test_start_times: start_time = self.test_start_times.pop(test_id) time = data["time"] - start_time - time_msg = "took %ims" % time + duration_msg = "took %ims" % time if "expected" in data: message = data.get("message", "") @@ -119,18 +120,20 @@ class TbplFormatter(BaseFormatter): message = message[:-1] failure_line = "TEST-UNEXPECTED-%s | %s | %s\n" % ( - data["status"], test_id, message) + data["status"], self.id_str(test_id), message) if data["expected"] not in ("PASS", "OK"): expected_msg = "expected %s | " % data["expected"] else: expected_msg = "" - info_line = "TEST-INFO %s%s\n" % (expected_msg, time_msg) + info_line = "TEST-INFO %s%s\n" % (expected_msg, duration_msg) return failure_line + info_line - return "TEST-%s | %s | %s\n" % ( - data["status"], test_id, time_msg) + sections = ["TEST-%s" % data['status'], self.id_str(test_id)] + if duration_msg: + sections.append(duration_msg) + return ' | '.join(sections) + '\n' def suite_end(self, data): start_time = self.suite_start_time diff --git a/testing/mozbase/mozlog/mozlog/logtypes.py b/testing/mozbase/mozlog/mozlog/logtypes.py index 4d458e2b30..dc516c9886 100644 --- a/testing/mozbase/mozlog/mozlog/logtypes.py +++ b/testing/mozbase/mozlog/mozlog/logtypes.py @@ -132,9 +132,9 @@ class TestId(DataType): def convert(self, data): if isinstance(data, unicode): return data - elif isinstance(data, str): + elif isinstance(data, bytes): return data.decode("utf-8", "replace") - elif isinstance(data, tuple): + elif isinstance(data, (tuple, list)): # This is really a bit of a hack; should really split out convertors from the # fields they operate on func = Unicode(None).convert diff --git a/testing/mozbase/mozlog/mozlog/structuredlog.py b/testing/mozbase/mozlog/mozlog/structuredlog.py index adabdc31ea..fd5279b082 100644 --- a/testing/mozbase/mozlog/mozlog/structuredlog.py +++ b/testing/mozbase/mozlog/mozlog/structuredlog.py @@ -238,7 +238,8 @@ class StructuredLogger(object): @log_action(List("tests", Unicode), Dict("run_info", default=None, optional=True), Dict("version_info", default=None, optional=True), - Dict("device_info", default=None, optional=True)) + Dict("device_info", default=None, optional=True), + Dict("extra", default=None, optional=True)) def suite_start(self, data): """Log a suite_start message @@ -252,7 +253,7 @@ class StructuredLogger(object): self._log_data("suite_start", data) - @log_action() + @log_action(Dict("extra", default=None, optional=True)) def suite_end(self, data): """Log a suite_end message""" if not self._ensure_suite_state('suite_end', data): diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index f6f3fa6c78..968439dd4e 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -53,6 +53,7 @@ #include "Layers.h" #include "ClientLayerManager.h" #include "mozilla/layers/LayerManagerComposite.h" +#include "GfxTexturesReporter.h" #include "GLTextureImage.h" #include "GLContextProvider.h" #include "GLContextCGL.h" @@ -2992,11 +2993,13 @@ RectTextureImage::EndUpdate(bool aKeepSurface) data += srcPoint.y * stride + srcPoint.x * bpp; UploadImageDataToTexture(mGLContext, data, stride, format, - updateRegion.ToUnknownRegion(), mTexture, + updateRegion.ToUnknownRegion(), mTexture, nullptr, overwriteTexture, /* aPixelBuffer = */ false, LOCAL_GL_TEXTURE0, LOCAL_GL_TEXTURE_RECTANGLE_ARB); + + if (!aKeepSurface) { mUpdateDrawTarget = nullptr; mUpdateDrawTargetData = nullptr; diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 42715c39d1..aa13a33c39 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -172,7 +172,7 @@ nsCocoaWindow::~nsCocoaWindow() if (mModal) { NS_WARNING("Widget destroyed while running modal!"); --gXULModalLevel; - NS_ASSERTION(gXULModalLevel >= 0, "Wierdness setting modality!"); + NS_ASSERTION(gXULModalLevel >= 0, "Weirdness setting modality!"); } NS_OBJC_END_TRY_ABORT_BLOCK; diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index ba29a166b1..5032c400d9 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -3191,7 +3191,6 @@ nsNativeThemeCocoa::GetWidgetPadding(nsDeviceContext* aContext, // We don't want CSS padding being used for certain widgets. // See bug 381639 for an example of why. switch (aWidgetType) { - case NS_THEME_BUTTON: // Radios and checkboxes return a fixed size in GetMinimumWidgetSize // and have a meaningful baseline, so they can't have // author-specified padding.