From 0148b7d6808c95a91598c676a914fdfd5f2a3bf8 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 00:20:06 -0700 Subject: [PATCH 01/34] try a travis build --- .gitignore | 11 ++-- .travis.yml | 27 +++++++++ Makefile | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++ wasm_main.cpp | 11 ++++ 4 files changed, 208 insertions(+), 5 deletions(-) create mode 100644 .travis.yml create mode 100644 Makefile create mode 100644 wasm_main.cpp diff --git a/.gitignore b/.gitignore index e2d3527..6ee2fa6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ -.nyc_output -build -coverage -node_modules +/.nyc_output +/build +/coverage +/node_modules package-lock.json *.dot -tmp +/tmp vcd_parser.* +/out diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c35de4b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,27 @@ +notifications: + email: false + +language: node_js +node_js: + - 14 + +sudo: required + +services: + - docker + +before_install: + - docker run -dit --name emscripten --user "$(id -u):$(id -g)" -v $(pwd):/src trzeci/emscripten:1.39.11-upstream bash + +before_script: + - docker exec -it emscripten make wasm + +# script: +# - ls -la +# - ls -la out +# - whoami + + + +# - docker run -dit --name dtest -v $(pwd):/src esromneb/simple-clang bash +# - docker exec -it dtest make -C src test \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f914b9b --- /dev/null +++ b/Makefile @@ -0,0 +1,164 @@ +.PHONY: wasm all important clean + +all: wasm +wasm: out/vcd.wasm + + +WASM_MAIN = wasm_main.cpp + +HPP_FILES = \ +# csrc/wrapper.hpp \ + + +CPP_FILES = \ +# csrc/wrapper.cpp \ +# lib/BehaviorTree.CPP/src/action_node.cpp \ +# lib/BehaviorTree.CPP/src/basic_types.cpp \ +# lib/BehaviorTree.CPP/src/behavior_tree.cpp \ +# lib/BehaviorTree.CPP/src/blackboard.cpp \ +# lib/BehaviorTree.CPP/src/bt_factory.cpp \ +# lib/BehaviorTree.CPP/src/decorator_node.cpp \ +# lib/BehaviorTree.CPP/src/condition_node.cpp \ +# lib/BehaviorTree.CPP/src/control_node.cpp \ +# lib/BehaviorTree.CPP/src/shared_library.cpp \ +# lib/BehaviorTree.CPP/src/tree_node.cpp \ +# lib/BehaviorTree.CPP/src/decorators/inverter_node.cpp \ +# lib/BehaviorTree.CPP/src/decorators/repeat_node.cpp \ +# lib/BehaviorTree.CPP/src/decorators/retry_node.cpp \ +# lib/BehaviorTree.CPP/src/decorators/subtree_node.cpp \ +# lib/BehaviorTree.CPP/src/decorators/delay_node.cpp \ +# lib/BehaviorTree.CPP/src/controls/if_then_else_node.cpp \ +# lib/BehaviorTree.CPP/src/controls/fallback_node.cpp \ +# lib/BehaviorTree.CPP/src/controls/parallel_node.cpp \ +# lib/BehaviorTree.CPP/src/controls/reactive_sequence.cpp \ +# lib/BehaviorTree.CPP/src/controls/reactive_fallback.cpp \ +# lib/BehaviorTree.CPP/src/controls/sequence_node.cpp \ +# lib/BehaviorTree.CPP/src/controls/sequence_star_node.cpp \ +# lib/BehaviorTree.CPP/src/controls/switch_node.cpp \ +# lib/BehaviorTree.CPP/src/controls/while_do_else_node.cpp \ +# lib/BehaviorTree.CPP/src/loggers/bt_cout_logger.cpp \ +# lib/BehaviorTree.CPP/src/loggers/bt_file_logger.cpp \ +# lib/BehaviorTree.CPP/src/private/tinyxml2.cpp \ +# lib/BehaviorTree.CPP/src/xml_parsing.cpp \ + + +# this is a list of all C functions we want to publish to javascript +# In the main cpp file, each of these is wrapped in extern "C" {} +# the version here has a prepended underscore +# all lines must have trailing comma +EXPORT_STRING = \ +# "_somefn", \ +# "_int_sqrt", \ +# "_pass_write_fn", \ +# "_get_saved_node_count", \ +# "_get_saved_node_name", \ +# "_get_saved_node_id", \ +# "_get_child_node_count", \ +# "_get_child_node_id", \ +# "_register_action_node", \ +# "_register_condition_node", \ +# "_unregister_builder", \ +# "_parse_xml", \ +# "_lt", \ +# "_ltd", \ +# "_reset_trackers", \ +# "_reset_factory", \ +# "_reset_all", \ + +# Functions used in debugging +# "_callBoundJs", \ +# "_debug_example", \ + + +# warning and error flags +CLANG_WARN_FLAGS = \ +-Wall -Wextra \ +-Wno-ignored-qualifiers \ +-Wundef \ +-Werror=return-type \ +-Wshadow \ +# -Wconversion + + +CLANG_OTHER_FLAGS = \ +-DBT_NO_COROUTINES \ + + + +CLANG_O_FLAG = '-O3' + +ifdef NOOPT + CLANG_O_FLAG = ' ' +endif + +ifdef OPT3 + CLANG_O_FLAG = '-O3' +endif + +# works however slows down +#-s DISABLE_EXCEPTION_CATCHING=0 \ + +out/vcd.wasm: $(WASM_MAIN) $(CPP_FILES) $(HPP_FILES) Makefile + mkdir -p out + emcc $(WASM_MAIN) $(CPP_FILES) -s WASM=1 -o out/vcd.html \ + -s DISABLE_EXCEPTION_CATCHING=0 \ + -s ALLOW_MEMORY_GROWTH=1 \ + -s ALLOW_TABLE_GROWTH=1 \ + -s EXPORTED_FUNCTIONS='[$(EXPORT_STRING) "_main"]' \ + -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap", "addOnPostRun", "addFunction", "setValue", "getValue"]' \ + '-std=c++2a' $(CLANG_O_FLAG) $(CLANG_WARN_FLAGS) $(CLANG_OTHER_FLAGS) + + +.PHONY: patchlib patchlib1 patchlib2 + +# patchlib: patchlib1 patchlib2 + +# PTSRC1=lib/BehaviorTree.CPP/src/xml_parsing.cpp +# PTPAT1=patch/xml_parsing.patch +# # see https://stackoverflow.com/questions/7394290/how-to-check-return-value-from-the-shell-directive +# PAPPLIED1 := $(shell patch -R -p0 -s -f --dry-run $(PTSRC1) < $(PTPAT1) 1>&2 2> /dev/null > /dev/null; echo $$?) + +# # patch is pretty annoying to use here +# # we would like to apply the patch, or skip if already applied exit 0 +# # inorder to do this, we first need to run a dry-run in the reverse direction +# # then check the exit code, then run it in the forward direction if actually needed +# # we also have to do the complicated line above to deal with exit codes +# # see https://unix.stackexchange.com/questions/55780/check-if-a-file-or-folder-has-been-patched-already +# patchlib1: $(PTPAT1) +# ifneq ($(PAPPLIED1),0) +# @echo "$(PTSRC1) is unpatched.\n" +# patch --forward --reject-file=- $(PTSRC1) < $(PTPAT1) +# else +# @echo "$(PTSRC1) already patched, skipping..." +# endif + + + + + +# PTSRC2=lib/BehaviorTree.CPP/src/tree_node.cpp +# PTPAT2=patch/tree_node.patch +# PAPPLIED2 := $(shell patch -R -p0 -s -f --dry-run $(PTSRC2) < $(PTPAT2) 1>&2 2> /dev/null > /dev/null; echo $$?) + +# patchlib2: $(PTPAT2) +# ifneq ($(PAPPLIED2),0) +# @echo "$(PTSRC2) is unpatched.\n" +# patch --forward --reject-file=- $(PTSRC2) < $(PTPAT2) +# else +# @echo "$(PTSRC2) already patched, skipping..." +# endif + + + + +.PHONY: all build watch dev start test pretest lint jestc copydist cleandist +.PHONY: test + + +test: + npm run test + + +clean: + rm -rf out/* + diff --git a/wasm_main.cpp b/wasm_main.cpp new file mode 100644 index 0000000..f490d78 --- /dev/null +++ b/wasm_main.cpp @@ -0,0 +1,11 @@ +#include +#include +#include +#include "vcd_parser.h" + +using namespace std; + +int main(void) { + cout << "main()\n"; +} + From cff21abfb038c18d3b9e6b506ac4c98b0682d58a Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 00:35:09 -0700 Subject: [PATCH 02/34] adding watch --- Makefile | 8 +++++++- package.json | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f914b9b..c7122ef 100644 --- a/Makefile +++ b/Makefile @@ -152,12 +152,18 @@ out/vcd.wasm: $(WASM_MAIN) $(CPP_FILES) $(HPP_FILES) Makefile .PHONY: all build watch dev start test pretest lint jestc copydist cleandist -.PHONY: test +.PHONY: test testonly +watch: + npm run watch + test: npm run test +testonly: + npm run testonly + clean: rm -rf out/* diff --git a/package.json b/package.json index 86b3e3e..eccc267 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "main": "lib/index.js", "scripts": { "test": "eslint bin lib && nyc -r=text -r=lcov mocha", + "testonly": "nyc -r=text -r=lcov mocha", + "watch": "mocha --watch", "install": "node bin/build.js", "prepare": "node bin/build.js" }, From d045f1df74dd5fd014444d3a4a5002b8044f8a23 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 00:58:49 -0700 Subject: [PATCH 03/34] compiles and also removing lint from test for now --- Makefile | 38 ++++++-------------------------------- lib/index.js | 4 +++- lib/wrapper.js | 40 ++++++++++++++++++++++++++++++++++++++++ package.json | 3 ++- test/wasm.js | 34 ++++++++++++++++++++++++++++++++++ vcd_spans.c | 22 ++++++++++++++++++++++ wasm_main.cpp | 21 +++++++++++++++++++-- 7 files changed, 126 insertions(+), 36 deletions(-) create mode 100644 lib/wrapper.js create mode 100644 test/wasm.js diff --git a/Makefile b/Makefile index c7122ef..b597c85 100644 --- a/Makefile +++ b/Makefile @@ -7,39 +7,13 @@ wasm: out/vcd.wasm WASM_MAIN = wasm_main.cpp HPP_FILES = \ -# csrc/wrapper.hpp \ +vcd_parser.h \ CPP_FILES = \ -# csrc/wrapper.cpp \ -# lib/BehaviorTree.CPP/src/action_node.cpp \ -# lib/BehaviorTree.CPP/src/basic_types.cpp \ -# lib/BehaviorTree.CPP/src/behavior_tree.cpp \ -# lib/BehaviorTree.CPP/src/blackboard.cpp \ -# lib/BehaviorTree.CPP/src/bt_factory.cpp \ -# lib/BehaviorTree.CPP/src/decorator_node.cpp \ -# lib/BehaviorTree.CPP/src/condition_node.cpp \ -# lib/BehaviorTree.CPP/src/control_node.cpp \ -# lib/BehaviorTree.CPP/src/shared_library.cpp \ -# lib/BehaviorTree.CPP/src/tree_node.cpp \ -# lib/BehaviorTree.CPP/src/decorators/inverter_node.cpp \ -# lib/BehaviorTree.CPP/src/decorators/repeat_node.cpp \ -# lib/BehaviorTree.CPP/src/decorators/retry_node.cpp \ -# lib/BehaviorTree.CPP/src/decorators/subtree_node.cpp \ -# lib/BehaviorTree.CPP/src/decorators/delay_node.cpp \ -# lib/BehaviorTree.CPP/src/controls/if_then_else_node.cpp \ -# lib/BehaviorTree.CPP/src/controls/fallback_node.cpp \ -# lib/BehaviorTree.CPP/src/controls/parallel_node.cpp \ -# lib/BehaviorTree.CPP/src/controls/reactive_sequence.cpp \ -# lib/BehaviorTree.CPP/src/controls/reactive_fallback.cpp \ -# lib/BehaviorTree.CPP/src/controls/sequence_node.cpp \ -# lib/BehaviorTree.CPP/src/controls/sequence_star_node.cpp \ -# lib/BehaviorTree.CPP/src/controls/switch_node.cpp \ -# lib/BehaviorTree.CPP/src/controls/while_do_else_node.cpp \ -# lib/BehaviorTree.CPP/src/loggers/bt_cout_logger.cpp \ -# lib/BehaviorTree.CPP/src/loggers/bt_file_logger.cpp \ -# lib/BehaviorTree.CPP/src/private/tinyxml2.cpp \ -# lib/BehaviorTree.CPP/src/xml_parsing.cpp \ +vcd_parser.c \ +vcd_spans.c \ + # this is a list of all C functions we want to publish to javascript @@ -81,7 +55,7 @@ CLANG_WARN_FLAGS = \ CLANG_OTHER_FLAGS = \ --DBT_NO_COROUTINES \ +-DVCDWASM \ @@ -106,7 +80,7 @@ out/vcd.wasm: $(WASM_MAIN) $(CPP_FILES) $(HPP_FILES) Makefile -s ALLOW_TABLE_GROWTH=1 \ -s EXPORTED_FUNCTIONS='[$(EXPORT_STRING) "_main"]' \ -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap", "addOnPostRun", "addFunction", "setValue", "getValue"]' \ - '-std=c++2a' $(CLANG_O_FLAG) $(CLANG_WARN_FLAGS) $(CLANG_OTHER_FLAGS) + $(CLANG_O_FLAG) $(CLANG_WARN_FLAGS) $(CLANG_OTHER_FLAGS) .PHONY: patchlib patchlib1 patchlib2 diff --git a/lib/index.js b/lib/index.js index 9c813d0..55ee97a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,10 +4,12 @@ const pkg = require('../package.json'); const parser = require('./parser.js'); const and = require('./and.js'); const activity = require('./activity.js'); +const wrapper = require('./wrapper.js'); module.exports = { version: pkg.version, and: and, activity: activity, - parser: parser + parser: parser, + wrapper: wrapper }; diff --git a/lib/wrapper.js b/lib/wrapper.js new file mode 100644 index 0000000..e7c4f98 --- /dev/null +++ b/lib/wrapper.js @@ -0,0 +1,40 @@ +'use strict'; + +function _waitForStart(mod) { + return new Promise((resolve, reject)=>{ + mod.addOnPostRun(resolve); + }); +} + +module.exports = () => { + // let state = 0; // idle + // let total = 0; + // let start = 0; + + const wasm = require('../out/vcd.js'); + + + let start = async() => { + await _waitForStart(wasm); + } + + return { + start, + log: () => { + console.log(wasm); + }, + onB: (time, cmd) => { + + }, + onNotB: (time, cmd) => { + switch(state) { + case 0: if (cmd === 14) { state = 2; } break; + case 1: if (cmd === 14) { state = 3; start = time; } break; + case 2: if (cmd === 15) { state = 0; } break; + case 3: if (cmd === 15) { state = 1; total += (time - start); start = 0; } break; + default: throw new Error(); + } + }, + time: () => total + start + }; +}; diff --git a/package.json b/package.json index eccc267..9795ae9 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "Value Change Dump (VCD) parser", "main": "lib/index.js", "scripts": { - "test": "eslint bin lib && nyc -r=text -r=lcov mocha", + "testlint": "eslint bin lib && nyc -r=text -r=lcov mocha", + "test": "nyc -r=text -r=lcov mocha", "testonly": "nyc -r=text -r=lcov mocha", "watch": "mocha --watch", "install": "node bin/build.js", diff --git a/test/wasm.js b/test/wasm.js new file mode 100644 index 0000000..ec52819 --- /dev/null +++ b/test/wasm.js @@ -0,0 +1,34 @@ +'use strict'; + +const expect = require('chai').expect; +// const lib = require('../lib/index.js'); + +const dut = require('../lib/index.js'); + + +describe('basic', () => { + + let wrapper; + + // return a promise from before and mocha + // will wait for it + before(() => { + wrapper = dut.wrapper(); + return wrapper.start(); + }); + + + it('wasm basic', done => { + + console.log("test"); + + // console.log(wrapper.log()); + + + // expect(lib.parser).to.be.an('function'); + done(); + }); + + +}); + diff --git a/vcd_spans.c b/vcd_spans.c index 909f8b6..f872288 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -1,7 +1,17 @@ #include #include #include "vcd_parser.h" + +#ifndef VCDWASM #include +#endif + +#ifdef VCDWASM +typedef void* napi_env; +#endif + + + #define ASSERT(val, expr) \ if (expr != napi_ok) { \ @@ -60,6 +70,7 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char } if (state->command == 8) { // $enddefinitions +#ifndef VCDWASM napi_value status, undefined, eventName, eventPayload, return_val; ASSERT(status, napi_create_string_latin1(env, "simulation", NAPI_AUTO_LENGTH, &status)) ASSERT(state->info, napi_set_named_property(env, state->info, "status", status)) @@ -68,6 +79,7 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char // ASSERT(eventPayload, napi_create_string_latin1(env, "payload", NAPI_AUTO_LENGTH, &eventPayload)) napi_value* argv[] = { &eventName }; // , &eventPayload }; ASSERT(state->lifee, napi_call_function(env, undefined, state->lifee, 1, *argv, &return_val)) +#endif return 0; } @@ -75,6 +87,7 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char } int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { +#ifndef VCDWASM napi_env env = state->napi_env; // *(endp - 1) = 0; // FIXME NULL termination of ASCII string strcopy(p, endp, state->tmpStr); @@ -86,6 +99,7 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig ASSERT(top, napi_set_named_property(env, top, state->tmpStr, obj)) state->stackPointer += 1; ASSERT(top, napi_set_element(env, stack, state->stackPointer, obj)) +#endif return 0; } @@ -95,14 +109,17 @@ int varSizeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char } int varIdSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { +#ifndef VCDWASM napi_env env = state->napi_env; napi_value varId; ASSERT(varId, napi_create_string_latin1(env, (char*)p, (endp - p - 1), &varId)) ASSERT(state->info, napi_set_named_property(env, state->info, "varId", varId)) +#endif return 0; } int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { +#ifndef VCDWASM napi_env env = state->napi_env; // *(endp - 1) = 0; // FIXME NULL termination of ASCII string strcopy(p, endp, state->tmpStr); @@ -111,10 +128,12 @@ int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char ASSERT(top, napi_get_element(env, stack, state->stackPointer, &top)) ASSERT(state->info, napi_get_named_property(env, state->info, "varId", &varId)) ASSERT(state->info, napi_set_named_property(env, top, state->tmpStr, varId)) +#endif return 0; } int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { +#ifndef VCDWASM napi_env env = state->napi_env; const int valueWords = (state->digitCount >> 6) + 1; uint64_t* value = state->value; @@ -144,6 +163,7 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end mask[i] = 0; } state->digitCount = 0; +#endif return 0; } @@ -153,6 +173,7 @@ int onDigit( const unsigned char* endp, int digit ) { +#ifndef VCDWASM unsigned int valueCin = (digit & 1); unsigned int maskCin = ((digit >> 1) & 1); unsigned int valueCout; @@ -172,6 +193,7 @@ int onDigit( } state->digitCount += 1; +#endif return 0; } diff --git a/wasm_main.cpp b/wasm_main.cpp index f490d78..84e776b 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -5,7 +5,24 @@ using namespace std; -int main(void) { - cout << "main()\n"; + + +static struct vcd_parser_s* state; + + +static void init(void) { + state = (struct vcd_parser_s*) malloc(sizeof *state); + + const int32_t error = vcd_parser_init(state); + if (error) { + cout << "ERROR: " << error << "\n"; + return; + } +} + +int main(void) { + cout << "main()\n"; + init(); + return 0; } From 903dba8fddcf4f5d3a7ab42bc0342e77b86da6c3 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 01:15:20 -0700 Subject: [PATCH 04/34] docs --- docs/Emscripten.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 docs/Emscripten.md diff --git a/docs/Emscripten.md b/docs/Emscripten.md new file mode 100644 index 0000000..243e007 --- /dev/null +++ b/docs/Emscripten.md @@ -0,0 +1,15 @@ +# Emscripten +This file is a bit of notes on the Emscripten changes to the C code. + +# Makefile +I added a `Makefile` to the project. A few key things here. +* warnings flags etc to in `CLANG_WARN_FLAGS` +* compile time `#define` go in `CLANG_OTHER_FLAGS` +* Every .c .cpp file goes in `CPP_FILES` +* Every .h .hpp file goes in `HPP_FILES` however not required + * This is only required if you want make "sensativity" to work correctly +* The emscripten `.js` file is minified by default. to disable this run + * `NOOPT=1 make wasm` + * Doing this will also compile the c code with `O0` +* Any c functions you want to access from javascript must be added to `EXPORT_STRING` + * When you add them, you must add a `_` prefix From d57cc3b147efebd0b31c391cacd139d27613d0a8 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 02:06:17 -0700 Subject: [PATCH 05/34] comments --- lib/parser.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/parser.js b/lib/parser.js index e5fafa5..f4b3874 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -11,10 +11,19 @@ module.exports = () => { const s = new stream.Writable(); - // const lifee = new EventEmitter(); + + // gets called by c with 1 argument, a number const lifemit = s.emit.bind(s); const triee = new EventEmitter(); + + // gets called by c with 5 arguments + // string eventName + // number state->time + // int command + // int state->value + // int state->mask + const triemit = triee.emit.bind(triee); let triemit2 = triemit; From 70d64632a377f9d36b2e9d54756da09a55b03d02 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 02:07:50 -0700 Subject: [PATCH 06/34] c calls js --- Makefile | 2 +- lib/wrapper.js | 44 +++++++++++++++++++++++++++++++++++++++++++- test/wasm.js | 4 ++++ wasm_main.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 90 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index b597c85..0d19a87 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ vcd_spans.c \ # the version here has a prepended underscore # all lines must have trailing comma EXPORT_STRING = \ -# "_somefn", \ +"_execute", \ # "_int_sqrt", \ # "_pass_write_fn", \ # "_get_saved_node_count", \ diff --git a/lib/wrapper.js b/lib/wrapper.js index e7c4f98..1318bf1 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -11,18 +11,60 @@ module.exports = () => { // let total = 0; // let start = 0; + const c = {}; + const wasm = require('../out/vcd.js'); + let bindCallback; - let start = async() => { + const bindCWrap = () => { + const w = wasm.cwrap; + c.execute = w('execute', 'void', ['number', 'number', 'number', 'number']); + }; + + const start = async() => { await _waitForStart(wasm); + bindCWrap(); + bindCallback(); } + // gets a string from a c heap pointer and length + const getString = (name,len) => { + const view = wasm.HEAPU8.subarray(name, name+len); + + let string = ''; + for (let i = 0; i < len; i++) { + string += String.fromCharCode(view[i]); + } + return string; + } + + let boundSet; + + // wasm.addFunction can't be called until after + // start finishes + bindCallback = () => { + boundSet = wasm.addFunction(function(name, len, value) { + + + let prop = getString(name, len); + + console.log(`setting ${prop} to ${value}`); + + + // vsi means returns void accepts a string and int + }, 'viii'); + }; + return { start, + c, log: () => { console.log(wasm); }, + execute: () => { + c.execute(0,0,boundSet,0); + }, onB: (time, cmd) => { }, diff --git a/test/wasm.js b/test/wasm.js index ec52819..9000923 100644 --- a/test/wasm.js +++ b/test/wasm.js @@ -22,6 +22,10 @@ describe('basic', () => { console.log("test"); + // wrapper.c.execute('hello world'); + + wrapper.execute(); + // console.log(wrapper.log()); diff --git a/wasm_main.cpp b/wasm_main.cpp index 84e776b..c68b475 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -10,19 +10,58 @@ using namespace std; static struct vcd_parser_s* state; -static void init(void) { +// returns context +int init(void) { state = (struct vcd_parser_s*) malloc(sizeof *state); const int32_t error = vcd_parser_init(state); if (error) { cout << "ERROR: " << error << "\n"; - return; + return -1; } + + return 0; } int main(void) { cout << "main()\n"; - init(); return 0; } + +/// Typedef used as part of c->js call +typedef void externalJsMethodOne(const int sz); +typedef void externalJsMethodTwo(const char*, const uint64_t time, const uint8_t command, const int dnc0, const int dnc1); + + +typedef int externalJsGetProperty(const char* name); +typedef void externalJsSetProperty(const char* name, const size_t len, const int value); + + +/// function pointer for c->js +static externalJsMethodOne* externalOne = 0; +static externalJsMethodTwo* externalTwo = 0; +static externalJsSetProperty* set_property = 0; +static externalJsGetProperty* get_property = 0; + + + +extern "C" { + +void execute( + externalJsMethodOne* f1, + externalJsMethodTwo* f2, + externalJsSetProperty* sfn, + externalJsGetProperty* gfn + ) { + + // cout << "execute got " << p << "\n"; + cout << "execute " << (int)sfn << "\n"; + set_property = sfn; + + set_property("foo", strlen("foo"), 4); + + +} + +} // extern C \ No newline at end of file From 351f988fb7e009adb2730aa216437303ac3fec6f Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 02:15:35 -0700 Subject: [PATCH 07/34] rework sigsg --- lib/wrapper.js | 20 ++++++++++++-------- wasm_main.cpp | 30 +++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/lib/wrapper.js b/lib/wrapper.js index 1318bf1..0c55cb9 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -19,7 +19,7 @@ module.exports = () => { const bindCWrap = () => { const w = wasm.cwrap; - c.execute = w('execute', 'void', ['number', 'number', 'number', 'number']); + c.execute = w('execute', 'void', ['number', 'number', 'number', 'number', 'number', 'string']); }; const start = async() => { @@ -40,20 +40,24 @@ module.exports = () => { } let boundSet; + let boundGet; // wasm.addFunction can't be called until after // start finishes bindCallback = () => { - boundSet = wasm.addFunction(function(name, len, value) { + boundSet = wasm.addFunction(function(name, len, value) { + let prop = getString(name, len); - let prop = getString(name, len); + console.log(`setting ${prop} to ${value}`); - console.log(`setting ${prop} to ${value}`); + // viii means returns void, accepts int int int + }, 'viii'); - - // vsi means returns void accepts a string and int - }, 'viii'); + boundGet = wasm.addFunction(function(name, len) { + let prop = getString(name, len); + return 42; + }, 'iii'); }; return { @@ -63,7 +67,7 @@ module.exports = () => { console.log(wasm); }, execute: () => { - c.execute(0,0,boundSet,0); + c.execute(0,0,0,boundSet,boundGet,"hi"); }, onB: (time, cmd) => { diff --git a/wasm_main.cpp b/wasm_main.cpp index c68b475..5b46863 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -34,34 +34,50 @@ typedef void externalJsMethodOne(const int sz); typedef void externalJsMethodTwo(const char*, const uint64_t time, const uint8_t command, const int dnc0, const int dnc1); -typedef int externalJsGetProperty(const char* name); +typedef int externalJsGetProperty(const char* name, const size_t len); typedef void externalJsSetProperty(const char* name, const size_t len, const int value); /// function pointer for c->js static externalJsMethodOne* externalOne = 0; static externalJsMethodTwo* externalTwo = 0; -static externalJsSetProperty* set_property = 0; -static externalJsGetProperty* get_property = 0; +static externalJsSetProperty* bound_set_property = 0; +static externalJsGetProperty* bound_get_property = 0; + +static void set_property(const char* name, const int value) { + bound_set_property(name, strlen(name), value); +} + +static int get_property(const char* name) { + return bound_get_property(name, strlen(name)); +} extern "C" { void execute( + const int context, externalJsMethodOne* f1, externalJsMethodTwo* f2, externalJsSetProperty* sfn, - externalJsGetProperty* gfn + externalJsGetProperty* gfn, + char* chunk ) { // cout << "execute got " << p << "\n"; - cout << "execute " << (int)sfn << "\n"; - set_property = sfn; + cout << "execute " << (int)sfn << " and got " << chunk << "\n"; + bound_set_property = sfn; + bound_get_property = gfn; - set_property("foo", strlen("foo"), 4); + int got = get_property("bar"); + + cout << "got " << got << " for bar\n"; + + + } } // extern C \ No newline at end of file From f46ad25c19811f1cd5891e0d1687b35b26c90c2f Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 02:42:00 -0700 Subject: [PATCH 08/34] setting strings and ints from c --- Makefile | 23 +---------- lib/wrapper.js | 31 ++++++++++++--- test/wasm.js | 10 +++++ wasm_main.cpp | 102 ++++++++++++++++++++++++++++++++++--------------- wasm_main.hpp | 8 ++++ 5 files changed, 117 insertions(+), 57 deletions(-) create mode 100644 wasm_main.hpp diff --git a/Makefile b/Makefile index 0d19a87..d7f916b 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ WASM_MAIN = wasm_main.cpp HPP_FILES = \ vcd_parser.h \ +wasm_main.hpp \ CPP_FILES = \ @@ -22,27 +23,7 @@ vcd_spans.c \ # all lines must have trailing comma EXPORT_STRING = \ "_execute", \ -# "_int_sqrt", \ -# "_pass_write_fn", \ -# "_get_saved_node_count", \ -# "_get_saved_node_name", \ -# "_get_saved_node_id", \ -# "_get_child_node_count", \ -# "_get_child_node_id", \ -# "_register_action_node", \ -# "_register_condition_node", \ -# "_unregister_builder", \ -# "_parse_xml", \ -# "_lt", \ -# "_ltd", \ -# "_reset_trackers", \ -# "_reset_factory", \ -# "_reset_all", \ - -# Functions used in debugging -# "_callBoundJs", \ -# "_debug_example", \ - +"_init", \ # warning and error flags CLANG_WARN_FLAGS = \ diff --git a/lib/wrapper.js b/lib/wrapper.js index 0c55cb9..4a03171 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -19,7 +19,8 @@ module.exports = () => { const bindCWrap = () => { const w = wasm.cwrap; - c.execute = w('execute', 'void', ['number', 'number', 'number', 'number', 'number', 'string']); + c.execute = w('execute', 'void', ['number', 'number', 'number', 'number', 'number', 'string']); + c.init = w('init', 'number', ['number', 'number', 'number', 'number']); }; const start = async() => { @@ -39,20 +40,34 @@ module.exports = () => { return string; } + let boundInfo; + let boundSet; let boundGet; + let context = -1; + // wasm.addFunction can't be called until after // start finishes bindCallback = () => { - boundSet = wasm.addFunction(function(name, len, value) { + boundSet = wasm.addFunction(function(name, len, type, v0, v1) { let prop = getString(name, len); - console.log(`setting ${prop} to ${value}`); + switch(type) { + case 0: + boundInfo[prop] = v0; + break; + case 1: + boundInfo[prop] = getString(v0, v1); + break; + default: throw new Error(); + } - // viii means returns void, accepts int int int - }, 'viii'); + console.log(`setting ${prop} to ${boundInfo[prop]}`); + + // viiiii means returns void, accepts int int int int int + }, 'viiiii'); boundGet = wasm.addFunction(function(name, len) { let prop = getString(name, len); @@ -66,8 +81,12 @@ module.exports = () => { log: () => { console.log(wasm); }, + init: (cb0, cb1, info) => { + boundInfo = info; + context = c.init(0,0,boundSet,boundGet); + }, execute: () => { - c.execute(0,0,0,boundSet,boundGet,"hi"); + c.execute(context,0,0,boundSet,boundGet,"hi"); }, onB: (time, cmd) => { diff --git a/test/wasm.js b/test/wasm.js index 9000923..8ce9889 100644 --- a/test/wasm.js +++ b/test/wasm.js @@ -22,10 +22,20 @@ describe('basic', () => { console.log("test"); + const wires = {}; + const info = {stack: [wires], wires: wires}; + + + wrapper.init({},{},info); + + console.log(info); + + // wrapper.c.execute('hello world'); wrapper.execute(); + expect(info.foo).to.equal(10); // console.log(wrapper.log()); diff --git a/wasm_main.cpp b/wasm_main.cpp index 5b46863..f203312 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -6,36 +6,13 @@ using namespace std; - -static struct vcd_parser_s* state; - - -// returns context -int init(void) { - state = (struct vcd_parser_s*) malloc(sizeof *state); - - const int32_t error = vcd_parser_init(state); - if (error) { - cout << "ERROR: " << error << "\n"; - return -1; - } - - return 0; -} - -int main(void) { - cout << "main()\n"; - return 0; -} - - /// Typedef used as part of c->js call typedef void externalJsMethodOne(const int sz); typedef void externalJsMethodTwo(const char*, const uint64_t time, const uint8_t command, const int dnc0, const int dnc1); - typedef int externalJsGetProperty(const char* name, const size_t len); -typedef void externalJsSetProperty(const char* name, const size_t len, const int value); +typedef void externalJsSetProperty(const char* name, const size_t len, const int type, const int v0, const int v1); + /// function pointer for c->js @@ -44,18 +21,76 @@ static externalJsMethodTwo* externalTwo = 0; static externalJsSetProperty* bound_set_property = 0; static externalJsGetProperty* bound_get_property = 0; -static void set_property(const char* name, const int value) { - bound_set_property(name, strlen(name), value); +void set_property_int(const char* name, const int value) { + bound_set_property(name, strlen(name), 0, value, 0); } -static int get_property(const char* name) { +void set_property_string(const char* name, const char* value) { + bound_set_property(name, strlen(name), 1, (int)value, strlen(value)); +} + +int get_property(const char* name) { return bound_get_property(name, strlen(name)); } +static struct vcd_parser_s* state; extern "C" { +// returns context +int init( + externalJsMethodOne* f1, + externalJsMethodTwo* f2, + externalJsSetProperty* sfn, + externalJsGetProperty* gfn + ) { + + + state = (struct vcd_parser_s*) malloc(sizeof *state); + + const int32_t error = vcd_parser_init(state); + if (error) { + cout << "ERROR: " << error << "\n"; + return -1; + } + + bound_set_property = sfn; + bound_get_property = gfn; + externalOne = f1; + externalTwo = f2; + + state->lifee = (void*) externalOne; + state->triee = (void*) externalTwo; + + static char triggerString [4096] = " "; + static char tmpStr [4096] = " "; + static uint64_t valueBuf [4096] = {}; + static uint64_t maskBuf [4096] = {}; + + state->trigger = triggerString; + state->reason = "NO REASON"; + state->napi_env = 0; + state->tmpStr = tmpStr; + state->value = valueBuf; + state->mask = maskBuf; + state->digitCount = 0; + + set_property_string("status", "declaration"); + + + static int context = 0; + context++; + + return context; +} + + + + + + + void execute( const int context, externalJsMethodOne* f1, @@ -69,15 +104,22 @@ void execute( cout << "execute " << (int)sfn << " and got " << chunk << "\n"; bound_set_property = sfn; bound_get_property = gfn; + externalOne = f1; + externalTwo = f2; + set_property_int("foo", 10); int got = get_property("bar"); cout << "got " << got << " for bar\n"; - - } +int main(void) { + cout << "main()\n"; + return 0; +} + + } // extern C \ No newline at end of file diff --git a/wasm_main.hpp b/wasm_main.hpp new file mode 100644 index 0000000..ee9ac0c --- /dev/null +++ b/wasm_main.hpp @@ -0,0 +1,8 @@ +#pragma once + + + +// void set_property(const char* name, const int value); +// int get_property(const char* name); + + From 4378dc826e511ba110ec1f3e4cc5d63457609613 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 12:44:36 -0700 Subject: [PATCH 09/34] prepare for parsing --- lib/wrapper.js | 2 +- test/wasm.js | 2 +- test/wasmdump.js | 124 +++++++++++++++++++++++++++++++++++++++++++++++ vcd_spans.c | 5 ++ wasm_main.cpp | 42 ++++++++++++---- 5 files changed, 163 insertions(+), 12 deletions(-) create mode 100644 test/wasmdump.js diff --git a/lib/wrapper.js b/lib/wrapper.js index 4a03171..a1f24d9 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -19,7 +19,7 @@ module.exports = () => { const bindCWrap = () => { const w = wasm.cwrap; - c.execute = w('execute', 'void', ['number', 'number', 'number', 'number', 'number', 'string']); + c.execute = w('execute', 'number', ['number', 'number', 'number', 'number', 'number', 'string']); c.init = w('init', 'number', ['number', 'number', 'number', 'number']); }; diff --git a/test/wasm.js b/test/wasm.js index 8ce9889..f55b022 100644 --- a/test/wasm.js +++ b/test/wasm.js @@ -35,7 +35,7 @@ describe('basic', () => { wrapper.execute(); - expect(info.foo).to.equal(10); + // expect(info.foo).to.equal(10); // console.log(wrapper.log()); diff --git a/test/wasmdump.js b/test/wasmdump.js new file mode 100644 index 0000000..95dbdcf --- /dev/null +++ b/test/wasmdump.js @@ -0,0 +1,124 @@ +'use strict'; + +const expect = require('chai').expect; +// const lib = require('../lib/index.js'); +const lib = require('../lib/wrapper.js')(); + +describe('dump', () => { + + before(() => { + return lib.start(); + }); + + it('simple', done => { + const inst = lib.parser(); + const dump = []; + ['"}G', '{u', 'u)'] // array of all signal ids + .map(id => + inst.change.on(id, (time, cmd, value, mask) => { + dump.push({ + id, + time, + cmd, + value, + mask + }); + }) + ); + + inst.on('finish', () => { + expect(inst.getTime()).to.eq(316n); + expect(dump).to.deep.eq([ + { id: '"}G', time: 100, cmd: 14, value: 0n, mask: 0n }, + { id: '"}G', time: 200, cmd: 15, value: 1n, mask: 0n }, + { id: '{u', time: 200, cmd: 19, value: 0xf0f0f0f0f0f0f0f0n, mask: 0xff00ff00ff00ff00n }, + { id: '"}G', time: 300, cmd: 14, value: 0n, mask: 0n }, + { id: '{u', time: 300, cmd: 19, value: 0xf000000000000000n, mask: 0n }, + { id: '{u', time: 301, cmd: 19, value: 0x0f00000000000000n, mask: 0n }, + { id: '{u', time: 302, cmd: 19, value: 0x00f0000000000000n, mask: 0n }, + { id: '{u', time: 303, cmd: 19, value: 0x000f000000000000n, mask: 0n }, + { id: '{u', time: 304, cmd: 19, value: 0x0000f00000000000n, mask: 0n }, + { id: '{u', time: 305, cmd: 19, value: 0x00000f0000000000n, mask: 0n }, + { id: '{u', time: 306, cmd: 19, value: 0x000000f000000000n, mask: 0n }, + { id: '{u', time: 307, cmd: 19, value: 0x0000000f00000000n, mask: 0n }, + { id: '{u', time: 308, cmd: 20, value: 0x00000000f0000000n, mask: 0n }, + { id: '{u', time: 309, cmd: 19, value: 0x000000000f000000n, mask: 0n }, + { id: '{u', time: 310, cmd: 19, value: 0x0000000000f00000n, mask: 0n }, + { id: '{u', time: 311, cmd: 19, value: 0x00000000000f0000n, mask: 0n }, + { id: '{u', time: 312, cmd: 19, value: 0x000000000000f000n, mask: 0n }, + { id: '{u', time: 313, cmd: 19, value: 0x0000000000000f00n, mask: 0n }, + { id: '{u', time: 314, cmd: 19, value: 0x00000000000000f0n, mask: 0n }, + { id: '{u', time: 315, cmd: 19, value: 0x000000000000000fn, mask: 0n }, + { id: '"}G', time: 316, cmd: 15, value: 1n, mask: 0n }, + ]) + // console.log(dump); + done(); + }); + + inst.write(` +$version Generated by VerilatedVcd $end +$date Wed Sep 18 22:59:07 2019 + $end +$timescale 1ns $end + + $scope module top $end + $var wire 1 "}G clock $end + $scope module leaf $end + $var wire 64 {u counter [63:0] $end + $upscope $end + $scope module fruit $end + $var wire 4 u) point [3:0] $end + $upscope $end + $upscope $end + + $enddefinitions $end +#100 +0"}G +#200 +1"}G +bzzzzxxxx11110000ZZZZXXXX11110000zzzzxxx`); + +// break in the middle of the number scan + + inst.write( `x11110000zzzzxxxx11110000 {u +#300 +0"}G +b1111000000000000000000000000000000000000000000000000000000000000 {u +#301 +b0000111100000000000000000000000000000000000000000000000000000000 {u +#302 +b0000000011110000000000000000000000000000000000000000000000000000 {u +#303 +b0000000000001111000000000000000000000000000000000000000000000000 {u +#304 +b0000000000000000111100000000000000000000000000000000000000000000 {u +#305 +b0000000000000000000011110000000000000000000000000000000000000000 {u +#306 +b0000000000000000000000001111000000000000000000000000000000000000 {u +#307 +b0000000000000000000000000000111100000000000000000000000000000000 {u +#308 +B0000000000000000000000000000000011110000000000000000000000000000 {u +#309 +b0000000000000000000000000000000000001111000000000000000000000000 {u +#310 +b0000000000000000000000000000000000000000111100000000000000000000 {u +#311 +b0000000000000000000000000000000000000000000011110000000000000000 {u +#312 +b0000000000000000000000000000000000000000000000001111000000000000 {u +#313 +b0000000000000000000000000000000000000000000000000000111100000000 {u +#314 +b0000000000000000000000000000000000000000000000000000000011110000 {u +#315 +b0000000000000000000000000000000000000000000000000000000000001111 {u +#316 +1"}G +`); + inst.end(); + }); +}); + +/* eslint-env mocha */ diff --git a/vcd_spans.c b/vcd_spans.c index f872288..af0602d 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -11,6 +11,8 @@ typedef void* napi_env; #endif +// #define LOGSPAN +#define LOGSPAN printf("%s\n", __FUNCTION__); #define ASSERT(val, expr) \ @@ -62,6 +64,7 @@ int stringEq ( } int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { + LOGSPAN; napi_env env = state->napi_env; if (state->command == 5) { // $upscope @@ -87,6 +90,7 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char } int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { + LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; // *(endp - 1) = 0; // FIXME NULL termination of ASCII string @@ -104,6 +108,7 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig } int varSizeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { + LOGSPAN; state->size = strtol((const char *)p, (char **)&endp, 10); return 0; } diff --git a/wasm_main.cpp b/wasm_main.cpp index f203312..057f011 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -88,33 +88,55 @@ int init( - - - -void execute( +int32_t execute( const int context, externalJsMethodOne* f1, externalJsMethodTwo* f2, externalJsSetProperty* sfn, externalJsGetProperty* gfn, - char* chunk + char* p ) { // cout << "execute got " << p << "\n"; - cout << "execute " << (int)sfn << " and got " << chunk << "\n"; + cout << "execute " << (int)sfn << " and got " << p << "\n"; bound_set_property = sfn; bound_get_property = gfn; externalOne = f1; externalTwo = f2; - set_property_int("foo", 10); + const size_t plen = strlen(p); + + const int32_t error = vcd_parser_execute(state, p, p + plen); + + return error; +} + + + +// void execute( +// const int context, +// externalJsMethodOne* f1, +// externalJsMethodTwo* f2, +// externalJsSetProperty* sfn, +// externalJsGetProperty* gfn, +// char* chunk +// ) { + +// // cout << "execute got " << p << "\n"; +// cout << "execute " << (int)sfn << " and got " << chunk << "\n"; +// bound_set_property = sfn; +// bound_get_property = gfn; +// externalOne = f1; +// externalTwo = f2; + +// set_property_int("foo", 10); - int got = get_property("bar"); +// int got = get_property("bar"); - cout << "got " << got << " for bar\n"; +// cout << "got " << got << " for bar\n"; -} +// } int main(void) { cout << "main()\n"; From 98eb19cd69ebf255fa74d320ce3c01baff1934b0 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 13:26:11 -0700 Subject: [PATCH 10/34] getting commandSpans now --- Makefile | 2 ++ lib/index.js | 2 ++ lib/wasmparser.js | 62 +++++++++++++++++++++++++++++++++++++++++++++++ lib/wrapper.js | 44 +++++++++++++++++++++------------ package.json | 2 +- test/wasmdump.js | 13 +++++++--- wasm_main.cpp | 43 +++++++++++++++++++------------- 7 files changed, 130 insertions(+), 38 deletions(-) create mode 100644 lib/wasmparser.js diff --git a/Makefile b/Makefile index d7f916b..165f246 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,8 @@ vcd_spans.c \ EXPORT_STRING = \ "_execute", \ "_init", \ +"_setTrigger", \ +"_getTime", \ # warning and error flags CLANG_WARN_FLAGS = \ diff --git a/lib/index.js b/lib/index.js index 55ee97a..bc48e45 100644 --- a/lib/index.js +++ b/lib/index.js @@ -2,6 +2,7 @@ const pkg = require('../package.json'); const parser = require('./parser.js'); +const wasmparser = require('./wasmparser.js'); const and = require('./and.js'); const activity = require('./activity.js'); const wrapper = require('./wrapper.js'); @@ -11,5 +12,6 @@ module.exports = { and: and, activity: activity, parser: parser, + wasmparser: wasmparser, wrapper: wrapper }; diff --git a/lib/wasmparser.js b/lib/wasmparser.js new file mode 100644 index 0000000..fde3c55 --- /dev/null +++ b/lib/wasmparser.js @@ -0,0 +1,62 @@ +'use strict'; + +const stream = require('stream'); +const EventEmitter = require('events').EventEmitter; +// let lib = require('bindings')('vcd.node'); + + +module.exports = async () => { + + const lib = require('../lib/wrapper.js')(); + await lib.start(); + + const wires = {}; + const info = {stack: [wires], wires: wires}; + + const s = new stream.Writable(); + + + // gets called by c with 1 argument, a number + const lifemit = s.emit.bind(s); + + const triee = new EventEmitter(); + + // gets called by c with 5 arguments + // string eventName + // number state->time + // int command + // int state->value + // int state->mask + + const triemit = triee.emit.bind(triee); + let triemit2 = triemit; + + const cxt = lib.init(lifemit, triemit, info); + + s._write = function (chunk, encoding, callback) { + console.log('about to write', chunk); + lib.execute(cxt, lifemit, triemit2, info, chunk); + callback(); + }; + + s.change = { + on: (id, fn) => { + triemit2 = triemit; + triee.on(id, fn); + const triggerString = triee.eventNames().join(' ') + ' '; + lib.setTrigger(cxt, triggerString); + }, + any: fn => { + triemit2 = fn; + lib.setTrigger(cxt, '\0'); + } + }; + + s.info = info; + + s.getTime = () => lib.getTime(cxt); + + s.start = lib.start; + + return s; +}; diff --git a/lib/wrapper.js b/lib/wrapper.js index a1f24d9..af87705 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -19,8 +19,10 @@ module.exports = () => { const bindCWrap = () => { const w = wasm.cwrap; - c.execute = w('execute', 'number', ['number', 'number', 'number', 'number', 'number', 'string']); - c.init = w('init', 'number', ['number', 'number', 'number', 'number']); + c.execute = w('execute', 'number', ['number', 'number', 'number', 'number', 'number', 'string']); + c.init = w('init', 'number', ['number', 'number', 'number', 'number']); + c.getTime = w('getTime', 'number', ['number']); + c.setTrigger = w('setTrigger', 'number', ['number', 'string']); }; const start = async() => { @@ -45,6 +47,11 @@ module.exports = () => { let boundSet; let boundGet; + let ee = []; + + let boundEE0; + let boundEE1; + let context = -1; // wasm.addFunction can't be called until after @@ -72,7 +79,16 @@ module.exports = () => { boundGet = wasm.addFunction(function(name, len) { let prop = getString(name, len); return 42; - }, 'iii'); + }, 'iii'); + + boundEE0 = wasm.addFunction(function(val) { + ee[0].emit(val); + }, 'vi'); + + boundEE1 = wasm.addFunction(function(eventName, l0, time, command, value, mask) { + ee[1].emit(getString(eventName, l0), time, command, value, mask); + }, 'viiiiii'); + }; return { @@ -83,22 +99,18 @@ module.exports = () => { }, init: (cb0, cb1, info) => { boundInfo = info; - context = c.init(0,0,boundSet,boundGet); + ee[0] = cb0; + ee[1] = cb1; + context = c.init(boundEE0,boundEE1,boundSet,boundGet); }, - execute: () => { - c.execute(context,0,0,boundSet,boundGet,"hi"); + execute: (ctx, lifemit, triemit, info, chunk) => { + c.execute(ctx,0,0,boundSet,boundGet,chunk.toString()); }, - onB: (time, cmd) => { - + setTrigger: (ctx, triggerString) => { + return c.setTrigger(ctx, triggerString); }, - onNotB: (time, cmd) => { - switch(state) { - case 0: if (cmd === 14) { state = 2; } break; - case 1: if (cmd === 14) { state = 3; start = time; } break; - case 2: if (cmd === 15) { state = 0; } break; - case 3: if (cmd === 15) { state = 1; total += (time - start); start = 0; } break; - default: throw new Error(); - } + getTime: (ctx) => { + return c.getTime(ctx); }, time: () => total + start }; diff --git a/package.json b/package.json index 9795ae9..9fc5d75 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "testlint": "eslint bin lib && nyc -r=text -r=lcov mocha", - "test": "nyc -r=text -r=lcov mocha", + "test": "eslint bin lib; nyc -r=text -r=lcov mocha", "testonly": "nyc -r=text -r=lcov mocha", "watch": "mocha --watch", "install": "node bin/build.js", diff --git a/test/wasmdump.js b/test/wasmdump.js index 95dbdcf..f8beb8e 100644 --- a/test/wasmdump.js +++ b/test/wasmdump.js @@ -1,17 +1,22 @@ 'use strict'; const expect = require('chai').expect; -// const lib = require('../lib/index.js'); -const lib = require('../lib/wrapper.js')(); +const lib = require('../lib/index.js'); describe('dump', () => { + let inst; + + // return a promise, and mocha will wait until it resolves before(() => { - return lib.start(); + const fn = async () => { + inst = await lib.wasmparser(); + }; + return fn(); }); it('simple', done => { - const inst = lib.parser(); + const dump = []; ['"}G', '{u', 'u)'] // array of all signal ids .map(id => diff --git a/wasm_main.cpp b/wasm_main.cpp index 057f011..8f8ca11 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -7,8 +7,8 @@ using namespace std; /// Typedef used as part of c->js call -typedef void externalJsMethodOne(const int sz); -typedef void externalJsMethodTwo(const char*, const uint64_t time, const uint8_t command, const int dnc0, const int dnc1); +typedef void externalJsMethodZero(const int sz); +typedef void externalJsMethodOne (const char*, const uint64_t time, const uint8_t command, const int dnc0, const int dnc1); typedef int externalJsGetProperty(const char* name, const size_t len); typedef void externalJsSetProperty(const char* name, const size_t len, const int type, const int v0, const int v1); @@ -16,8 +16,8 @@ typedef void externalJsSetProperty(const char* name, const size_t len, const int /// function pointer for c->js -static externalJsMethodOne* externalOne = 0; -static externalJsMethodTwo* externalTwo = 0; +static externalJsMethodZero* externalZero = 0; +static externalJsMethodOne* externalOne = 0; static externalJsSetProperty* bound_set_property = 0; static externalJsGetProperty* bound_get_property = 0; @@ -40,8 +40,8 @@ extern "C" { // returns context int init( - externalJsMethodOne* f1, - externalJsMethodTwo* f2, + externalJsMethodZero* f0, + externalJsMethodOne* f1, externalJsSetProperty* sfn, externalJsGetProperty* gfn ) { @@ -57,11 +57,11 @@ int init( bound_set_property = sfn; bound_get_property = gfn; - externalOne = f1; - externalTwo = f2; + externalZero = f0; + externalOne = f1; - state->lifee = (void*) externalOne; - state->triee = (void*) externalTwo; + state->lifee = (void*) externalZero; + state->triee = (void*) externalOne; static char triggerString [4096] = " "; static char tmpStr [4096] = " "; @@ -90,19 +90,19 @@ int init( int32_t execute( const int context, - externalJsMethodOne* f1, - externalJsMethodTwo* f2, + externalJsMethodZero* f0, + externalJsMethodOne* f1, externalJsSetProperty* sfn, externalJsGetProperty* gfn, char* p ) { // cout << "execute got " << p << "\n"; - cout << "execute " << (int)sfn << " and got " << p << "\n"; + // cout << "execute " << (int)sfn << " and got " << p << "\n"; bound_set_property = sfn; bound_get_property = gfn; - externalOne = f1; - externalTwo = f2; + externalZero = f0; + externalOne = f1; const size_t plen = strlen(p); @@ -111,12 +111,21 @@ int32_t execute( return error; } +int setTrigger(const int context, char* triggerString) { + cout << "setTrigger() got " << triggerString << "\n"; + return 0; +} + +int getTime(const int context) { + return state->time; +} + // void execute( // const int context, +// externalJsMethodZero* f0, // externalJsMethodOne* f1, -// externalJsMethodTwo* f2, // externalJsSetProperty* sfn, // externalJsGetProperty* gfn, // char* chunk @@ -126,8 +135,8 @@ int32_t execute( // cout << "execute " << (int)sfn << " and got " << chunk << "\n"; // bound_set_property = sfn; // bound_get_property = gfn; +// externalZero = f0; // externalOne = f1; -// externalTwo = f2; // set_property_int("foo", 10); From a244a0581df1a0030a7d2763904409e969a42257 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 13:54:26 -0700 Subject: [PATCH 11/34] install dot-prop --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 9fc5d75..e61a249 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "dependencies": { "async": "^3.1.0", "bindings": "^1.5.0", + "dot-prop": "^5.3.0", "fs-extra": "^9.0.1", "llparse": "^7.0.1" }, From c59c26b3873065222026203590a4ef6b7cf319c1 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 14:06:11 -0700 Subject: [PATCH 12/34] no code change --- Makefile | 5 ++++- lib/wasmparser.js | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 165f246..8a86e5e 100644 --- a/Makefile +++ b/Makefile @@ -108,7 +108,7 @@ out/vcd.wasm: $(WASM_MAIN) $(CPP_FILES) $(HPP_FILES) Makefile -.PHONY: all build watch dev start test pretest lint jestc copydist cleandist +.PHONY: all build watch dev start test pretest lint jestc copydist cleandist prepare .PHONY: test testonly @@ -121,6 +121,9 @@ test: testonly: npm run testonly +prepare: + npm run prepare + clean: rm -rf out/* diff --git a/lib/wasmparser.js b/lib/wasmparser.js index fde3c55..5786948 100644 --- a/lib/wasmparser.js +++ b/lib/wasmparser.js @@ -16,7 +16,7 @@ module.exports = async () => { const s = new stream.Writable(); - // gets called by c with 1 argument, a number + // gets called by c with 1 argument, a string const lifemit = s.emit.bind(s); const triee = new EventEmitter(); From 846d4e0c6a41b45b891c098a995af5125c2bc797 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 14:58:31 -0700 Subject: [PATCH 13/34] progress --- bin/build.js | 1 + lib/wasmparser.js | 3 +++ lib/wrapper.js | 21 +++++++++++++++------ vcd.c | 2 ++ vcd_spans.c | 24 ++++++++++++++++++++++-- wasm_main.cpp | 19 ++++++++++++++----- wasm_main.hpp | 10 +++++----- 7 files changed, 62 insertions(+), 18 deletions(-) diff --git a/bin/build.js b/bin/build.js index 24508c1..5f39a52 100755 --- a/bin/build.js +++ b/bin/build.js @@ -37,6 +37,7 @@ const properties = { mask: 'ptr', // mask (x, z) of the signal on change event digitCount: 'i32', tmpStr: 'ptr', + tmpStr2: 'ptr', stackPointer: 'i32', id: 'ptr', napi_env: 'ptr' diff --git a/lib/wasmparser.js b/lib/wasmparser.js index 5786948..7f42996 100644 --- a/lib/wasmparser.js +++ b/lib/wasmparser.js @@ -3,6 +3,7 @@ const stream = require('stream'); const EventEmitter = require('events').EventEmitter; // let lib = require('bindings')('vcd.node'); +const util = require('util'); module.exports = async () => { @@ -36,6 +37,8 @@ module.exports = async () => { s._write = function (chunk, encoding, callback) { console.log('about to write', chunk); lib.execute(cxt, lifemit, triemit2, info, chunk); + console.log(util.inspect(info, {showHidden: true, depth : null, colorize: true})); + // console.log(info); callback(); }; diff --git a/lib/wrapper.js b/lib/wrapper.js index af87705..cd7564c 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -1,5 +1,7 @@ 'use strict'; +const dotProp = require('dot-prop'); + function _waitForStart(mod) { return new Promise((resolve, reject)=>{ mod.addOnPostRun(resolve); @@ -64,14 +66,20 @@ module.exports = () => { switch(type) { case 0: boundInfo[prop] = v0; + // console.log(`setting ${prop} to ${boundInfo[prop]}`); break; case 1: boundInfo[prop] = getString(v0, v1); + // console.log(`setting ${prop} to ${boundInfo[prop]}`); break; + case 2: + dotProp.set(boundInfo, prop, getString(v0, v1)); + console.log(`setting ${prop} to ${getString(v0, v1)}`); + break; + default: throw new Error(); } - console.log(`setting ${prop} to ${boundInfo[prop]}`); // viiiii means returns void, accepts int int int int int }, 'viiiii'); @@ -81,12 +89,13 @@ module.exports = () => { return 42; }, 'iii'); - boundEE0 = wasm.addFunction(function(val) { - ee[0].emit(val); - }, 'vi'); + + boundEE0 = wasm.addFunction(function(name, len) { + ee[0](getString(name, len)); + }, 'vii'); boundEE1 = wasm.addFunction(function(eventName, l0, time, command, value, mask) { - ee[1].emit(getString(eventName, l0), time, command, value, mask); + ee[1](getString(eventName, l0), time, command, value, mask); }, 'viiiiii'); }; @@ -104,7 +113,7 @@ module.exports = () => { context = c.init(boundEE0,boundEE1,boundSet,boundGet); }, execute: (ctx, lifemit, triemit, info, chunk) => { - c.execute(ctx,0,0,boundSet,boundGet,chunk.toString()); + c.execute(ctx,boundEE0,boundEE1,boundSet,boundGet,chunk.toString()); }, setTrigger: (ctx, triggerString) => { return c.setTrigger(ctx, triggerString); diff --git a/vcd.c b/vcd.c index 9da6991..04ace22 100644 --- a/vcd.c +++ b/vcd.c @@ -124,6 +124,7 @@ METHOD(init) { static char triggerString [4096] = " "; static char tmpStr [4096] = " "; + static char tmpStr2 [4096] = " "; static uint64_t valueBuf [4096] = {}; static uint64_t maskBuf [4096] = {}; @@ -131,6 +132,7 @@ METHOD(init) { state->reason = "NO REASON"; state->napi_env = env; state->tmpStr = tmpStr; + state->tmpStr2 = tmpStr2; state->value = valueBuf; state->mask = maskBuf; state->digitCount = 0; diff --git a/vcd_spans.c b/vcd_spans.c index af0602d..83f7eb6 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -1,9 +1,12 @@ #include #include +#include #include "vcd_parser.h" #ifndef VCDWASM #include +#else +#include "wasm_main.hpp" #endif #ifdef VCDWASM @@ -82,6 +85,9 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char // ASSERT(eventPayload, napi_create_string_latin1(env, "payload", NAPI_AUTO_LENGTH, &eventPayload)) napi_value* argv[] = { &eventName }; // , &eventPayload }; ASSERT(state->lifee, napi_call_function(env, undefined, state->lifee, 1, *argv, &return_val)) +#else + set_property_string("status", "simulation"); + emit_lifee("$enddefinitions"); #endif return 0; } @@ -95,14 +101,20 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig napi_env env = state->napi_env; // *(endp - 1) = 0; // FIXME NULL termination of ASCII string strcopy(p, endp, state->tmpStr); - napi_value name, obj, stack, top; - ASSERT(name, napi_create_string_latin1(env, (char*)p, (endp - p - 1), &name)) + napi_value obj, stack, top; ASSERT(obj, napi_create_object(env, &obj)) ASSERT(state->info, napi_get_named_property(env, state->info, "stack", &stack)) ASSERT(top, napi_get_element(env, stack, state->stackPointer, &top)) + printf("Got stack %d\n", state->stackPointer); ASSERT(top, napi_set_named_property(env, top, state->tmpStr, obj)) + printf("Set ? to %s\n", (char*)state->tmpStr); state->stackPointer += 1; ASSERT(top, napi_set_element(env, stack, state->stackPointer, obj)) +#else + state->stackPointer += 1; + strcopy(p, endp, state->tmpStr); // load the value into temp string 1 + snprintf(state->tmpStr2, 4096, "stack.%d\n", state->stackPointer); // load the dot-prop into string 2 + set_path_string(state->tmpStr2, state->tmpStr); #endif return 0; } @@ -114,16 +126,21 @@ int varSizeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char } int varIdSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { + LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; napi_value varId; ASSERT(varId, napi_create_string_latin1(env, (char*)p, (endp - p - 1), &varId)) ASSERT(state->info, napi_set_named_property(env, state->info, "varId", varId)) +#else + strcopy(p, endp, state->tmpStr); + set_property_string("varId", state->tmpStr); #endif return 0; } int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { + LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; // *(endp - 1) = 0; // FIXME NULL termination of ASCII string @@ -133,6 +150,9 @@ int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char ASSERT(top, napi_get_element(env, stack, state->stackPointer, &top)) ASSERT(state->info, napi_get_named_property(env, state->info, "varId", &varId)) ASSERT(state->info, napi_set_named_property(env, top, state->tmpStr, varId)) +#else + // char *varIdString = + set_property_string("varId", state->tmpStr); #endif return 0; } diff --git a/wasm_main.cpp b/wasm_main.cpp index 8f8ca11..9571c4f 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -7,7 +7,7 @@ using namespace std; /// Typedef used as part of c->js call -typedef void externalJsMethodZero(const int sz); +typedef void externalJsMethodZero(const char* name, const size_t len); typedef void externalJsMethodOne (const char*, const uint64_t time, const uint8_t command, const int dnc0, const int dnc1); typedef int externalJsGetProperty(const char* name, const size_t len); @@ -20,6 +20,9 @@ static externalJsMethodZero* externalZero = 0; static externalJsMethodOne* externalOne = 0; static externalJsSetProperty* bound_set_property = 0; static externalJsGetProperty* bound_get_property = 0; +static struct vcd_parser_s* state; + +extern "C" { void set_property_int(const char* name, const int value) { bound_set_property(name, strlen(name), 0, value, 0); @@ -29,14 +32,20 @@ void set_property_string(const char* name, const char* value) { bound_set_property(name, strlen(name), 1, (int)value, strlen(value)); } -int get_property(const char* name) { +void set_path_string(const char* name, const char* value) { + bound_set_property(name, strlen(name), 2, (int)value, strlen(value)); +} + +int get_property_int(const char* name) { return bound_get_property(name, strlen(name)); } +void emit_lifee(const char* name) { + externalZero(name, strlen(name)); +} + -static struct vcd_parser_s* state; -extern "C" { // returns context int init( @@ -141,7 +150,7 @@ int getTime(const int context) { // set_property_int("foo", 10); -// int got = get_property("bar"); +// int got = get_property_int("bar"); // cout << "got " << got << " for bar\n"; diff --git a/wasm_main.hpp b/wasm_main.hpp index ee9ac0c..d18ffea 100644 --- a/wasm_main.hpp +++ b/wasm_main.hpp @@ -1,8 +1,8 @@ #pragma once - -// void set_property(const char* name, const int value); -// int get_property(const char* name); - - +void set_property_int(const char* name, const int value); +void set_property_string(const char* name, const char* value); +void set_path_string(const char* name, const char* value); +int get_property_int(const char* name); +void emit_lifee(const char* name); From 6a27f48a1fae3b1f630301f954c85d8337613b38 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 15:37:42 -0700 Subject: [PATCH 14/34] closer --- lib/wrapper.js | 14 ++++++++ test/wasmdump.js | 93 ++++++++++++++---------------------------------- vcd_spans.c | 34 +++++++++++++----- wasm_main.cpp | 10 +++++- wasm_main.hpp | 2 ++ 5 files changed, 77 insertions(+), 76 deletions(-) diff --git a/lib/wrapper.js b/lib/wrapper.js index cd7564c..22e7463 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -64,18 +64,32 @@ module.exports = () => { let prop = getString(name, len); switch(type) { + // set number case 0: boundInfo[prop] = v0; // console.log(`setting ${prop} to ${boundInfo[prop]}`); break; + // set string case 1: boundInfo[prop] = getString(v0, v1); // console.log(`setting ${prop} to ${boundInfo[prop]}`); break; + // set string to path case 2: dotProp.set(boundInfo, prop, getString(v0, v1)); console.log(`setting ${prop} to ${getString(v0, v1)}`); break; + // path to path (any type) + case 3: + let tmp = dotProp.get(boundInfo, getString(v0, v1)); + console.log(`for ${getString(v0, v1)} got ${tmp}, set to ${prop}`); + dotProp.set(boundInfo, prop, tmp); + break; + // create empty object at path + case 4: + console.log(`${prop} is new {}`); + dotProp.set(boundInfo, prop, {}); + break; default: throw new Error(); } diff --git a/test/wasmdump.js b/test/wasmdump.js index f8beb8e..df63d40 100644 --- a/test/wasmdump.js +++ b/test/wasmdump.js @@ -15,7 +15,7 @@ describe('dump', () => { return fn(); }); - it('simple', done => { + it('simple wasm', done => { const dump = []; ['"}G', '{u', 'u)'] // array of all signal ids @@ -32,30 +32,30 @@ describe('dump', () => { ); inst.on('finish', () => { - expect(inst.getTime()).to.eq(316n); - expect(dump).to.deep.eq([ - { id: '"}G', time: 100, cmd: 14, value: 0n, mask: 0n }, - { id: '"}G', time: 200, cmd: 15, value: 1n, mask: 0n }, - { id: '{u', time: 200, cmd: 19, value: 0xf0f0f0f0f0f0f0f0n, mask: 0xff00ff00ff00ff00n }, - { id: '"}G', time: 300, cmd: 14, value: 0n, mask: 0n }, - { id: '{u', time: 300, cmd: 19, value: 0xf000000000000000n, mask: 0n }, - { id: '{u', time: 301, cmd: 19, value: 0x0f00000000000000n, mask: 0n }, - { id: '{u', time: 302, cmd: 19, value: 0x00f0000000000000n, mask: 0n }, - { id: '{u', time: 303, cmd: 19, value: 0x000f000000000000n, mask: 0n }, - { id: '{u', time: 304, cmd: 19, value: 0x0000f00000000000n, mask: 0n }, - { id: '{u', time: 305, cmd: 19, value: 0x00000f0000000000n, mask: 0n }, - { id: '{u', time: 306, cmd: 19, value: 0x000000f000000000n, mask: 0n }, - { id: '{u', time: 307, cmd: 19, value: 0x0000000f00000000n, mask: 0n }, - { id: '{u', time: 308, cmd: 20, value: 0x00000000f0000000n, mask: 0n }, - { id: '{u', time: 309, cmd: 19, value: 0x000000000f000000n, mask: 0n }, - { id: '{u', time: 310, cmd: 19, value: 0x0000000000f00000n, mask: 0n }, - { id: '{u', time: 311, cmd: 19, value: 0x00000000000f0000n, mask: 0n }, - { id: '{u', time: 312, cmd: 19, value: 0x000000000000f000n, mask: 0n }, - { id: '{u', time: 313, cmd: 19, value: 0x0000000000000f00n, mask: 0n }, - { id: '{u', time: 314, cmd: 19, value: 0x00000000000000f0n, mask: 0n }, - { id: '{u', time: 315, cmd: 19, value: 0x000000000000000fn, mask: 0n }, - { id: '"}G', time: 316, cmd: 15, value: 1n, mask: 0n }, - ]) + // expect(inst.getTime()).to.eq(316n); + // expect(dump).to.deep.eq([ + // { id: '"}G', time: 100, cmd: 14, value: 0n, mask: 0n }, + // { id: '"}G', time: 200, cmd: 15, value: 1n, mask: 0n }, + // { id: '{u', time: 200, cmd: 19, value: 0xf0f0f0f0f0f0f0f0n, mask: 0xff00ff00ff00ff00n }, + // { id: '"}G', time: 300, cmd: 14, value: 0n, mask: 0n }, + // { id: '{u', time: 300, cmd: 19, value: 0xf000000000000000n, mask: 0n }, + // { id: '{u', time: 301, cmd: 19, value: 0x0f00000000000000n, mask: 0n }, + // { id: '{u', time: 302, cmd: 19, value: 0x00f0000000000000n, mask: 0n }, + // { id: '{u', time: 303, cmd: 19, value: 0x000f000000000000n, mask: 0n }, + // { id: '{u', time: 304, cmd: 19, value: 0x0000f00000000000n, mask: 0n }, + // { id: '{u', time: 305, cmd: 19, value: 0x00000f0000000000n, mask: 0n }, + // { id: '{u', time: 306, cmd: 19, value: 0x000000f000000000n, mask: 0n }, + // { id: '{u', time: 307, cmd: 19, value: 0x0000000f00000000n, mask: 0n }, + // { id: '{u', time: 308, cmd: 20, value: 0x00000000f0000000n, mask: 0n }, + // { id: '{u', time: 309, cmd: 19, value: 0x000000000f000000n, mask: 0n }, + // { id: '{u', time: 310, cmd: 19, value: 0x0000000000f00000n, mask: 0n }, + // { id: '{u', time: 311, cmd: 19, value: 0x00000000000f0000n, mask: 0n }, + // { id: '{u', time: 312, cmd: 19, value: 0x000000000000f000n, mask: 0n }, + // { id: '{u', time: 313, cmd: 19, value: 0x0000000000000f00n, mask: 0n }, + // { id: '{u', time: 314, cmd: 19, value: 0x00000000000000f0n, mask: 0n }, + // { id: '{u', time: 315, cmd: 19, value: 0x000000000000000fn, mask: 0n }, + // { id: '"}G', time: 316, cmd: 15, value: 1n, mask: 0n }, + // ]) // console.log(dump); done(); }); @@ -68,12 +68,6 @@ $timescale 1ns $end $scope module top $end $var wire 1 "}G clock $end - $scope module leaf $end - $var wire 64 {u counter [63:0] $end - $upscope $end - $scope module fruit $end - $var wire 4 u) point [3:0] $end - $upscope $end $upscope $end $enddefinitions $end @@ -81,46 +75,11 @@ $timescale 1ns $end 0"}G #200 1"}G -bzzzzxxxx11110000ZZZZXXXX11110000zzzzxxx`); +`); // break in the middle of the number scan inst.write( `x11110000zzzzxxxx11110000 {u -#300 -0"}G -b1111000000000000000000000000000000000000000000000000000000000000 {u -#301 -b0000111100000000000000000000000000000000000000000000000000000000 {u -#302 -b0000000011110000000000000000000000000000000000000000000000000000 {u -#303 -b0000000000001111000000000000000000000000000000000000000000000000 {u -#304 -b0000000000000000111100000000000000000000000000000000000000000000 {u -#305 -b0000000000000000000011110000000000000000000000000000000000000000 {u -#306 -b0000000000000000000000001111000000000000000000000000000000000000 {u -#307 -b0000000000000000000000000000111100000000000000000000000000000000 {u -#308 -B0000000000000000000000000000000011110000000000000000000000000000 {u -#309 -b0000000000000000000000000000000000001111000000000000000000000000 {u -#310 -b0000000000000000000000000000000000000000111100000000000000000000 {u -#311 -b0000000000000000000000000000000000000000000011110000000000000000 {u -#312 -b0000000000000000000000000000000000000000000000001111000000000000 {u -#313 -b0000000000000000000000000000000000000000000000000000111100000000 {u -#314 -b0000000000000000000000000000000000000000000000000000000011110000 {u -#315 -b0000000000000000000000000000000000000000000000000000000000001111 {u -#316 -1"}G `); inst.end(); }); diff --git a/vcd_spans.c b/vcd_spans.c index 83f7eb6..c928a92 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -71,6 +71,7 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char napi_env env = state->napi_env; if (state->command == 5) { // $upscope + printf("commandSpan sp goes from %d to %d\n", state->stackPointer, state->stackPointer-1); state->stackPointer -= 1; return 0; } @@ -89,6 +90,7 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char set_property_string("status", "simulation"); emit_lifee("$enddefinitions"); #endif + printf("commandSpan END\n"); return 0; } @@ -99,22 +101,35 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; - // *(endp - 1) = 0; // FIXME NULL termination of ASCII string strcopy(p, endp, state->tmpStr); napi_value obj, stack, top; ASSERT(obj, napi_create_object(env, &obj)) ASSERT(state->info, napi_get_named_property(env, state->info, "stack", &stack)) - ASSERT(top, napi_get_element(env, stack, state->stackPointer, &top)) + + // get the top of the stack in top printf("Got stack %d\n", state->stackPointer); + ASSERT(top, napi_get_element(env, stack, state->stackPointer, &top)) + + // set top.prop to new object + printf("Set top of stack[%d].%s to {}\n", state->stackPointer, (char*)state->tmpStr); ASSERT(top, napi_set_named_property(env, top, state->tmpStr, obj)) - printf("Set ? to %s\n", (char*)state->tmpStr); + + printf("Set top+1 of stack to top %d, %d\n", state->stackPointer, state->stackPointer+1); state->stackPointer += 1; ASSERT(top, napi_set_element(env, stack, state->stackPointer, obj)) #else - state->stackPointer += 1; strcopy(p, endp, state->tmpStr); // load the value into temp string 1 - snprintf(state->tmpStr2, 4096, "stack.%d\n", state->stackPointer); // load the dot-prop into string 2 - set_path_string(state->tmpStr2, state->tmpStr); + snprintf(state->tmpStr2, 4096, "stack.%d.%s", state->stackPointer, state->tmpStr); + new_object_path(state->tmpStr2); + + state->stackPointer += 1; + + snprintf(state->tmpStr2, 4096, "stack.%d", state->stackPointer); + new_object_path(state->tmpStr2); + + // snprintf(state->tmpStr, 4096, "stack.%d", state->stackPointer+1); // load the dot-prop into string 2 + // set_path_to_path(state->tmpStr2, state->tmpStr); + #endif return 0; } @@ -151,8 +166,11 @@ int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char ASSERT(state->info, napi_get_named_property(env, state->info, "varId", &varId)) ASSERT(state->info, napi_set_named_property(env, top, state->tmpStr, varId)) #else - // char *varIdString = - set_property_string("varId", state->tmpStr); + strcopy(p, endp, state->tmpStr); + // set + // info.stack[sp].`tmpStr` = info.varId + snprintf(state->tmpStr2, 4096, "stack.%d.%s", state->stackPointer, state->tmpStr); + set_path_to_path(state->tmpStr2, "varId"); #endif return 0; } diff --git a/wasm_main.cpp b/wasm_main.cpp index 9571c4f..31f9327 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -36,6 +36,14 @@ void set_path_string(const char* name, const char* value) { bound_set_property(name, strlen(name), 2, (int)value, strlen(value)); } +void set_path_to_path(const char* name, const char* value) { + bound_set_property(name, strlen(name), 3, (int)value, strlen(value)); +} + +void new_object_path(const char* name) { + bound_set_property(name, strlen(name), 4, 0, 0); +} + int get_property_int(const char* name) { return bound_get_property(name, strlen(name)); } @@ -121,7 +129,7 @@ int32_t execute( } int setTrigger(const int context, char* triggerString) { - cout << "setTrigger() got " << triggerString << "\n"; + // cout << "setTrigger() got " << triggerString << "\n"; return 0; } diff --git a/wasm_main.hpp b/wasm_main.hpp index d18ffea..c83b02a 100644 --- a/wasm_main.hpp +++ b/wasm_main.hpp @@ -4,5 +4,7 @@ void set_property_int(const char* name, const int value); void set_property_string(const char* name, const char* value); void set_path_string(const char* name, const char* value); +void set_path_to_path(const char* name, const char* value); +void new_object_path(const char* name); int get_property_int(const char* name); void emit_lifee(const char* name); From 2aa3b803f4f621979697de0dee26d76b31acf7eb Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 15:46:25 -0700 Subject: [PATCH 15/34] limited set if signals looks perfect --- vcd_spans.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vcd_spans.c b/vcd_spans.c index c928a92..1c1e96c 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -122,13 +122,18 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig snprintf(state->tmpStr2, 4096, "stack.%d.%s", state->stackPointer, state->tmpStr); new_object_path(state->tmpStr2); + + // snprintf(state->tmpStr2, 4096, "stack.%d", state->stackPointer); state->stackPointer += 1; - snprintf(state->tmpStr2, 4096, "stack.%d", state->stackPointer); - new_object_path(state->tmpStr2); + snprintf(state->tmpStr, 4096, "stack.%d", state->stackPointer); + + + // snprintf(state->tmpStr2, 4096, "stack.%d", state->stackPointer); + // new_object_path(state->tmpStr2); // snprintf(state->tmpStr, 4096, "stack.%d", state->stackPointer+1); // load the dot-prop into string 2 - // set_path_to_path(state->tmpStr2, state->tmpStr); + set_path_to_path(state->tmpStr, state->tmpStr2); #endif return 0; From c95aeaf172eba6660e90628984b998387f2b9820 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 15:51:30 -0700 Subject: [PATCH 16/34] signal seem ok --- vcd_spans.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/vcd_spans.c b/vcd_spans.c index 1c1e96c..dfeda1b 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -119,22 +119,18 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig ASSERT(top, napi_set_element(env, stack, state->stackPointer, obj)) #else strcopy(p, endp, state->tmpStr); // load the value into temp string 1 + + // set stack[sp].`tmpStr` to {} snprintf(state->tmpStr2, 4096, "stack.%d.%s", state->stackPointer, state->tmpStr); new_object_path(state->tmpStr2); - - // snprintf(state->tmpStr2, 4096, "stack.%d", state->stackPointer); + // bump state->stackPointer += 1; + // set stack[sp+1] to the same object as stack[sp].`tmpStr` snprintf(state->tmpStr, 4096, "stack.%d", state->stackPointer); - - // snprintf(state->tmpStr2, 4096, "stack.%d", state->stackPointer); - // new_object_path(state->tmpStr2); - - // snprintf(state->tmpStr, 4096, "stack.%d", state->stackPointer+1); // load the dot-prop into string 2 set_path_to_path(state->tmpStr, state->tmpStr2); - #endif return 0; } From 3a56ab2bcc37bcdf4c1079f8b28445ac1b1882cd Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 18:15:46 -0700 Subject: [PATCH 17/34] close, off by 1 somewhere --- lib/wasmparser.js | 8 ++-- lib/wrapper.js | 43 ++++++++++++++++++--- test/wasmdump.js | 95 ++++++++++++++++++++++++++++++++--------------- vcd_spans.c | 44 ++++++++++++++++------ wasm_main.cpp | 37 ++++++++++++++++-- wasm_main.hpp | 1 + 6 files changed, 175 insertions(+), 53 deletions(-) diff --git a/lib/wasmparser.js b/lib/wasmparser.js index 7f42996..52f4bb6 100644 --- a/lib/wasmparser.js +++ b/lib/wasmparser.js @@ -35,10 +35,12 @@ module.exports = async () => { const cxt = lib.init(lifemit, triemit, info); s._write = function (chunk, encoding, callback) { - console.log('about to write', chunk); + // console.log('about to write', chunk); lib.execute(cxt, lifemit, triemit2, info, chunk); - console.log(util.inspect(info, {showHidden: true, depth : null, colorize: true})); - // console.log(info); + // console.log(util.inspect(info, {showHidden: true, depth : null, colorize: true})); + // console.log(info.stack[0].top); + // console.log(info.stack[1]); + // console.log(info.stack[0].top == info.stack[1]); callback(); }; diff --git a/lib/wrapper.js b/lib/wrapper.js index 22e7463..641dee2 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -8,6 +8,21 @@ function _waitForStart(mod) { }); } +function u8ToBn(u8) { + var hex = []; + // let u8 = Uint8Array.from(buf); + + u8.forEach(function (i) { + var h = i.toString(16); + if (h.length % 2) { h = '0' + h; } + hex.push(h); + }); + + return BigInt('0x' + hex.join('')); +} + + + module.exports = () => { // let state = 0; // idle // let total = 0; @@ -56,6 +71,7 @@ module.exports = () => { let context = -1; + // wasm.addFunction can't be called until after // start finishes bindCallback = () => { @@ -77,17 +93,17 @@ module.exports = () => { // set string to path case 2: dotProp.set(boundInfo, prop, getString(v0, v1)); - console.log(`setting ${prop} to ${getString(v0, v1)}`); + // console.log(`setting ${prop} to ${getString(v0, v1)}`); break; // path to path (any type) case 3: let tmp = dotProp.get(boundInfo, getString(v0, v1)); - console.log(`for ${getString(v0, v1)} got ${tmp}, set to ${prop}`); + // console.log(`for ${getString(v0, v1)} got ${tmp}, set to ${prop}`); dotProp.set(boundInfo, prop, tmp); break; // create empty object at path case 4: - console.log(`${prop} is new {}`); + // console.log(`${prop} is new {}`); dotProp.set(boundInfo, prop, {}); break; @@ -108,9 +124,24 @@ module.exports = () => { ee[0](getString(name, len)); }, 'vii'); - boundEE1 = wasm.addFunction(function(eventName, l0, time, command, value, mask) { - ee[1](getString(eventName, l0), time, command, value, mask); - }, 'viiiiii'); + // const char* name, const size_t len, const uint64_t time, const uint8_t command, const int valueWords, const uint64_t* aValue, const uint64_t* aMask); + // boundEE1 = wasm.addFunction(function(eventName, l0, time, command, valueWords, value, mask) { + boundEE1 = wasm.addFunction(function(eventName, l0, time, command, valueWords, value, mask) { + const name = getString(eventName, l0); + // console.log(`event name`); + // console.log(`event ${name} time ${time} cmd ${command} wrds ${valueWords}`); + + + const view0 = wasm.HEAPU8.subarray(value, value+(valueWords*8)); + const view1 = wasm.HEAPU8.subarray(mask, mask+(valueWords*8)); + + let big_value = u8ToBn(view0); + let big_mask = u8ToBn(view1); + + console.log(big_value.toString(16)); + + ee[1](name, time, command, big_value, big_mask); + }, 'viiiiiii'); }; diff --git a/test/wasmdump.js b/test/wasmdump.js index df63d40..4fb6647 100644 --- a/test/wasmdump.js +++ b/test/wasmdump.js @@ -32,30 +32,30 @@ describe('dump', () => { ); inst.on('finish', () => { - // expect(inst.getTime()).to.eq(316n); - // expect(dump).to.deep.eq([ - // { id: '"}G', time: 100, cmd: 14, value: 0n, mask: 0n }, - // { id: '"}G', time: 200, cmd: 15, value: 1n, mask: 0n }, - // { id: '{u', time: 200, cmd: 19, value: 0xf0f0f0f0f0f0f0f0n, mask: 0xff00ff00ff00ff00n }, - // { id: '"}G', time: 300, cmd: 14, value: 0n, mask: 0n }, - // { id: '{u', time: 300, cmd: 19, value: 0xf000000000000000n, mask: 0n }, - // { id: '{u', time: 301, cmd: 19, value: 0x0f00000000000000n, mask: 0n }, - // { id: '{u', time: 302, cmd: 19, value: 0x00f0000000000000n, mask: 0n }, - // { id: '{u', time: 303, cmd: 19, value: 0x000f000000000000n, mask: 0n }, - // { id: '{u', time: 304, cmd: 19, value: 0x0000f00000000000n, mask: 0n }, - // { id: '{u', time: 305, cmd: 19, value: 0x00000f0000000000n, mask: 0n }, - // { id: '{u', time: 306, cmd: 19, value: 0x000000f000000000n, mask: 0n }, - // { id: '{u', time: 307, cmd: 19, value: 0x0000000f00000000n, mask: 0n }, - // { id: '{u', time: 308, cmd: 20, value: 0x00000000f0000000n, mask: 0n }, - // { id: '{u', time: 309, cmd: 19, value: 0x000000000f000000n, mask: 0n }, - // { id: '{u', time: 310, cmd: 19, value: 0x0000000000f00000n, mask: 0n }, - // { id: '{u', time: 311, cmd: 19, value: 0x00000000000f0000n, mask: 0n }, - // { id: '{u', time: 312, cmd: 19, value: 0x000000000000f000n, mask: 0n }, - // { id: '{u', time: 313, cmd: 19, value: 0x0000000000000f00n, mask: 0n }, - // { id: '{u', time: 314, cmd: 19, value: 0x00000000000000f0n, mask: 0n }, - // { id: '{u', time: 315, cmd: 19, value: 0x000000000000000fn, mask: 0n }, - // { id: '"}G', time: 316, cmd: 15, value: 1n, mask: 0n }, - // ]) + expect(inst.getTime()).to.eq(316n); + expect(dump).to.deep.eq([ + { id: '"}G', time: 100, cmd: 14, value: 0n, mask: 0n }, + { id: '"}G', time: 200, cmd: 15, value: 1n, mask: 0n }, + { id: '{u', time: 200, cmd: 19, value: 0xf0f0f0f0f0f0f0f0n, mask: 0xff00ff00ff00ff00n }, + { id: '"}G', time: 300, cmd: 14, value: 0n, mask: 0n }, + { id: '{u', time: 300, cmd: 19, value: 0xf000000000000000n, mask: 0n }, + { id: '{u', time: 301, cmd: 19, value: 0x0f00000000000000n, mask: 0n }, + { id: '{u', time: 302, cmd: 19, value: 0x00f0000000000000n, mask: 0n }, + { id: '{u', time: 303, cmd: 19, value: 0x000f000000000000n, mask: 0n }, + { id: '{u', time: 304, cmd: 19, value: 0x0000f00000000000n, mask: 0n }, + { id: '{u', time: 305, cmd: 19, value: 0x00000f0000000000n, mask: 0n }, + { id: '{u', time: 306, cmd: 19, value: 0x000000f000000000n, mask: 0n }, + { id: '{u', time: 307, cmd: 19, value: 0x0000000f00000000n, mask: 0n }, + { id: '{u', time: 308, cmd: 20, value: 0x00000000f0000000n, mask: 0n }, + { id: '{u', time: 309, cmd: 19, value: 0x000000000f000000n, mask: 0n }, + { id: '{u', time: 310, cmd: 19, value: 0x0000000000f00000n, mask: 0n }, + { id: '{u', time: 311, cmd: 19, value: 0x00000000000f0000n, mask: 0n }, + { id: '{u', time: 312, cmd: 19, value: 0x000000000000f000n, mask: 0n }, + { id: '{u', time: 313, cmd: 19, value: 0x0000000000000f00n, mask: 0n }, + { id: '{u', time: 314, cmd: 19, value: 0x00000000000000f0n, mask: 0n }, + { id: '{u', time: 315, cmd: 19, value: 0x000000000000000fn, mask: 0n }, + { id: '"}G', time: 316, cmd: 15, value: 1n, mask: 0n }, + ]) // console.log(dump); done(); }); @@ -68,6 +68,12 @@ $timescale 1ns $end $scope module top $end $var wire 1 "}G clock $end + $scope module leaf $end + $var wire 64 {u counter [63:0] $end + $upscope $end + $scope module fruit $end + $var wire 4 u) point [3:0] $end + $upscope $end $upscope $end $enddefinitions $end @@ -75,11 +81,42 @@ $timescale 1ns $end 0"}G #200 1"}G -`); - -// break in the middle of the number scan - - inst.write( `x11110000zzzzxxxx11110000 {u +bzzzzxxxx11110000ZZZZXXXX11110000zzzzxxxx11110000zzzzxxxx11110000 {u +#300 +0"}G +b1111000000000000000000000000000000000000000000000000000000000000 {u +#301 +b0000111100000000000000000000000000000000000000000000000000000000 {u +#302 +b0000000011110000000000000000000000000000000000000000000000000000 {u +#303 +b0000000000001111000000000000000000000000000000000000000000000000 {u +#304 +b0000000000000000111100000000000000000000000000000000000000000000 {u +#305 +b0000000000000000000011110000000000000000000000000000000000000000 {u +#306 +b0000000000000000000000001111000000000000000000000000000000000000 {u +#307 +b0000000000000000000000000000111100000000000000000000000000000000 {u +#308 +B0000000000000000000000000000000011110000000000000000000000000000 {u +#309 +b0000000000000000000000000000000000001111000000000000000000000000 {u +#310 +b0000000000000000000000000000000000000000111100000000000000000000 {u +#311 +b0000000000000000000000000000000000000000000011110000000000000000 {u +#312 +b0000000000000000000000000000000000000000000000001111000000000000 {u +#313 +b0000000000000000000000000000000000000000000000000000111100000000 {u +#314 +b0000000000000000000000000000000000000000000000000000000011110000 {u +#315 +b0000000000000000000000000000000000000000000000000000000000001111 {u +#316 +1"}G `); inst.end(); }); diff --git a/vcd_spans.c b/vcd_spans.c index dfeda1b..3ca324a 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -98,7 +98,7 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char } int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - LOGSPAN; + // LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; strcopy(p, endp, state->tmpStr); @@ -107,14 +107,14 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig ASSERT(state->info, napi_get_named_property(env, state->info, "stack", &stack)) // get the top of the stack in top - printf("Got stack %d\n", state->stackPointer); + // printf("Got stack %d\n", state->stackPointer); ASSERT(top, napi_get_element(env, stack, state->stackPointer, &top)) // set top.prop to new object - printf("Set top of stack[%d].%s to {}\n", state->stackPointer, (char*)state->tmpStr); + // printf("Set top of stack[%d].%s to {}\n", state->stackPointer, (char*)state->tmpStr); ASSERT(top, napi_set_named_property(env, top, state->tmpStr, obj)) - printf("Set top+1 of stack to top %d, %d\n", state->stackPointer, state->stackPointer+1); + // printf("Set top+1 of stack to top %d, %d\n", state->stackPointer, state->stackPointer+1); state->stackPointer += 1; ASSERT(top, napi_set_element(env, stack, state->stackPointer, obj)) #else @@ -136,13 +136,13 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig } int varSizeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - LOGSPAN; + // LOGSPAN; state->size = strtol((const char *)p, (char **)&endp, 10); return 0; } int varIdSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - LOGSPAN; + // LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; napi_value varId; @@ -156,7 +156,7 @@ int varIdSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* } int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - LOGSPAN; + // LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; // *(endp - 1) = 0; // FIXME NULL termination of ASCII string @@ -177,10 +177,18 @@ int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char } int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { + LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; +#endif + + // uint64_t foo = 0x123456789abcdef0; + + // printf(" '%s' ", state->trigger); + const int valueWords = (state->digitCount >> 6) + 1; uint64_t* value = state->value; + // value = &foo; uint64_t* mask = state->mask; if (stringEq((state->trigger), p, endp)) { const uint8_t command = state->command; @@ -192,6 +200,9 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end value[0] = 1; mask[0] = 0; } + printf("valueWords %d %d %d\n", valueWords, (int)command, state->digitCount); + printf("\ntriee %lx\n", *value); +#ifndef VCDWASM napi_value undefined, eventName, aTime, aCommand, aValue, aMask, return_val; ASSERT(undefined, napi_get_undefined(env, &undefined)) ASSERT(eventName, napi_create_string_latin1(env, (char*)p, (endp - p - 1), &eventName)) @@ -199,15 +210,23 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end ASSERT(aCommand, napi_create_int32(env, command, &aCommand)) ASSERT(aValue, napi_create_bigint_words(env, 0, valueWords, value, &aValue)) ASSERT(aMask, napi_create_bigint_words(env, 0, valueWords, mask, &aMask)) + + napi_value* argv[] = {&eventName, &aTime, &aCommand, &aValue, &aMask}; ASSERT(state->triee, napi_call_function(env, undefined, state->triee, 5, *argv, &return_val)) + +#else + + // printf("\ntriee %lx\n", *value); + strcopy(p, endp, state->tmpStr); + emit_triee(state->tmpStr, state->time, command, valueWords, value, mask); +#endif } for (int i = 0; i < valueWords; i++) { value[i] = 0; mask[i] = 0; } state->digitCount = 0; -#endif return 0; } @@ -217,7 +236,6 @@ int onDigit( const unsigned char* endp, int digit ) { -#ifndef VCDWASM unsigned int valueCin = (digit & 1); unsigned int maskCin = ((digit >> 1) & 1); unsigned int valueCout; @@ -234,10 +252,14 @@ int onDigit( maskCout = mask[i] >> 63; mask[i] = (mask[i] << 1) + maskCin; maskCin = maskCout; - + // unsigned char* c = p; + // while(c != endp) { + // puts(c); c++; + // } } + char c = *p; + printf("%c", c); state->digitCount += 1; -#endif return 0; } diff --git a/wasm_main.cpp b/wasm_main.cpp index 31f9327..38a6d45 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include "vcd_parser.h" @@ -8,7 +9,8 @@ using namespace std; /// Typedef used as part of c->js call typedef void externalJsMethodZero(const char* name, const size_t len); -typedef void externalJsMethodOne (const char*, const uint64_t time, const uint8_t command, const int dnc0, const int dnc1); +// typedef void externalJsMethodOne (const char* name, const size_t len, const uint64_t time, const uint8_t command, const int valueWords, const int aValue, const int aMask); +typedef void externalJsMethodOne (const char* name, const size_t len, const int time, const int command, const int valueWords, const int aValue, const int aMask); typedef int externalJsGetProperty(const char* name, const size_t len); typedef void externalJsSetProperty(const char* name, const size_t len, const int type, const int v0, const int v1); @@ -52,6 +54,29 @@ void emit_lifee(const char* name) { externalZero(name, strlen(name)); } +void emit_triee(const char* name, const int64_t time, const int command, const int valueWords, uint64_t* aValue, uint64_t* aMask) { + + // return; + // externalOne( + // "hi" + // ,2 + // ,time + // ,command + // ,0 + // ,0 + // ,0 + // ); + externalOne( + name, + strlen(name), + time, + command, + valueWords, + (int)aValue, + (int)aMask + ); +} + @@ -77,11 +102,12 @@ int init( externalZero = f0; externalOne = f1; - state->lifee = (void*) externalZero; - state->triee = (void*) externalOne; + state->lifee = 0; + state->triee = 0; static char triggerString [4096] = " "; static char tmpStr [4096] = " "; + static char tmpStr2 [4096] = " "; static uint64_t valueBuf [4096] = {}; static uint64_t maskBuf [4096] = {}; @@ -89,6 +115,7 @@ int init( state->reason = "NO REASON"; state->napi_env = 0; state->tmpStr = tmpStr; + state->tmpStr2 = tmpStr2; state->value = valueBuf; state->mask = maskBuf; state->digitCount = 0; @@ -129,6 +156,8 @@ int32_t execute( } int setTrigger(const int context, char* triggerString) { + state->trigger = malloc(strlen(triggerString)); + strcpy((char*)state->trigger, triggerString); // cout << "setTrigger() got " << triggerString << "\n"; return 0; } @@ -165,7 +194,7 @@ int getTime(const int context) { // } int main(void) { - cout << "main()\n"; + // cout << "main()\n"; return 0; } diff --git a/wasm_main.hpp b/wasm_main.hpp index c83b02a..6472298 100644 --- a/wasm_main.hpp +++ b/wasm_main.hpp @@ -8,3 +8,4 @@ void set_path_to_path(const char* name, const char* value); void new_object_path(const char* name); int get_property_int(const char* name); void emit_lifee(const char* name); +void emit_triee(const char* name, const int64_t time, const int command, const int valueWords, uint64_t* aValue, uint64_t* aMask); From 7898fb09c864b58f7383973cae33350e19f8101b Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 18:17:02 -0700 Subject: [PATCH 18/34] testing with this for now --- test/dump.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/dump.js b/test/dump.js index fe3ed9e..64d3bf4 100644 --- a/test/dump.js +++ b/test/dump.js @@ -71,11 +71,7 @@ $timescale 1ns $end 0"}G #200 1"}G -bzzzzxxxx11110000ZZZZXXXX11110000zzzzxxx`); - -// break in the middle of the number scan - - inst.write( `x11110000zzzzxxxx11110000 {u +bzzzzxxxx11110000ZZZZXXXX11110000zzzzxxxx11110000zzzzxxxx11110000 {u #300 0"}G b1111000000000000000000000000000000000000000000000000000000000000 {u From 0d73ffd4f63dc884b4ace08f44d72214f6d16f2b Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 18:42:16 -0700 Subject: [PATCH 19/34] maybe fixed --- lib/wrapper.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/wrapper.js b/lib/wrapper.js index 641dee2..e6472b6 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -18,6 +18,8 @@ function u8ToBn(u8) { hex.push(h); }); + hex.reverse(); + return BigInt('0x' + hex.join('')); } @@ -132,8 +134,8 @@ module.exports = () => { // console.log(`event ${name} time ${time} cmd ${command} wrds ${valueWords}`); - const view0 = wasm.HEAPU8.subarray(value, value+(valueWords*8)); - const view1 = wasm.HEAPU8.subarray(mask, mask+(valueWords*8)); + const view0 = wasm.HEAPU8.subarray(value, value+(valueWords*4)); + const view1 = wasm.HEAPU8.subarray(mask, mask+(valueWords*4)); let big_value = u8ToBn(view0); let big_mask = u8ToBn(view1); From 68a61150b390bf33d32269258e429d2378c32289 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 18:50:58 -0700 Subject: [PATCH 20/34] works except for time --- lib/wasmparser.js | 1 + lib/wrapper.js | 2 +- test/wasmdump.js | 1 + vcd_spans.c | 4 ++-- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/wasmparser.js b/lib/wasmparser.js index 52f4bb6..8001848 100644 --- a/lib/wasmparser.js +++ b/lib/wasmparser.js @@ -47,6 +47,7 @@ module.exports = async () => { s.change = { on: (id, fn) => { triemit2 = triemit; + // console.log(id, fn); triee.on(id, fn); const triggerString = triee.eventNames().join(' ') + ' '; lib.setTrigger(cxt, triggerString); diff --git a/lib/wrapper.js b/lib/wrapper.js index e6472b6..fac5b34 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -140,7 +140,7 @@ module.exports = () => { let big_value = u8ToBn(view0); let big_mask = u8ToBn(view1); - console.log(big_value.toString(16)); + // console.log(big_value.toString(16)); ee[1](name, time, command, big_value, big_mask); }, 'viiiiiii'); diff --git a/test/wasmdump.js b/test/wasmdump.js index 4fb6647..9276d6d 100644 --- a/test/wasmdump.js +++ b/test/wasmdump.js @@ -21,6 +21,7 @@ describe('dump', () => { ['"}G', '{u', 'u)'] // array of all signal ids .map(id => inst.change.on(id, (time, cmd, value, mask) => { + console.log(time, cmd, value, mask); dump.push({ id, time, diff --git a/vcd_spans.c b/vcd_spans.c index 3ca324a..b53849e 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -200,8 +200,8 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end value[0] = 1; mask[0] = 0; } - printf("valueWords %d %d %d\n", valueWords, (int)command, state->digitCount); - printf("\ntriee %lx\n", *value); + // printf("valueWords %d %d %d\n", valueWords, (int)command, state->digitCount); + // printf("\ntriee %llx\n", *value); #ifndef VCDWASM napi_value undefined, eventName, aTime, aCommand, aValue, aMask, return_val; ASSERT(undefined, napi_get_undefined(env, &undefined)) From 2571735fcd7e411a806d421e3dc7df25056af948 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 18:58:16 -0700 Subject: [PATCH 21/34] one passing --- lib/wrapper.js | 5 +---- vcd_spans.c | 22 +++------------------- wasm_main.cpp | 2 +- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/lib/wrapper.js b/lib/wrapper.js index fac5b34..122701a 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -150,9 +150,6 @@ module.exports = () => { return { start, c, - log: () => { - console.log(wasm); - }, init: (cb0, cb1, info) => { boundInfo = info; ee[0] = cb0; @@ -166,7 +163,7 @@ module.exports = () => { return c.setTrigger(ctx, triggerString); }, getTime: (ctx) => { - return c.getTime(ctx); + return BigInt(c.getTime(ctx)); }, time: () => total + start }; diff --git a/vcd_spans.c b/vcd_spans.c index b53849e..8311ac4 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -15,7 +15,7 @@ typedef void* napi_env; // #define LOGSPAN -#define LOGSPAN printf("%s\n", __FUNCTION__); +// #define LOGSPAN printf("%s\n", __FUNCTION__); #define ASSERT(val, expr) \ @@ -67,11 +67,10 @@ int stringEq ( } int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - LOGSPAN; napi_env env = state->napi_env; if (state->command == 5) { // $upscope - printf("commandSpan sp goes from %d to %d\n", state->stackPointer, state->stackPointer-1); + // printf("commandSpan sp goes from %d to %d\n", state->stackPointer, state->stackPointer-1); state->stackPointer -= 1; return 0; } @@ -90,7 +89,7 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char set_property_string("status", "simulation"); emit_lifee("$enddefinitions"); #endif - printf("commandSpan END\n"); + // printf("commandSpan END\n"); return 0; } @@ -98,7 +97,6 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char } int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - // LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; strcopy(p, endp, state->tmpStr); @@ -136,13 +134,11 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig } int varSizeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - // LOGSPAN; state->size = strtol((const char *)p, (char **)&endp, 10); return 0; } int varIdSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - // LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; napi_value varId; @@ -156,7 +152,6 @@ int varIdSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* } int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - // LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; // *(endp - 1) = 0; // FIXME NULL termination of ASCII string @@ -177,15 +172,10 @@ int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char } int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - LOGSPAN; #ifndef VCDWASM napi_env env = state->napi_env; #endif - // uint64_t foo = 0x123456789abcdef0; - - // printf(" '%s' ", state->trigger); - const int valueWords = (state->digitCount >> 6) + 1; uint64_t* value = state->value; // value = &foo; @@ -252,13 +242,7 @@ int onDigit( maskCout = mask[i] >> 63; mask[i] = (mask[i] << 1) + maskCin; maskCin = maskCout; - // unsigned char* c = p; - // while(c != endp) { - // puts(c); c++; - // } } - char c = *p; - printf("%c", c); state->digitCount += 1; return 0; } diff --git a/wasm_main.cpp b/wasm_main.cpp index 38a6d45..27e8266 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -162,7 +162,7 @@ int setTrigger(const int context, char* triggerString) { return 0; } -int getTime(const int context) { +uint64_t getTime(const int context) { return state->time; } From ae8f76a0c012c4e6dcdea5b5c067c09a0e59964e Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 19:05:27 -0700 Subject: [PATCH 22/34] fix warning --- lib/wasmparser.js | 2 +- lib/wrapper.js | 2 +- test/wasmdump.js | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/wasmparser.js b/lib/wasmparser.js index 8001848..bb03862 100644 --- a/lib/wasmparser.js +++ b/lib/wasmparser.js @@ -3,7 +3,7 @@ const stream = require('stream'); const EventEmitter = require('events').EventEmitter; // let lib = require('bindings')('vcd.node'); -const util = require('util'); +// const util = require('util'); module.exports = async () => { diff --git a/lib/wrapper.js b/lib/wrapper.js index 122701a..a10ed50 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -3,7 +3,7 @@ const dotProp = require('dot-prop'); function _waitForStart(mod) { - return new Promise((resolve, reject)=>{ + return new Promise((resolve)=>{ mod.addOnPostRun(resolve); }); } diff --git a/test/wasmdump.js b/test/wasmdump.js index 9276d6d..076f4e2 100644 --- a/test/wasmdump.js +++ b/test/wasmdump.js @@ -21,7 +21,6 @@ describe('dump', () => { ['"}G', '{u', 'u)'] // array of all signal ids .map(id => inst.change.on(id, (time, cmd, value, mask) => { - console.log(time, cmd, value, mask); dump.push({ id, time, @@ -82,7 +81,11 @@ $timescale 1ns $end 0"}G #200 1"}G -bzzzzxxxx11110000ZZZZXXXX11110000zzzzxxxx11110000zzzzxxxx11110000 {u +bzzzzxxxx11110000ZZZZXXXX11110000zzzzxxx`); + +// break in the middle of the number scan + + inst.write( `x11110000zzzzxxxx11110000 {u #300 0"}G b1111000000000000000000000000000000000000000000000000000000000000 {u From 1d5fb9f82f2d0fbbb068a6067b58de3452835de1 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 19:13:08 -0700 Subject: [PATCH 23/34] 2nd passing --- lib/wrapper.js | 7 ++-- test/wasm_events.js | 84 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 test/wasm_events.js diff --git a/lib/wrapper.js b/lib/wrapper.js index a10ed50..1197247 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -23,7 +23,7 @@ function u8ToBn(u8) { return BigInt('0x' + hex.join('')); } - +let startCalled = 0; module.exports = () => { // let state = 0; // idle @@ -45,7 +45,10 @@ module.exports = () => { }; const start = async() => { - await _waitForStart(wasm); + if( !startCalled ) { + await _waitForStart(wasm); + startCalled++; + } bindCWrap(); bindCallback(); } diff --git a/test/wasm_events.js b/test/wasm_events.js new file mode 100644 index 0000000..33eeb26 --- /dev/null +++ b/test/wasm_events.js @@ -0,0 +1,84 @@ +'use strict'; + +const expect = require('chai').expect; +const lib = require('../lib/index.js'); + +describe('wasm events', () => { + let inst; + // return a promise, and mocha will wait until it resolves + before(() => { + const fn = async () => { + inst = await lib.wasmparser(); + }; + return fn(); + }); + + it('$enddefinitions', done => { + + inst.on('$enddefinitions', () => { + expect(inst.info).to.deep.eq({ + status: 'simulation', + varId: 'u)', + wires: { + top: { + clock: '"}G', + fruit: { + point: 'u)' + }, + leaf: { + counter: '{u' + } + } + }, + stack: [{ + top: { + clock: '"}G', + fruit: { + point: 'u)' + }, + leaf: { + counter: '{u' + } + } + }, + { + clock: '"}G', + fruit: { + point: 'u)' + }, + leaf: { + counter: '{u' + } + }, + { + point: 'u)' + }] + }); + }); + expect(inst.write(` +$version Generated by VerilatedVcd $end +$date Wed Sep 18 22:59:07 2019 + $end +$timescale 1ns $end + + $scope module top $end + $var wire 1 "}G clock $end + $scope module leaf $end + $var wire 64 {u counter [63:0] $end + $upscope $end + $scope module fruit $end + $var wire 4 u) point [3:0] $end + $upscope $end + $upscope $end + + $enddefinitions $end +` + )).to.eq(true); + + done(); + }); + + +}); + +/* eslint-env mocha */ From 604c2994d4adf0b22fc7b7a1cb9c06d84ac171bf Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 19:14:33 -0700 Subject: [PATCH 24/34] rename --- test/{wasmdump.js => wasm_dump.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{wasmdump.js => wasm_dump.js} (100%) diff --git a/test/wasmdump.js b/test/wasm_dump.js similarity index 100% rename from test/wasmdump.js rename to test/wasm_dump.js From ba7bef4322e7ee16892631207c39d1a8086dcd6d Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 19:16:07 -0700 Subject: [PATCH 25/34] try this --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e61a249..0316fe7 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "testlint": "eslint bin lib && nyc -r=text -r=lcov mocha", - "test": "eslint bin lib; nyc -r=text -r=lcov mocha", + "test": "nyc -r=text -r=lcov mocha", "testonly": "nyc -r=text -r=lcov mocha", "watch": "mocha --watch", "install": "node bin/build.js", From 05b8f6e83376fa67370691f0ae9ac7cee991717a Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 19:21:39 -0700 Subject: [PATCH 26/34] another --- test/wasm_basic.js | 121 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 test/wasm_basic.js diff --git a/test/wasm_basic.js b/test/wasm_basic.js new file mode 100644 index 0000000..57a4d61 --- /dev/null +++ b/test/wasm_basic.js @@ -0,0 +1,121 @@ +'use strict'; + +const expect = require('chai').expect; +const lib = require('../lib/index.js'); + +describe('basic', () => { + + it('typeof vcd', done => { + expect(lib.wasmparser).to.be.an('function'); + done(); + }); + + it('typeof vcd instance', done => { + expect(lib.wasmparser()).to.be.an('promise'); + done(); + }); + + it('fail: foo bar', async () => { + const inst = await lib.wasmparser(); + expect(inst.write(Buffer.from(' foo bar ???'))).to.eq(true); + expect(inst.info).to.deep.eq({ + stack: [{}], + status: 'declaration', + wires: {} + }); + }); + + it('$comment', async () => { + const inst = await lib.wasmparser(); + expect(inst.write(Buffer.from( + ' \n $comment some text $end $comment more text $end ???' + ))).to.eq(true); + expect(inst.info).to.deep.eq({ + stack: [{}], + status: 'declaration', + wires: {} + }); + }); + + it('$version', async () => { + const inst = await lib.wasmparser(); + expect(inst.write(` +$version Generated by VerilatedVcd $end +$date Wed Sep 18 22:59:07 2019 + $end +$timescale 1ns $end + + $scope module top $end + $var wire 1 "}G clock $end + $scope module leaf $end + $var wire 64 {u counter [63:0] $end + $upscope $end + $scope module fruit $end + $var wire 4 u) point [3:0] $end + $upscope $end + $upscope $end + + $enddefinitions $end +` +)).to.eq(true); + + expect(inst.write(` + +#1 +0"}G +#2 +1"}G +#300 +0"}G +b1111000000000000 {u +#301 +b0000111100000000 {u +#302 +b0000000011110000 {u +#303 +b0000000000001111 {u +` +)).to.eq(true); + + expect(inst.info).to.deep.eq({ + status: 'simulation', + varId: 'u)', + wires: { + top: { + clock: '"}G', + fruit: { + point: 'u)' + }, + leaf: { + counter: '{u' + } + } + }, + stack: [{ + top: { + clock: '"}G', + fruit: { + point: 'u)' + }, + leaf: { + counter: '{u' + } + } + }, + { + clock: '"}G', + fruit: { + point: 'u)' + }, + leaf: { + counter: '{u' + } + }, + { + point: 'u)' + }] + }); + }); +}); + +/* eslint-env mocha */ From 2f2f7115c34eafea6f6491eb2d902643f4e046f5 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 19:22:15 -0700 Subject: [PATCH 27/34] remove failing test --- test/wasm.js | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) delete mode 100644 test/wasm.js diff --git a/test/wasm.js b/test/wasm.js deleted file mode 100644 index f55b022..0000000 --- a/test/wasm.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; - -const expect = require('chai').expect; -// const lib = require('../lib/index.js'); - -const dut = require('../lib/index.js'); - - -describe('basic', () => { - - let wrapper; - - // return a promise from before and mocha - // will wait for it - before(() => { - wrapper = dut.wrapper(); - return wrapper.start(); - }); - - - it('wasm basic', done => { - - console.log("test"); - - const wires = {}; - const info = {stack: [wires], wires: wires}; - - - wrapper.init({},{},info); - - console.log(info); - - - // wrapper.c.execute('hello world'); - - wrapper.execute(); - - // expect(info.foo).to.equal(10); - // console.log(wrapper.log()); - - - // expect(lib.parser).to.be.an('function'); - done(); - }); - - -}); - From b1720ade242ae3727c343cb8dcd5adba454bc19b Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 27 Sep 2020 19:25:20 -0700 Subject: [PATCH 28/34] rename --- test/wasm_basic.js | 2 +- test/wasm_dump.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/wasm_basic.js b/test/wasm_basic.js index 57a4d61..1d6355d 100644 --- a/test/wasm_basic.js +++ b/test/wasm_basic.js @@ -3,7 +3,7 @@ const expect = require('chai').expect; const lib = require('../lib/index.js'); -describe('basic', () => { +describe('wasm basic', () => { it('typeof vcd', done => { expect(lib.wasmparser).to.be.an('function'); diff --git a/test/wasm_dump.js b/test/wasm_dump.js index 076f4e2..afb9c81 100644 --- a/test/wasm_dump.js +++ b/test/wasm_dump.js @@ -3,7 +3,7 @@ const expect = require('chai').expect; const lib = require('../lib/index.js'); -describe('dump', () => { +describe('wasm dump', () => { let inst; From 5ce8cb1388374071dbf9b19464b57cbe2148c754 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 28 Sep 2020 00:22:29 -0700 Subject: [PATCH 29/34] fix part of any --- lib/wrapper.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/wrapper.js b/lib/wrapper.js index 1197247..d5581de 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -159,7 +159,10 @@ module.exports = () => { ee[1] = cb1; context = c.init(boundEE0,boundEE1,boundSet,boundGet); }, - execute: (ctx, lifemit, triemit, info, chunk) => { + execute: (ctx, cb0, cb1, info, chunk) => { + boundInfo = info; + ee[0] = cb0; + ee[1] = cb1; c.execute(ctx,boundEE0,boundEE1,boundSet,boundGet,chunk.toString()); }, setTrigger: (ctx, triggerString) => { From bf4f4980800c0ed0efb6264bcf34471d0d31e6a0 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 28 Sep 2020 00:24:33 -0700 Subject: [PATCH 30/34] All tests passing --- lib/wrapper.js | 4 +-- test/wasm_any.js | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 test/wasm_any.js diff --git a/lib/wrapper.js b/lib/wrapper.js index d5581de..3934bc3 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -137,8 +137,8 @@ module.exports = () => { // console.log(`event ${name} time ${time} cmd ${command} wrds ${valueWords}`); - const view0 = wasm.HEAPU8.subarray(value, value+(valueWords*4)); - const view1 = wasm.HEAPU8.subarray(mask, mask+(valueWords*4)); + const view0 = wasm.HEAPU8.subarray(value, value+(valueWords*8)); + const view1 = wasm.HEAPU8.subarray(mask, mask+(valueWords*8)); let big_value = u8ToBn(view0); let big_mask = u8ToBn(view1); diff --git a/test/wasm_any.js b/test/wasm_any.js new file mode 100644 index 0000000..40552ed --- /dev/null +++ b/test/wasm_any.js @@ -0,0 +1,76 @@ +'use strict'; + +const expect = require('chai').expect; +const lib = require('../lib/index.js'); + +describe('wasm any', () => { + + let inst; + + // return a promise, and mocha will wait until it resolves + before(() => { + const fn = async () => { + inst = await lib.wasmparser(); + }; + return fn(); + }); + + it('simple any', (done) => { + const dump = []; + inst.change.any((id, time, cmd, value, mask) => { + dump.push({ + id, time, cmd, value, mask + }); + }); + + inst.on('finish', () => { + expect(dump).to.deep.eq([ + { id: 'ABC', time: 100, cmd: 14, value: 0n, mask: 0n }, + { id: '123', time: 200, cmd: 15, value: 1n, mask: 0n }, + { id: 'XyZ', time: 300, cmd: 14, value: 0n, mask: 0n }, + { id: '64b', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '128b', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '256b', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '512b', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '1024b', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '2048b', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '4096b', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '8192b', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '16kb', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '32kb', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '64kb', time: 400, cmd: 19, value: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan, mask: 0n }, + { id: '68b', time: 400, cmd: 19, value: 0xf0ff00000000000000fn, mask: 0xff00000000000000000n }, + { id: 'foo', time: 400, cmd: 15, value: 1n, mask: 0n } + ]) + // console.log(dump); + done(); + }); + + inst.write(`\ +$enddefinitions $end +#100 +0ABC +#200 +1123 +#300 +0XyZ +#400 +b1010101010101010101010101010101010101010101010101010101010101010 64b +b10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 128b +b1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 256b +b10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 512b +b1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 1024b +b10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 2048b +b1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 4096b +b10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 8192b +b1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 16kb +b10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 32kb +b1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 64kb +bzzzzxxxx11111111000000000000000000000000000000000000000000000000000000001111 68b +1foo +`); + inst.end(); + }); +}); + +/* eslint-env mocha */ From 3a039a619fdece5e01b9e34df4bc0c94616ea4ce Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 28 Sep 2020 00:28:50 -0700 Subject: [PATCH 31/34] instructions --- docs/Emscripten.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/Emscripten.md b/docs/Emscripten.md index 243e007..f6fcf75 100644 --- a/docs/Emscripten.md +++ b/docs/Emscripten.md @@ -13,3 +13,17 @@ I added a `Makefile` to the project. A few key things here. * Doing this will also compile the c code with `O0` * Any c functions you want to access from javascript must be added to `EXPORT_STRING` * When you add them, you must add a `_` prefix + +# Install +I tested this project with `1.39.11` + +```bash +git clone https://github.com/emscripten-core/emsdk.git +cd emsdk/ +git pull +./emsdk install latest +./emsdk activate latest +source ./emsdk_env.sh +``` + +See https://emscripten.org/docs/getting_started/downloads.html From d184681eaeb515107a92b65849ab4a71c85b4b1c Mon Sep 17 00:00:00 2001 From: Ben Morse Date: Mon, 28 Sep 2020 00:38:59 -0700 Subject: [PATCH 32/34] * undo changes not related to my changes --- lib/parser.js | 9 +++++---- package.json | 3 +-- vcd_spans.c | 13 +------------ 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/lib/parser.js b/lib/parser.js index f4b3874..8bc0dee 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -11,7 +11,8 @@ module.exports = () => { const s = new stream.Writable(); - + // const lifee = new EventEmitter(); + // gets called by c with 1 argument, a number const lifemit = s.emit.bind(s); @@ -19,10 +20,10 @@ module.exports = () => { // gets called by c with 5 arguments // string eventName - // number state->time + // bigint state->time // int command - // int state->value - // int state->mask + // bigint state->value + // bigint state->mask const triemit = triee.emit.bind(triee); let triemit2 = triemit; diff --git a/package.json b/package.json index 0316fe7..94c0611 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,7 @@ "description": "Value Change Dump (VCD) parser", "main": "lib/index.js", "scripts": { - "testlint": "eslint bin lib && nyc -r=text -r=lcov mocha", - "test": "nyc -r=text -r=lcov mocha", + "test": "eslint bin lib && nyc -r=text -r=lcov mocha", "testonly": "nyc -r=text -r=lcov mocha", "watch": "mocha --watch", "install": "node bin/build.js", diff --git a/vcd_spans.c b/vcd_spans.c index 8311ac4..94b1433 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -70,7 +70,6 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char napi_env env = state->napi_env; if (state->command == 5) { // $upscope - // printf("commandSpan sp goes from %d to %d\n", state->stackPointer, state->stackPointer-1); state->stackPointer -= 1; return 0; } @@ -89,7 +88,6 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char set_property_string("status", "simulation"); emit_lifee("$enddefinitions"); #endif - // printf("commandSpan END\n"); return 0; } @@ -105,14 +103,11 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig ASSERT(state->info, napi_get_named_property(env, state->info, "stack", &stack)) // get the top of the stack in top - // printf("Got stack %d\n", state->stackPointer); ASSERT(top, napi_get_element(env, stack, state->stackPointer, &top)) // set top.prop to new object - // printf("Set top of stack[%d].%s to {}\n", state->stackPointer, (char*)state->tmpStr); ASSERT(top, napi_set_named_property(env, top, state->tmpStr, obj)) - // printf("Set top+1 of stack to top %d, %d\n", state->stackPointer, state->stackPointer+1); state->stackPointer += 1; ASSERT(top, napi_set_element(env, stack, state->stackPointer, obj)) #else @@ -178,7 +173,6 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end const int valueWords = (state->digitCount >> 6) + 1; uint64_t* value = state->value; - // value = &foo; uint64_t* mask = state->mask; if (stringEq((state->trigger), p, endp)) { const uint8_t command = state->command; @@ -190,8 +184,6 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end value[0] = 1; mask[0] = 0; } - // printf("valueWords %d %d %d\n", valueWords, (int)command, state->digitCount); - // printf("\ntriee %llx\n", *value); #ifndef VCDWASM napi_value undefined, eventName, aTime, aCommand, aValue, aMask, return_val; ASSERT(undefined, napi_get_undefined(env, &undefined)) @@ -200,14 +192,10 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end ASSERT(aCommand, napi_create_int32(env, command, &aCommand)) ASSERT(aValue, napi_create_bigint_words(env, 0, valueWords, value, &aValue)) ASSERT(aMask, napi_create_bigint_words(env, 0, valueWords, mask, &aMask)) - - napi_value* argv[] = {&eventName, &aTime, &aCommand, &aValue, &aMask}; ASSERT(state->triee, napi_call_function(env, undefined, state->triee, 5, *argv, &return_val)) #else - - // printf("\ntriee %lx\n", *value); strcopy(p, endp, state->tmpStr); emit_triee(state->tmpStr, state->time, command, valueWords, value, mask); #endif @@ -242,6 +230,7 @@ int onDigit( maskCout = mask[i] >> 63; mask[i] = (mask[i] << 1) + maskCin; maskCin = maskCout; + } state->digitCount += 1; return 0; From 6bcb3afb386f5a2e3de6495c99d9acc21263ed75 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 28 Sep 2020 00:45:56 -0700 Subject: [PATCH 33/34] fix linting, add to readme --- README.md | 1 + lib/wrapper.js | 41 ++++++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index eec6ccf..f97ca61 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Install ``` npm i vcd-stream +make wasm ``` Require diff --git a/lib/wrapper.js b/lib/wrapper.js index 3934bc3..db06330 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -1,5 +1,7 @@ 'use strict'; +/* global BigInt */ + const dotProp = require('dot-prop'); function _waitForStart(mod) { @@ -51,18 +53,18 @@ module.exports = () => { } bindCWrap(); bindCallback(); - } + }; // gets a string from a c heap pointer and length - const getString = (name,len) => { - const view = wasm.HEAPU8.subarray(name, name+len); + const getString = (name, len) => { + const view = wasm.HEAPU8.subarray(name, name+len); - let string = ''; - for (let i = 0; i < len; i++) { - string += String.fromCharCode(view[i]); - } - return string; - } + let string = ''; + for (let i = 0; i < len; i++) { + string += String.fromCharCode(view[i]); + } + return string; + }; let boundInfo; @@ -83,6 +85,7 @@ module.exports = () => { boundSet = wasm.addFunction(function(name, len, type, v0, v1) { let prop = getString(name, len); + let tmp; switch(type) { // set number @@ -102,7 +105,7 @@ module.exports = () => { break; // path to path (any type) case 3: - let tmp = dotProp.get(boundInfo, getString(v0, v1)); + tmp = dotProp.get(boundInfo, getString(v0, v1)); // console.log(`for ${getString(v0, v1)} got ${tmp}, set to ${prop}`); dotProp.set(boundInfo, prop, tmp); break; @@ -121,7 +124,7 @@ module.exports = () => { boundGet = wasm.addFunction(function(name, len) { let prop = getString(name, len); - return 42; + return prop; }, 'iii'); @@ -140,12 +143,12 @@ module.exports = () => { const view0 = wasm.HEAPU8.subarray(value, value+(valueWords*8)); const view1 = wasm.HEAPU8.subarray(mask, mask+(valueWords*8)); - let big_value = u8ToBn(view0); - let big_mask = u8ToBn(view1); + let bigValue = u8ToBn(view0); + let bigMask = u8ToBn(view1); - // console.log(big_value.toString(16)); + // console.log(bigValue.toString(16)); - ee[1](name, time, command, big_value, big_mask); + ee[1](name, time, command, bigValue, bigMask); }, 'viiiiiii'); }; @@ -157,20 +160,20 @@ module.exports = () => { boundInfo = info; ee[0] = cb0; ee[1] = cb1; - context = c.init(boundEE0,boundEE1,boundSet,boundGet); + context = c.init(boundEE0, boundEE1, boundSet, boundGet); + return context; }, execute: (ctx, cb0, cb1, info, chunk) => { boundInfo = info; ee[0] = cb0; ee[1] = cb1; - c.execute(ctx,boundEE0,boundEE1,boundSet,boundGet,chunk.toString()); + c.execute(ctx, boundEE0, boundEE1, boundSet, boundGet, chunk.toString()); }, setTrigger: (ctx, triggerString) => { return c.setTrigger(ctx, triggerString); }, getTime: (ctx) => { return BigInt(c.getTime(ctx)); - }, - time: () => total + start + } }; }; From d8626754c16d7b878baf907c8573cef963ec2a8e Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 28 Sep 2020 00:46:48 -0700 Subject: [PATCH 34/34] fix paths in gitignore --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6ee2fa6..2b3c2e1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,8 @@ /build /coverage /node_modules -package-lock.json +/package-lock.json *.dot /tmp -vcd_parser.* +/vcd_parser.* /out