diff --git a/html/index.html b/html/index.html
index 083cc70..b265dad 100644
--- a/html/index.html
+++ b/html/index.html
@@ -128,6 +128,12 @@
+
diff --git a/html/index.js b/html/index.js
index 446053e..2c1e722 100644
--- a/html/index.js
+++ b/html/index.js
@@ -175,10 +175,21 @@ function changePreset() {
}
async function clickCount() {
+ if (document.getElementById('bltFile').files.length === 0) {
+ return;
+ }
+
// Read BLT file
let bltFile = document.getElementById('bltFile').files[0];
let text = await bltFile.text();
+ // Read CON file (if applicable)
+ let conText = null;
+ if (document.getElementById('conFile').files.length > 0) {
+ let conFile = document.getElementById('conFile').files[0];
+ conText = await conFile.text();
+ }
+
// Initialise table rows
let tblResults = document.getElementById('result');
tblResults.innerHTML = '';
@@ -333,7 +344,7 @@ async function clickCount() {
elTd = document.createElement('td');
elTd.classList.add('count');
- if (countCard.state === py.pyRCV2.model.CandidateState.WITHDRAWN || countCard.state === py.pyRCV2.model.CandidateState.EXCLUDED || countCard.state === py.pyRCV2.model.CandidateState.EXCLUDING) {
+ if (countCard.state === py.pyRCV2.model.CandidateState.WITHDRAWN || countCard.state === py.pyRCV2.model.CandidateState.EXCLUDED || countCard.state === py.pyRCV2.model.CandidateState.EXCLUDING || countCard.state === py.pyRCV2.model.CandidateState.DOOMED) {
elTd.classList.add('excluded');
} else if (countCard.state === py.pyRCV2.model.CandidateState.ELECTED || countCard.state === py.pyRCV2.model.CandidateState.PROVISIONALLY_ELECTED || countCard.state === py.pyRCV2.model.CandidateState.DISTRIBUTING_SURPLUS) {
elTd.classList.add('elected');
@@ -358,7 +369,7 @@ async function clickCount() {
} else if (countCard.state === py.pyRCV2.model.CandidateState.EXCLUDED) {
elTd.classList.add('excluded');
elTd.innerText = 'Ex';
- } else if (countCard.state === py.pyRCV2.model.CandidateState.EXCLUDING) {
+ } else if (countCard.state === py.pyRCV2.model.CandidateState.EXCLUDING || countCard.state === py.pyRCV2.model.CandidateState.DOOMED) {
elTd.classList.add('excluded');
elTd.innerHTML = ppVotes(countCard.votes);
} else {
@@ -503,7 +514,8 @@ async function clickCount() {
'round_weights': document.getElementById('chkRoundWeights').checked ? parseInt(document.getElementById('txtRoundWeights').value) : null,
},
'seed': document.getElementById('txtSeed').value,
- 'data': text
+ 'election': text,
+ 'constraints': conText,
}
});
diff --git a/html/worker.js b/html/worker.js
index ab6beaa..68a4893 100644
--- a/html/worker.js
+++ b/html/worker.js
@@ -1,6 +1,6 @@
/*
pyRCV2: Preferential vote counting
- Copyright © 2020 Lee Yingtong Li (RunasSudo)
+ Copyright © 2020–2021 Lee Yingtong Li (RunasSudo)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@@ -40,12 +40,18 @@ onmessage = function(evt) {
ppDPs = evt.data.data.ppDPs;
- let election = py.pyRCV2.blt.readBLT(evt.data.data.data);
+ // Load election
+ let election = py.pyRCV2.blt.readBLT(evt.data.data.election);
let total_ballots = py.pyRCV2.numbers.Num(0);
for (let b of election.ballots) {
total_ballots.__iadd__(b.value);
}
+ // Load constraints (if applicable)
+ if (evt.data.data.constraints) {
+ election.constraints = py.pyRCV2.con.readCON(evt.data.data.constraints, election);
+ }
+
// Create counter
if (evt.data.data.transfers === 'uig') {
counter = py.pyRCV2.method.gregory.UIGSTVCounter(election, evt.data.data.options);
diff --git a/pyRCV2/transcrypt.py b/pyRCV2/transcrypt.py
index 34e0471..e24fb31 100644
--- a/pyRCV2/transcrypt.py
+++ b/pyRCV2/transcrypt.py
@@ -15,6 +15,8 @@
# along with this program. If not, see .
import pyRCV2.blt
+import pyRCV2.con
+import pyRCV2.constraints
import pyRCV2.model
import pyRCV2.method, pyRCV2.method.base_stv, pyRCV2.method.gregory, pyRCV2.method.meek
import pyRCV2.numbers