#
-# fiddle section
+# fiddle/wasm section
#
fiddle_dir = ext/fiddle
fiddle_dir_abs = $(TOP)/$(fiddle_dir)
fiddle_module_js = $(fiddle_dir)/fiddle-module.js
fiddle_generated = $(fiddle_module_js) \
$(fiddle_dir)/fiddle-module.wasm
-clean-fiddle:
- rm -f $(fiddle_generated)
-clean: clean-fiddle
+sqlite3_wasm_js = $(fiddle_dir)/sqlite3.js
+sqlite3_wasm = $(fiddle_dir)/sqlite3.wasm
+sqlite3_wasm_generated = $(sqlite3_wasm) $(sqlite3_wasm_js)
+clean-wasm:
+ rm -f $(fiddle_generated) $(sqlite3_wasm_generated)
+clean: clean-wasm
#emcc_opt = -O0
#emcc_opt = -O1
#emcc_opt = -O2
#emcc_opt = -O3
-# --js-library $(fiddle_dir)/_dummylib.js
emcc_opt = -Oz
-emcc_flags = $(emcc_opt) $(SHELL_OPT) \
- -sEXPORTED_RUNTIME_METHODS=@$(fiddle_dir_abs)/EXPORTED_RUNTIME_METHODS \
- -sEXPORTED_FUNCTIONS=@$(fiddle_dir_abs)/EXPORTED_FUNCTIONS \
- $(fiddle_cflags)
-# $(fiddle_cflags) is intended to be passed to make via the CLI in
-# order to override, e.g., -Ox for one-off builds.
+emcc_flags = $(emcc_opt) -I. $(SHELL_OPT)
$(fiddle_module_js): Makefile sqlite3.c shell.c \
- $(fiddle_dir)/EXPORTED_RUNTIME_METHODS $(fiddle_dir)/EXPORTED_FUNCTIONS
- emcc -o $@ $(emcc_flags) sqlite3.c shell.c
+ $(fiddle_dir)/EXPORTED_RUNTIME_METHODS $(fiddle_dir)/EXPORTED_FUNCTIONS.fiddle
+ emcc -o $@ $(emcc_flags) \
+ -sEXPORTED_RUNTIME_METHODS=@$(fiddle_dir_abs)/EXPORTED_RUNTIME_METHODS \
+ -sEXPORTED_FUNCTIONS=@$(fiddle_dir_abs)/EXPORTED_FUNCTIONS.fiddle \
+ sqlite3.c shell.c
+$(sqlite3_wasm_js): Makefile sqlite3.c \
+ $(fiddle_dir)/EXPORTED_RUNTIME_METHODS $(fiddle_dir)/EXPORTED_FUNCTIONS.sqlite3
+ emcc -o $@ $(emcc_flags) \
+ -sEXPORTED_RUNTIME_METHODS=@$(fiddle_dir_abs)/EXPORTED_RUNTIME_METHODS \
+ -sEXPORTED_FUNCTIONS=@$(fiddle_dir_abs)/EXPORTED_FUNCTIONS.sqlite3 \
+ --no-entry \
+ sqlite3.c
fiddle: $(fiddle_module_js)
+sqlite3-wasm: $(sqlite3_wasm_js)
+wasm: fiddle sqlite3-wasm
--- /dev/null
+_sqlite3_bind_blob
+_sqlite3_bind_double
+_sqlite3_bind_int
+_sqlite3_bind_parameter_index
+_sqlite3_bind_text
+_sqlite3_changes
+_sqlite3_clear_bindings
+_sqlite3_close_v2
+_sqlite3_column_blob
+_sqlite3_column_bytes
+_sqlite3_column_count
+_sqlite3_column_count
+_sqlite3_column_double
+_sqlite3_column_name
+_sqlite3_column_text
+_sqlite3_column_type
+_sqlite3_create_function_v2
+_sqlite3_data_count
+_sqlite3_errmsg
+_sqlite3_exec
+_sqlite3_finalize
+_sqlite3_libversion
+_sqlite3_open
+_sqlite3_prepare_v2
+_sqlite3_prepare_v2
+_sqlite3_reset
+_sqlite3_result_blob
+_sqlite3_result_double
+_sqlite3_result_error
+_sqlite3_result_int
+_sqlite3_result_null
+_sqlite3_result_text
+_sqlite3_sourceid
+_sqlite3_step
+_sqlite3_value_blob
+_sqlite3_value_bytes
+_sqlite3_value_double
+_sqlite3_value_text
+_sqlite3_value_type
# This makefile exists primarily to simplify/speed up development from
# emacs. It is not part of the canonical build process.
default:
- make -C ../.. fiddle -e emcc_opt=-O0
+ make -C ../.. wasm -e emcc_opt=-O0
clean:
- make -C ../../ clean-fiddle
+ make -C ../../ clean-wasm
+
+push-demo:
+ rsync -va fiddle*.js fiddle*.wasm fiddle.html *.css wh2:www/wh/sqlite3/.
--- /dev/null
+/* emcscript-related styling, used during the module load/intialization processes... */
+.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
+div.emscripten { text-align: center; }
+div.emscripten_border { border: 1px solid black; }
+#module-spinner { overflow: visible; }
+#module-spinner > * {
+ margin-top: 1em;
+}
+.spinner {
+ height: 50px;
+ width: 50px;
+ margin: 0px auto;
+ animation: rotation 0.8s linear infinite;
+ border-left: 10px solid rgb(0,150,240);
+ border-right: 10px solid rgb(0,150,240);
+ border-bottom: 10px solid rgb(0,150,240);
+ border-top: 10px solid rgb(100,0,200);
+ border-radius: 100%;
+ background-color: rgb(200,100,250);
+}
+@keyframes rotation {
+ from {transform: rotate(0deg);}
+ to {transform: rotate(360deg);}
+}
sqlite3 wasm module and offers access to the db via the Worker
message-passing interface.
+ Forewarning: this API is still very much Under Construction and
+ subject to any number of changes as experience reveals what those
+ need to be.
+
Because we can have only a single message handler, as opposed to an
arbitrary number of discrete event listeners like with DOM elements,
we have to define a lower-level message API. Messages abstractly
Noting that it happens in Firefox as well as Chrome. Harmless but
annoying.
*/
-
-const thisWorker = self;
+"use strict";
const wMsg = (type,data)=>postMessage({type, data});
self.onerror = function(/*message, source, lineno, colno, error*/) {
const err = arguments[4];
if(err && 'ExitStatus'==err.name){
+ /* This is relevant for the sqlite3 shell binding but not the
+ lower-level binding. */
Module._isDead = true;
Module.printErr("FATAL ERROR:", err.message);
Module.printErr("Restarting the app requires reloading the page.");
- //const taOutput = document.querySelector('#output');
- //if(taOutput) taOutput.classList.add('error');
+ wMsg('error', err);
}
Module.setStatus('Exception thrown, see JavaScript console');
Module.setStatus = function(text) {
- if(text) console.error('[post-exception status] ' + text);
+ console.error('[post-exception status]', text);
};
};
self.Module.setStatus('Downloading...');
importScripts('fiddle-module.js')
/* loads the wasm module and notifies, via Module.setStatus() and
- Module.onRuntimeInitialized(), when it's done loading. */;
+ Module.onRuntimeInitialized(), when it's done loading. The latter
+ is called _before_ the final call to Module.setStatus(). */;
Module["onRuntimeInitialized"] = function onRuntimeInitialized() {
- /* For reference: sql.js does essentially everything we want and
- it solves much of the wasm-related voodoo, but we'll need a
- different structure because we want the db connection to run in
- a worker thread and feed data back into the main
- thread. Regardless of those differences, it makes a great point
- of reference:
-
- https://github.com/sql-js/sql.js
-
- Some of the specific design goals here:
-
- - Bind a low-level sqlite3 API which is close to the native one in
- terms of usage.
-
- - Create a higher-level one, more akin to sql.js and
- node.js-style implementations. This one would speak directly
- to the low-level API. This API could be used by clients who
- import the low-level API directly into their main thread
- (which we don't want to recommend but also don't want to
- outright forbid).
-
- - Create a second higher-level one which speaks to the
- low-level API via worker messages. This one would be intended
- for use in the main thread, talking to the low-level UI via
- worker messages. Because workers have only a single message
- channel, some acrobatics will be needed here to feed async
- work results back into client-side callbacks (as those
- callbacks cannot simply be passed to the worker). Exactly
- what those acrobatics should look like is not yet entirely
- clear and much experimentation is pending.
-
- */
- console.log('onRuntimeInitialized');
-
- /*
- TODO: create the main sqlite API here. We'll have another for
- use in the main thread which will talk to this one via worker
- messages.
- */
-
-}
+ //console.log('onRuntimeInitialized');
+ //wMsg('module','done');
+};
<title>sqlite3 fiddle</title>
<!--script src="jqterm/jqterm-bundle.min.js"></script>
<link rel="stylesheet" href="jqterm/jquery.terminal.min.css"/-->
+ <link rel="stylesheet" href="emscripten.css"/>
<style>
- /* emcscript-related styling, used during the intialization phase... */
- .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
- div.emscripten { text-align: center; }
- div.emscripten_border { border: 1px solid black; }
- #module-spinner { overflow: visible; }
- #module-spinner > * {
- margin-top: 1em;
- }
- .spinner {
- height: 50px;
- width: 50px;
- margin: 0px auto;
- animation: rotation 0.8s linear infinite;
- border-left: 10px solid rgb(0,150,240);
- border-right: 10px solid rgb(0,150,240);
- border-bottom: 10px solid rgb(0,150,240);
- border-top: 10px solid rgb(100,0,200);
- border-radius: 100%;
- background-color: rgb(200,100,250);
- }
- @keyframes rotation {
- from {transform: rotate(0deg);}
- to {transform: rotate(360deg);}
- }
-
/* The following styles are for app-level use. */
-
textarea {
font-family: monospace;
flex: 1 1 auto;
filter: invert(100%);
flex: 10 1 auto;
}
- /*#main-wrapper:not(.side-by-side) .ta-wrapper.input {
- flex: 5 1 auto;
- }*/
.button-bar {
display: flex;
justify-content: center;
</head>
<body>
<header id='titlebar'><span>sqlite3 fiddle</span></header>
+ <!-- emscripten bits -->
<figure id="module-spinner">
<div class="spinner"></div>
<div class='center'><strong>Initializing app...</strong></div>
<div class="emscripten" id="module-status">Downloading...</div>
<div class="emscripten">
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
- </div>
+ </div><!-- /emscripten bits -->
<div id='view-terminal' class='app-view hidden initially-hidden'>
This is a placeholder for a terminal-like view.
progressElement.remove();
if(!text) spinnerElement.remove();
}
- if(text) statusElement.innerText = text;
- else {
+ if(text){
+ statusElement.innerText = text;
+ }else{
console.log("Finalizing status.");
statusElement.remove();
SF.clearMsgHandlers('module');
--- /dev/null
+/*
+ 2022-05-22
+
+ The author disclaims copyright to this source code. In place of a
+ legal notice, here is a blessing:
+
+ * May you do good and not evil.
+ * May you find forgiveness for yourself and forgive others.
+ * May you share freely, never taking more than you give.
+
+ ***********************************************************************
+
+ This file is intended to be loaded after loading
+ sqlite3-module.wasm. It sets one of any number of potential
+ bindings using that API, this one as closely matching the C-native
+ API as is feasible.
+
+ Note that this file is not named sqlite3.js because that file gets
+ generated by emscripten as the JS-glue counterpart of sqlite3.wasm.
+
+ The API gets installed as self.sqlite3, where self is expected to be
+ either the global window or Worker object.
+
+ Because using this API properly requires some degree of WASM-related
+ magic, it is not recommended that this API be used as-is in
+ client-level code, but instead is intended to be used as a basis for
+ APIs more appropriate for high-level client code.
+
+ This file installs namespace.sqlite3, where namespace is `self`,
+ meaning either the global window or worker, depending on where this
+ is loaded from.
+*/
+(function(namespace){
+ /* For reference: sql.js does essentially everything we want and
+ it solves much of the wasm-related voodoo, but we'll need a
+ different structure because we want the db connection to run in
+ a worker thread and feed data back into the main
+ thread. Regardless of those differences, it makes a great point
+ of reference:
+
+ https://github.com/sql-js/sql.js
+
+ Some of the specific design goals here:
+
+ - Bind a low-level sqlite3 API which is close to the native one
+ in terms of usage.
+
+ - Create a higher-level one, more akin to sql.js and
+ node.js-style implementations. This one would speak directly
+ to the low-level API. This API could be used by clients who
+ import the low-level API directly into their main thread
+ (which we don't want to recommend but also don't want to
+ outright forbid).
+
+ - Create a second higher-level one which speaks to the
+ low-level API via worker messages. This one would be intended
+ for use in the main thread, talking to the low-level UI via
+ worker messages. Because workers have only a single message
+ channel, some acrobatics will be needed here to feed async
+ work results back into client-side callbacks (as those
+ callbacks cannot simply be passed to the worker). Exactly
+ what those acrobatics should look like is not yet entirely
+ clear and much experimentation is pending.
+ */
+
+ /**
+ Set up the main sqlite3 binding API here, mimicking the C API as
+ closely as we can.
+
+ Attribution: though not a direct copy/paste, much of what
+ follows is strongly influenced by the sql.js implementation.
+ */
+ const api = {
+ /* It is important that the following integer values match
+ those from the C code. Ideally we could fetch them from the
+ C API, e.g., in the form of a JSON object, but getting that
+ JSON string constructed within our current confised is
+ currently not worth the effort. */
+ /* Minimum subset of sqlite result codes we'll need. */
+ SQLITE_OK: 0,
+ SQLITE_ROW: 100,
+ SQLITE_DONE: 101,
+ /* sqlite data types */
+ SQLITE_INTEGER: 1,
+ SQLITE_FLOAT: 2,
+ SQLITE_TEXT: 3,
+ SQLITE_BLOB: 4,
+ /* sqlite encodings, used for creating UDFs, noting that we
+ will only support UTF8. */
+ SQLITE_UTF8: 1
+ };
+ const cwrap = Module.cwrap;
+ [/* C-side functions to bind. Each entry is an array with 3 or 4
+ elements:
+
+ ["c-side name",
+ "result type" (cwrap() syntax),
+ [arg types in cwrap() syntax]
+ ]
+
+ If it has 4 elements, the first one is an alternate name to
+ use for the JS-side binding. That's required when overloading
+ a binding for two different uses.
+ */
+ ["sqlite3_open", "number", ["string", "number"]],
+ ["sqlite3_close_v2", "number", ["number"]],
+ ["sqlite3_exec", "number",
+ ["number", "string", "number", "number", "number"]],
+ ["sqlite3_changes", "number", ["number"]],
+ ["sqlite3_prepare_v2", "number", ["number", "string", "number", "number", "number"]],
+ ["sqlite3_prepare_v2_sqlptr",
+ /* Impl which requires that the 2nd argument be a pointer to
+ the SQL, instead of a string. This is used for cases where
+ we require a non-NULL value for the final argument. We may
+ or may not need this, depending on how our higher-level
+ API shapes up, but this code's spiritual guide (sql.js)
+ uses it we we'll include it. */
+ "sqlite3_prepare_v2",
+ "number", ["number", "number", "number", "number", "number"]],
+ ["sqlite3_bind_text","number",["number", "number", "number", "number", "number"]],
+ ["sqlite3_bind_blob","number",["number", "number", "number", "number", "number"]],
+ ["sqlite3_bind_double","number",["number", "number", "number"]],
+ ["sqlite3_bind_int","number",["number", "number", "number"]],
+ ["sqlite3_bind_parameter_index","number",["number", "string"]],
+ ["sqlite3_step", "number", ["number"]],
+ ["sqlite3_errmsg", "string", ["number"]],
+ ["sqlite3_column_count","number",["number"]],
+ ["sqlite3_data_count", "number", ["number"]],
+ ["sqlite3_column_count", "number", ["number"]],
+ ["sqlite3_column_double","number",["number", "number"]],
+ ["sqlite3_column_text","string",["number", "number"]],
+ ["sqlite3_column_blob","number", ["number", "number"]],
+ ["sqlite3_column_bytes","number",["number", "number"]],
+ ["sqlite3_column_type","number",["number", "number"]],
+ ["sqlite3_column_name","string",["number", "number"]],
+ ["sqlite3_reset", "number", ["number"]],
+ ["sqlite3_clear_bindings","number",["number"]],
+ ["sqlite3_finalize", "number", ["number"]],
+ ["sqlite3_create_function_v2", "number",
+ ["number", "string", "number", "number",
+ "number", "number", "number", "number",
+ "number"]],
+ ["sqlite3_value_type", "number", ["number"]],
+ ["sqlite3_value_bytes","number",["number"]],
+ ["sqlite3_value_text", "string", ["number"]],
+ ["sqlite3_value_blob", "number", ["number"]],
+ ["sqlite3_value_double","number",["number"]],
+ ["sqlite3_result_double",null,["number", "number"]],
+ ["sqlite3_result_null",null,["number"]],
+ ["sqlite3_result_text",null,["number", "string", "number", "number"]],
+ ["sqlite3_result_blob",null,["number", "number", "number", "number"]],
+ ["sqlite3_result_int",null,["number", "number"]],
+ ["sqlite3_result_error",null,["number", "string", "number"]],
+ ["sqlite3_libversion", "string", []],
+ ["sqlite3_sourceid", "string", []]
+ //["sqlite3_sql", "string", ["number"]],
+ //["sqlite3_normalized_sql", "string", ["number"]]
+ ].forEach(function(e){
+ const a = Array.prototype.slice.call(e);
+ const k = (4==a.length) ? a.shift() : a[0];
+ api[k] = cwrap.apply(this, a);
+ });
+ //console.debug("libversion =",api.sqlite3_libversion());
+ namespace.sqlite3 = api;
+})(self/*worker or window*/);
--- /dev/null
+/*
+ 2022-05-22
+
+ The author disclaims copyright to this source code. In place of a
+ legal notice, here is a blessing:
+
+ * May you do good and not evil.
+ * May you find forgiveness for yourself and forgive others.
+ * May you share freely, never taking more than you give.
+
+ ***********************************************************************
+
+ This file contains bootstrapping code used by various test scripts
+ which live in this file's directory.
+*/
+(function(){
+ /* querySelectorAll() proxy */
+ const EAll = function(/*[element=document,] cssSelector*/){
+ return (arguments.length>1 ? arguments[0] : document)
+ .querySelectorAll(arguments[arguments.length-1]);
+ };
+ /* querySelector() proxy */
+ const E = function(/*[element=document,] cssSelector*/){
+ return (arguments.length>1 ? arguments[0] : document)
+ .querySelector(arguments[arguments.length-1]);
+ };
+
+ const statusElement = E('#module-status');
+ const progressElement = E('#module-progress');
+ const spinnerElement = E('#module-spinner');
+
+ self.Module = {
+ /* ^^^ cannot declare that const because fiddle-module.js
+ (auto-generated) includes a decl for it and runs in this scope. */
+ preRun: [],
+ postRun: [],
+ //onRuntimeInitialized: function(){},
+ print: function(){
+ console.log(Array.prototype.slice.call(arguments));
+ },
+ printErr: function(){
+ console.error(Array.prototype.slice.call(arguments));
+ },
+ setStatus: function f(text){
+ if(!f.last) f.last = { time: Date.now(), text: '' };
+ if(text === f.last.text) return;
+ const m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
+ const now = Date.now();
+ if(m && now - f.last.time < 30) return; // if this is a progress update, skip it if too soon
+ f.last.time = now;
+ f.last.text = text;
+ if(m) {
+ text = m[1];
+ progressElement.value = parseInt(m[2])*100;
+ progressElement.max = parseInt(m[4])*100;
+ progressElement.hidden = false;
+ spinnerElement.hidden = false;
+ } else {
+ progressElement.remove();
+ if(!text) spinnerElement.remove();
+ }
+ if(text) statusElement.innerText = text;
+ else statusElement.remove();
+ },
+ totalDependencies: 0,
+ monitorRunDependencies: function(left) {
+ this.totalDependencies = Math.max(this.totalDependencies, left);
+ this.setStatus(left
+ ? ('Preparing... (' + (this.totalDependencies-left)
+ + '/' + this.totalDependencies + ')')
+ : 'All downloads complete.');
+ },
+ /* Loads sqlite3-api.js and calls the given callback (if
+ provided), passing it the sqlite3 module. Whether this is
+ synchronous or async depends on whether it's run in the
+ main thread or a worker.*/
+ loadSqliteAPI: function(callback){
+ const theScript = 'sqlite3-api.js';
+ if(self.importScripts){/*worker*/
+ importScripts(theScript);
+ if(callback) callback(self.sqlite3);
+ }else{/*main thread*/
+ new Promise((resolve, reject) => {
+ const script = document.createElement('script');
+ document.body.appendChild(script);
+ script.onload = resolve;
+ script.onerror = reject;
+ script.async = true;
+ script.src = theScript;
+ }).then(() => {
+ if(callback) callback(self.sqlite3);
+ });
+ }
+ }
+ };
+})(self/*window or worker*/);
--- /dev/null
+<!doctype html>
+<html lang="en-us">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <link rel="stylesheet" href="emscripten.css"/>
+ <title>sqlite3-api.js tests</title>
+ <style></style>
+ </head>
+ <body>
+ <header id='titlebar'><span>sqlite3-api.js tests</span></header>
+ <!-- emscripten bits -->
+ <figure id="module-spinner">
+ <div class="spinner"></div>
+ <div class='center'><strong>Initializing app...</strong></div>
+ <div class='center'>
+ On a slow internet connection this may take a moment. If this
+ message displays for "a long time", intialization may have
+ failed and the JavaScript console may contain clues as to why.
+ </div>
+ </figure>
+ <div class="emscripten" id="module-status">Downloading...</div>
+ <div class="emscripten">
+ <progress value="0" max="100" id="module-progress" hidden='1'></progress>
+ </div><!-- /emscripten bits -->
+ <div>Everything on this page happens in the dev console.</div>
+ <script src="testing-common.js"></script>
+ <script src="testing1.js"></script>
+ <script src="sqlite3.js"></script>
+ </body>
+</html>
--- /dev/null
+/*
+ 2022-05-22
+
+ The author disclaims copyright to this source code. In place of a
+ legal notice, here is a blessing:
+
+ * May you do good and not evil.
+ * May you find forgiveness for yourself and forgive others.
+ * May you share freely, never taking more than you give.
+
+ ***********************************************************************
+
+ A basic test script for sqlite3-api.js.
+*/
+(function(){
+ self.Module.onRuntimeInitialized = function(){
+ console.log("Loading sqlite3-api.js...");
+ self.Module.loadSqliteAPI(function(S){
+ console.log("Loaded module:",S.sqlite3_libversion(),
+ S.sqlite3_sourceid());
+ });
+ };
+})(self/*window or worker*/);
-C Minor\sfiddle-related\sbuild\srestructuring\sto\ssupport\supcoming\sdevelopment\sof\sthe\sC-style\swasm\ssqlite3\sinterface,\splus\ssome\scommentary\sabout\sthe\splans\sand\sgoals\sfor\sthat.
-D 2022-05-21T21:13:44.686
+C Build\srefactoring\sfor\sthe\sfiddle/wasm\sbits.\sSet\sup\swasm\sbinding\sof\sa\schunk\sof\sthe\score\sC\sAPI\sand\sadded\ssome\sinfastructure\sfor\screating\stest\spages\sfor\sit.
+D 2022-05-22T00:27:19.296
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
-F Makefile.in 62df7206650987c76f15b2e1c23830976858892815b9fc4d283c850628e0c724
+F Makefile.in a192a8de35ba61e6d695a3bd430b021e7cbf7ea473497028540801fe7b659282
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
F Makefile.msc b28a8a7a977e7312f6859f560348e1eb110c21bd6cf9fab0d16537c0a514eef3
F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e
F ext/expert/sqlite3expert.c 6ca30d73b9ed75bd56d6e0d7f2c962d2affaa72c505458619d0ff5d9cdfac204
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
-F ext/fiddle/EXPORTED_FUNCTIONS 487fc7c83d45c48326f731c89162ed17ab15767e5efede8999d7d6c6e2d04c0f
+F ext/fiddle/EXPORTED_FUNCTIONS.fiddle 487fc7c83d45c48326f731c89162ed17ab15767e5efede8999d7d6c6e2d04c0f w ext/fiddle/EXPORTED_FUNCTIONS
+F ext/fiddle/EXPORTED_FUNCTIONS.sqlite3 4b06e6c3ce8c8389274079ffb6b441ffff1a55e32a448cf21ce1da45a16c8a01
F ext/fiddle/EXPORTED_RUNTIME_METHODS 91d5dcb0168ee056fa1a340cb8ab3c23d922622f8dad39d28919dd8af2b3ade0
-F ext/fiddle/Makefile b2904d52c10a7c984cfab95c54fb85f33aa8a6b2653faf1527d08ce57114be46
-F ext/fiddle/fiddle-worker.js 28e50e021e84aaedf4cbdb2ef25e4183f1e5be8da7996a50fc8d0b5ed78fa00a
-F ext/fiddle/fiddle.html f536878dbaa35ba4d9ad8c87dda7fb2ea5502fdd824577d83b2265d65b8ca4d1
-F ext/fiddle/fiddle.js 9361d451845ac3c97c5492c24c8d18b8fe2deff07741462bdf8e39c375be25b2
+F ext/fiddle/Makefile 9277c73e208b9c8093659256c9f07409c877e366480c7c22ec545ee345451d95
+F ext/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
+F ext/fiddle/fiddle-worker.js c22557b641b47fa1473d3465a4e69fe06b8b09b924955805a4202c8201ddc429
+F ext/fiddle/fiddle.html 657c6c3f860c322fba3c69fa4f7a1209e2d2ce44b4bc65a3e154e3a97c047a7c
+F ext/fiddle/fiddle.js f9c79164428e96a5909532f18a8bc8f8c8ec4f738bfc09ad3d2a532c2400f9f0
F ext/fiddle/index.md d9c1c308d8074341bc3b11d1d39073cd77754cb3ca9aeb949f23fdd8323d81cf
+F ext/fiddle/sqlite3-api.js d3c6da99850e146e50dc42039ac027e5d9b08b9f24eb22b31d1982c49930ee7c
+F ext/fiddle/testing-common.js 37b014758db7e5e74278e37dc712ced2fc9b40d0617f5ed0b8b64a6bd9c0a45d
+F ext/fiddle/testing1.html 68cec1b1c8646a071717e5979f22e4268e6d36d96ba13ad68333351acdbcf1d1
+F ext/fiddle/testing1.js 0fb900c768b06c2ec3922ab522f721a68b0756d200e3c66602461f45910bcd39
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 5ff3326856bc190cee15a5fca5ded89aacc4bf931a8df98726a872b310e2a4fc
-R 3ab23a2e617cc2f177067d0130c7a41f
+P c7cfdd4c3682659352642461d3307bf8180703b121ec1802ba5881f8e1ef9809
+R d89e623e1614875df0e3a579152a2be9
U stephan
-Z 0792a8e58fb57cfdbc5dcb7974589bd6
+Z fd89698a5fe01334529b2fb407d595a1
# Remove this line to create a well-formed Fossil manifest.
-c7cfdd4c3682659352642461d3307bf8180703b121ec1802ba5881f8e1ef9809
\ No newline at end of file
+dea098b64eb95c395b346ebcae687afe42b7d21df48833527808c02226300a66
\ No newline at end of file