15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This is part of jsdifflib v1.0. <http://snowtide.com/jsdifflib>
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (c) 2007, Snowtide Informatics Systems, Inc.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * All rights reserved.
6197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without modification,
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are permitted provided that the following conditions are met:
9197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    * Redistributions of source code must retain the above copyright notice, this
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * list of conditions and the following disclaimer.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    * Redistributions in binary form must reproduce the above copyright notice,
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this list of conditions and the following disclaimer in the documentation
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * and/or other materials provided with the distribution.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    * Neither the name of the Snowtide Informatics Systems nor the names of its
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from this
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * software without specific prior written permission.
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) **/
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* Author: Chas Emerick <cemerick@snowtide.com> */
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* taken from https://github.com/cemerick/jsdifflib */
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)__whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true};
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)difflib = {
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    defaultJunkFunction: function (c) {
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return __whitespace.hasOwnProperty(c);
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    },
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); },
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    stringAsLines: function (str) {
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var lfpos = str.indexOf("\n");
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var crpos = str.indexOf("\r");
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var linebreak = ((lfpos > -1 && crpos > -1) || crpos < 0) ? "\n" : "\r";
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var lines = str.split(linebreak);
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (var i = 0; i < lines.length; i++) {
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            lines[i] = difflib.stripLinebreaks(lines[i]);
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return lines;
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    },
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // iteration-based reduce implementation
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    __reduce: function (func, list, initial) {
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (initial != null) {
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var value = initial;
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var idx = 0;
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (list) {
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var value = list[0];
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var idx = 1;
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return null;
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (; idx < list.length; idx++) {
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            value = func(value, list[idx]);
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return value;
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    },
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // comparison function for sorting lists of numeric tuples
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    __ntuplecomp: function (a, b) {
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var mlen = Math.max(a.length, b.length);
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (var i = 0; i < mlen; i++) {
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (a[i] < b[i]) return -1;
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (a[i] > b[i]) return 1;
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return a.length == b.length ? 0 : (a.length < b.length ? -1 : 1);
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    },
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    __calculate_ratio: function (matches, length) {
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return length ? 2.0 * matches / length : 1.0;
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    },
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // returns a function that returns true if a key passed to the returned function
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // is in the dict (js object) provided to this function; replaces being able to
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // carry around dict.has_key in python...
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    __isindict: function (dict) {
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return function (key) { return dict.hasOwnProperty(key); };
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    },
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // replacement for python's dict.get function -- need easy default values
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    __dictget: function (dict, key, defaultValue) {
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return dict.hasOwnProperty(key) ? dict[key] : defaultValue;
99197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    },
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SequenceMatcher: function (a, b, isjunk) {
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.set_seqs = function (a, b) {
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.set_seq1(a);
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.set_seq2(b);
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.set_seq1 = function (a) {
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (a == this.a) return;
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.a = a;
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.matching_blocks = this.opcodes = null;
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.set_seq2 = function (b) {
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (b == this.b) return;
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.b = b;
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.matching_blocks = this.opcodes = this.fullbcount = null;
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.__chain_b();
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.__chain_b = function () {
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var b = this.b;
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var n = b.length;
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var b2j = this.b2j = {};
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var populardict = {};
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (var i = 0; i < b.length; i++) {
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                var elt = b[i];
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (b2j.hasOwnProperty(elt)) {
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    var indices = b2j[elt];
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (n >= 200 && indices.length * 100 > n) {
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        populardict[elt] = 1;
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        delete b2j[elt];
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    } else {
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        indices.push(i);
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                } else {
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    b2j[elt] = [i];
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (var elt in populardict) {
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (populardict.hasOwnProperty(elt)) {
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    delete b2j[elt];
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var isjunk = this.isjunk;
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var junkdict = {};
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isjunk) {
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (var elt in populardict) {
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (populardict.hasOwnProperty(elt) && isjunk(elt)) {
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        junkdict[elt] = 1;
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        delete populardict[elt];
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (var elt in b2j) {
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (b2j.hasOwnProperty(elt) && isjunk(elt)) {
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        junkdict[elt] = 1;
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        delete b2j[elt];
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.isbjunk = difflib.__isindict(junkdict);
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.isbpopular = difflib.__isindict(populardict);
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.find_longest_match = function (alo, ahi, blo, bhi) {
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var a = this.a;
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var b = this.b;
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var b2j = this.b2j;
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var isbjunk = this.isbjunk;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var besti = alo;
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var bestj = blo;
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var bestsize = 0;
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var j = null;
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var j2len = {};
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var nothing = [];
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (var i = alo; i < ahi; i++) {
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                var newj2len = {};
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                var jdict = difflib.__dictget(b2j, a[i], nothing);
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (var jkey in jdict) {
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (jdict.hasOwnProperty(jkey)) {
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        j = jdict[jkey];
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        if (j < blo) continue;
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        if (j >= bhi) break;
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1;
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        if (k > bestsize) {
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            besti = i - k + 1;
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            bestj = j - k + 1;
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            bestsize = k;
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        }
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                j2len = newj2len;
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (besti > alo && bestj > blo && !isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                besti--;
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bestj--;
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bestsize++;
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (besti + bestsize < ahi && bestj + bestsize < bhi &&
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    !isbjunk(b[bestj + bestsize]) &&
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    a[besti + bestsize] == b[bestj + bestsize]) {
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bestsize++;
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (besti > alo && bestj > blo && isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                besti--;
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bestj--;
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bestsize++;
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) &&
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    a[besti + bestsize] == b[bestj + bestsize]) {
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bestsize++;
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return [besti, bestj, bestsize];
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.get_matching_blocks = function () {
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (this.matching_blocks != null) return this.matching_blocks;
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var la = this.a.length;
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var lb = this.b.length;
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var queue = [[0, la, 0, lb]];
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var matching_blocks = [];
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var alo, ahi, blo, bhi, qi, i, j, k, x;
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (queue.length) {
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                qi = queue.pop();
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                alo = qi[0];
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ahi = qi[1];
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                blo = qi[2];
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bhi = qi[3];
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                x = this.find_longest_match(alo, ahi, blo, bhi);
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                i = x[0];
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                j = x[1];
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                k = x[2];
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (k) {
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    matching_blocks.push(x);
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (alo < i && blo < j)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        queue.push([alo, i, blo, j]);
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (i+k < ahi && j+k < bhi)
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        queue.push([i + k, ahi, j + k, bhi]);
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            matching_blocks.sort(difflib.__ntuplecomp);
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var i1 = j1 = k1 = block = 0;
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var non_adjacent = [];
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (var idx in matching_blocks) {
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (matching_blocks.hasOwnProperty(idx)) {
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    block = matching_blocks[idx];
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    i2 = block[0];
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    j2 = block[1];
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    k2 = block[2];
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (i1 + k1 == i2 && j1 + k1 == j2) {
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        k1 += k2;
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    } else {
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        if (k1) non_adjacent.push([i1, j1, k1]);
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        i1 = i2;
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        j1 = j2;
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        k1 = k2;
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (k1) non_adjacent.push([i1, j1, k1]);
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            non_adjacent.push([la, lb, 0]);
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.matching_blocks = non_adjacent;
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return this.matching_blocks;
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.get_opcodes = function () {
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (this.opcodes != null) return this.opcodes;
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var i = 0;
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var j = 0;
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var answer = [];
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            this.opcodes = answer;
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var block, ai, bj, size, tag;
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var blocks = this.get_matching_blocks();
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (var idx in blocks) {
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (blocks.hasOwnProperty(idx)) {
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    block = blocks[idx];
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    ai = block[0];
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    bj = block[1];
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    size = block[2];
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    tag = '';
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (i < ai && j < bj) {
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        tag = 'replace';
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    } else if (i < ai) {
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        tag = 'delete';
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    } else if (j < bj) {
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        tag = 'insert';
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (tag) answer.push([tag, i, ai, j, bj]);
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    i = ai + size;
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    j = bj + size;
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (size) answer.push(['equal', ai, i, bj, j]);
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return answer;
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // this is a generator function in the python lib, which of course is not supported in javascript
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // the reimplementation builds up the grouped opcodes into a list in their entirety and returns that.
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.get_grouped_opcodes = function (n) {
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!n) n = 3;
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var codes = this.get_opcodes();
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!codes) codes = [["equal", 0, 1, 0, 1]];
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var code, tag, i1, i2, j1, j2;
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (codes[0][0] == 'equal') {
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                code = codes[0];
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                tag = code[0];
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                i1 = code[1];
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                i2 = code[2];
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                j1 = code[3];
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                j2 = code[4];
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                codes[0] = [tag, Math.max(i1, i2 - n), i2, Math.max(j1, j2 - n), j2];
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (codes[codes.length - 1][0] == 'equal') {
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                code = codes[codes.length - 1];
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                tag = code[0];
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                i1 = code[1];
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                i2 = code[2];
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                j1 = code[3];
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                j2 = code[4];
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                codes[codes.length - 1] = [tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)];
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var nn = n + n;
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var groups = [];
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (var idx in codes) {
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (codes.hasOwnProperty(idx)) {
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    code = codes[idx];
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    tag = code[0];
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    i1 = code[1];
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    i2 = code[2];
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    j1 = code[3];
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    j2 = code[4];
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (tag == 'equal' && i2 - i1 > nn) {
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        groups.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]);
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        i1 = Math.max(i1, i2-n);
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        j1 = Math.max(j1, j2-n);
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    groups.push([tag, i1, i2, j1, j2]);
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (groups && groups[groups.length - 1][0] == 'equal') groups.pop();
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return groups;
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.ratio = function () {
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            matches = difflib.__reduce(
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            function (sum, triple) { return sum + triple[triple.length - 1]; },
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            this.get_matching_blocks(), 0);
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.quick_ratio = function () {
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var fullbcount, elt;
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (this.fullbcount == null) {
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                this.fullbcount = fullbcount = {};
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (var i = 0; i < this.b.length; i++) {
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    elt = this.b[i];
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    fullbcount[elt] = difflib.__dictget(fullbcount, elt, 0) + 1;
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            fullbcount = this.fullbcount;
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var avail = {};
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var availhas = difflib.__isindict(avail);
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var matches = numb = 0;
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (var i = 0; i < this.a.length; i++) {
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                elt = this.a[i];
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (availhas(elt)) {
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    numb = avail[elt];
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                } else {
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    numb = difflib.__dictget(fullbcount, elt, 0);
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                avail[elt] = numb - 1;
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (numb > 0) matches++;
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.real_quick_ratio = function () {
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var la = this.a.length;
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var lb = this.b.length;
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return _calculate_ratio(Math.min(la, lb), la + lb);
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.isjunk = isjunk ? isjunk : difflib.defaultJunkFunction;
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.a = this.b = null;
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        this.set_seqs(a, b);
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
410