importScripts('opentally.js'); var wasm = wasm_bindgen; async function initWasm() { await wasm_bindgen('opentally_bg.wasm'); postMessage({'type': 'init', 'version': wasm.version()}); } initWasm(); var numbers, election, opts, state, stageNum; onmessage = function(evt) { if (evt.data.type === 'countElection') { numbers = 'DynNum'; if (evt.data.numbers === 'fixed') { wasm.dynnum_set_kind(wasm.NumKind.Fixed); wasm.fixed_set_dps(evt.data.decimals); } else if (evt.data.numbers === 'gfixed') { wasm.dynnum_set_kind(wasm.NumKind.GuardedFixed); wasm.gfixed_set_dps(evt.data.decimals); } else if (evt.data.numbers === 'float64') { wasm.dynnum_set_kind(wasm.NumKind.NativeFloat64); } else if (evt.data.numbers === 'rational') { wasm.dynnum_set_kind(wasm.NumKind.Rational); } else { throw 'Unknown --numbers'; } // Init election election = wasm['election_from_blt_' + numbers](evt.data.bltData); if (evt.data.normaliseBallots) { wasm['election_normalise_ballots_' + numbers](election); } // Init constraints if applicable if (evt.data.conData) { wasm['election_load_constraints_' + numbers](election, evt.data.conData); } // Init STV options opts = wasm.STVOptions.new.apply(null, evt.data.optsStr); // Validate options opts.validate(); // Describe count postMessage({'type': 'describeCount', 'content': wasm['describe_count_' + numbers](evt.data.bltPath, election, opts)}); // Init results table postMessage({'type': 'initResultsTable', 'content': wasm['init_results_table_' + numbers](election, opts)}); // Step election state = wasm['CountState' + numbers].new(election); wasm['count_init_' + numbers](state, opts); postMessage({'type': 'updateResultsTable', 'result': wasm['update_results_table_' + numbers](1, state, opts)}); postMessage({'type': 'updateStageComments', 'comment': wasm['update_stage_comments_' + numbers](state)}); stageNum = 2; resume_count(); } else if (evt.data.type == 'userInput') { user_input_buffer = evt.data.response; resume_count(); } } function resume_count() { for (;; stageNum++) { try { let isDone = wasm['count_one_stage_' + numbers](state, opts); if (isDone) { break; } } catch (ex) { if (ex === "RequireInput") { return; } else { throw ex; } } postMessage({'type': 'updateResultsTable', 'result': wasm['update_results_table_' + numbers](stageNum, state, opts)}); postMessage({'type': 'updateStageComments', 'comment': wasm['update_stage_comments_' + numbers](state)}); } postMessage({'type': 'updateResultsTable', 'result': wasm['finalise_results_table_' + numbers](state)}); postMessage({'type': 'finalResultSummary', 'summary': wasm['final_result_summary_' + numbers](state, opts)}); } var user_input_buffer = null; function read_user_input_buffer(message) { if (user_input_buffer === null) { postMessage({'type': 'requireInput', 'message': message}); return null; } else { let user_input = user_input_buffer; user_input_buffer = null; return user_input; } }