+function share(index,string){
+ this.index=index;
+ this.codes=string.split(' ');
+ this.codeCount=function(){return this.codes.length};
+ this.code=function(i){return this.codes[i];};
+ this.pick=function(i){return [this.index,this.codes[i]]};
+ this.string=function(){
+ return 'Share '+this.index+': '+this.codes.join(' / ');
+ };
+}
+
+function collect(){
+ var divs=document.getElementsByClassName('share');
+ var shares=[],lastValue,div,inputs,num;
+ for (i=0; i<divs.length; i++){
+ div=divs[i];
+ inputs = div.getElementsByTagName('input');
+ num=0;
+ for (var j=0; j<inputs.length;j++){
+ var input = inputs[j];
+ if (input.className == 'num') {
+ num=input.value;
+ } else {
+ lastValue=input.value;
+ if (num>0 && lastValue!='') shares[i]=new share(num,lastValue);
+ }
+ }
+ }
+ if (lastValue!=''){
+ var clone=div.cloneNode(true);
+ var inputs=clone.getElementsByTagName('input');
+ for (var j=0; j<inputs.length; j++) inputs[j].value='';
+ div.parentNode.appendChild(clone);
+ }
+ return shares;
+}
+
+function gcdD(a,b) {
+ if (b == 0) return [a, 1, 0];
+ else {
+ var n = Math.floor(a/b), c = a % b, r = gcdD(b,c);
+ return [r[0], r[2], r[1]-r[2]*n];
+ }
+}
+
+function modInverse(k) {
+ k = k % prime;
+ var r = (k < 0) ? -gcdD(prime,-k)[2] : gcdD(prime,k)[2];
+ return (prime + r) % prime;
+}
+
+function join(shares) {
+ var accum, count, formula, startposition, nextposition, value, numerator, denominator;
+ for(formula = accum = 0; formula < shares.length; formula++) {
+ for(count = 0, numerator = denominator = 1; count < shares.length; count++) {
+ if(formula == count) continue; // If not the same value
+ startposition = shares[formula][0];
+ nextposition = shares[count][0];
+ numerator = (numerator * -nextposition) % prime;
+ denominator = (denominator * (startposition - nextposition)) % prime;
+ }
+ value = shares[formula][1];
+ accum = (prime + accum + (value * numerator * modInverse(denominator))) % prime;
+ }
+ return accum;
+}
+
+function decode(){
+ var shares=collect(); // fetch shares
+ var codeCount=null;
+ for (var i=0; i<shares.length; i++) codeCount=(codeCount==null)?shares[i].codeCount():Math.min(shares[i].codeCount(),codeCount);
+ var ascii=document.getElementById('ascii');
+ ascii.innerHTML='ascii: ';
+ result.innerHTML='Passphrase: ';
+ for (codeIndex=0; codeIndex<codeCount; codeIndex++){
+ var shareSet=[];
+ for (var i=0; i<shares.length; i++){
+ shareSet[i]=shares[i].pick(codeIndex);
+ }
+ var r=join(shareSet);
+ ascii.innerHTML += r+' ';
+ result.innerHTML+= String.fromCharCode(r);
+ }
+}
+
+function secret2numbers(s){