696
return undefined;
697
}
699
>
// Find the max matching word position for each pattern position
700
>
// NOTE: the min matching word position was filled in above, in the `isPatternInWord` call
701
>
_fillInMaxWordMatchPos(patternLen, wordLen, patternStart, wordStart, patternLow, wordLow);
702
>
703
>
let row: number = 1;
704
>
let column: number = 1;
705
>
let patternPos = patternStart;
706
>
let wordPos = wordStart;
707
>
708
>
const hasStrongFirstMatch = [false];
709
>
710
>
// There will be a match, fill in tables
711
>
for (row = 1, patternPos = patternStart; patternPos < patternLen; row++, patternPos++) {
712
>
713
>
// Reduce search space to possible matching word positions and to possible access from next row
714
>
const minWordMatchPos = _minWordMatchPos[patternPos];
715
>
const maxWordMatchPos = _maxWordMatchPos[patternPos];
716
>
const nextMaxWordMatchPos = (patternPos + 1 < patternLen ? _maxWordMatchPos[patternPos + 1] : wordLen);
717
>
718
>
for (column = minWordMatchPos - wordStart + 1, wordPos = minWordMatchPos; wordPos < nextMaxWordMatchPos; column++, wordPos++) {
719
>
720
>
let score = Number.MIN_SAFE_INTEGER;
721
>
let canComeDiag = false;
722
>
723
>
if (wordPos <= maxWordMatchPos) {
724
>
score = _doScore(
725
>
pattern, patternLow, patternPos, patternStart,
726
>
word, wordLow, wordPos, wordLen, wordStart,
727
>
_diag[row - 1][column - 1] === 0,
728
>
hasStrongFirstMatch
729
>
);
730
>
}
731
>
732
>
let diagScore = 0;
733
>
if (score !== Number.MIN_SAFE_INTEGER) {
734
>
canComeDiag = true;
735
>
diagScore = score + _table[row - 1][column - 1];
736
>
}
737
>
738
>
const canComeLeft = wordPos > minWordMatchPos;
739
>
const leftScore = canComeLeft ? _table[row][column - 1] + (_diag[row][column - 1] > 0 ? -5 : 0) : 0; // penalty for a gap start
740
>
741
>
const canComeLeftLeft = wordPos > minWordMatchPos + 1 && _diag[row][column - 1] > 0;
742
>
const leftLeftScore = canComeLeftLeft ? _table[row][column - 2] + (_diag[row][column - 2] > 0 ? -5 : 0) : 0; // penalty for a gap start
743
>
744
>
if (canComeLeftLeft && (!canComeLeft || leftLeftScore >= leftScore) && (!canComeDiag || leftLeftScore >= diagScore)) {
745
// always prefer choosing left left to jump over a diagonal because that means a match is earlier in the word
746
_table[row][column] = leftLeftScore;
747
_arrows[row][column] = Arrow.LeftLeft;
748
_diag[row][column] = 0;
749
>
} else if (canComeLeft && (!canComeDiag || leftScore >= diagScore)) {
filters.ts
750
// always prefer choosing left since that means a match is earlier in the word
751
_table[row][column] = leftScore;
752
_arrows[row][column] = Arrow.Left;
753
_diag[row][column] = 0;
755
>
_table[row][column] = diagScore;
756
>
_arrows[row][column] = Arrow.Diag;
757
>
_diag[row][column] = _diag[row - 1][column - 1] + 1;
758
>
} else {
759
throw new Error(`not possible`);
760
}
762
>
}
763
>
764
>
if (_debug) {
765
printTables(pattern, patternStart, word, wordStart);
766
}
768
if (!hasStrongFirstMatch[0] && !options.firstMatchCanBeWeak) {
769
return undefined;