//
//  Feral Cow Poker Hand History Converter
//
//  by vbnautilus & qyayqi
//
//  Copyright 2010.  All rights reserved. 
//  You are not permitted to distribute, copy, or otherwise use this code without
//  the expressed permission of its authors.  
//
var version = "1.24";

var debug = 0;

var PSTARS = 0;
var FTP = 1;
var CEREUS = 2;
var HEM = 3;
var RPM = 4;
var TITAN = 5;

var reBlinds = new Array();
reBlinds[PSTARS] = /[\$|\(]?([\d|,|\.]+)\/[\$]?([\d|,|\.]+)[\)]?/;
reBlinds[FTP] = /[\$]?([\d|,|\.]+)\/[\$]?([\d|,|\.]+)/;
reBlinds[CEREUS] = /[\$]?([\d|,|\.]+)\/[\$]?([\d|,|\.]+)/;
reBlinds[HEM] = /[\$]?([\d|,|\.]+)\/[\$]?([\d|,|\.]+)/;
reBlinds[RPM] = /[\$]?([\d|,|\.]+)\/[\$]?([\d|,|\.]+)/;
reBlinds[TITAN] = /<gametype>.*?([\d|,|\.]+)\/.*?([\d|,|\.]+)<\/gametype>/;

var reGameSize = new Array();
reGameSize[PSTARS] = /(\d+)-max/;
reGameSize[FTP] = /(\d+) max/;
reGameSize[CEREUS] = /(\d+)-max/;
reGameSize[HEM] = /(\d+)-max/;

var reAnteText = new Array();
reAnteText[PSTARS] = /(.*?)\*\*\*/;
reAnteText[FTP] = /(.*?)\*\*\*/;
reAnteText[CEREUS] = /(.*?)\*\*\* 3rd/;
reAnteText[HEM] = /(.*?)\*\* Dealing down/;
reAnteText[RPM] = /(.*?)<round id=\"PREFLOP\"/;

var reAnteLines = new Array();
reAnteLines[PSTARS] = /posts the ante [\$]?([\d|,|\.]+)/;
reAnteLines[FTP] = / antes [\$]?([\d|,|\.]+)/;
reAnteLines[CEREUS] = / - Ante [\$]?([\d|,|\.]+)/;
reAnteLines[HEM] = / posts ante of \[[\$]?([\d|,|\.]+)/;

var reSeatingText = new Array();
reSeatingText[PSTARS] = /(.*?)\*\*\* /;
reSeatingText[FTP] = /(.*?)\*\*\* /;
reSeatingText[CEREUS] = /(.*?)\*\*\* /;
reSeatingText[HEM] = /\■(.*)\*\* Dealing down/i;
reSeatingText[TITAN] = /<players>(.*)<\/players>/;
reAnteText[RPM] = /(.*?)<round id=\"BLINDS\"/;

var reGameType = new Array();
reGameType[PSTARS] = /Tournament/;
reGameType[FTP] = /Seat.*\(\d/;
reGameType[CEREUS] = /Tournament/;
reGameType[HEM] = /Tournament/;
reGameType[RPM] = /Tournament/;
reGameType[TITAN] = /Tournament/;

var reFindSeats = new Array();
reFindSeats[PSTARS] = /(Seat \d+)\: .*chips\)/g;
reFindSeats[FTP] = /(Seat \d+)\: .*/g;
reFindSeats[CEREUS] = /(Seat \d+) -.*chips\)/g;
reFindSeats[HEM] = /(Seat \d+)\: .* \( [\$]?([\d|,|\.]+)/g;
reFindSeats[RPM] = /<(player seat=\"\d+\")/g;
reFindSeats[TITAN] = /<(player seat.*?)\/>/g;

var reFindInfo = new Array();
reFindInfo[PSTARS] = /Seat \d+\:.*/g;
reFindInfo[FTP] = /Seat \d+\: .*/g;
reFindInfo[CEREUS] = /Seat \d+ - .*/g;
reFindInfo[HEM] = /Seat \d+\: .*/g;
reFindInfo[RPM] = /<player seat=\"\d+\" .*/g;
reFindInfo[TITAN] = /<player seat=.*?\/>/g;

var rePlayerInfo = new Array();
rePlayerInfo[PSTARS] = /Seat (\d+)\: (.*) \([\$]?([\d|,|\.]+) in chips\)/;
rePlayerInfo[FTP] = /Seat (\d+)\: (.*) \([\$]?([\d|,|\.]+)\)/;
rePlayerInfo[CEREUS] = /Seat (\d+) - (.*) \([\$]?([\d|,|\.]+) in chips\)/;
rePlayerInfo[HEM] = /Seat (\d+)\: (.*) \( [\$]?([\d|,|\.]+) \S* \)/;
rePlayerInfo[RPM] = /<player seat=\"(\d+)\" nickname=\"(.*)\" balance=\"[\$]?([\d|,|.])\"/;
rePlayerInfo[TITAN] = /<player seat=\"(\d+)\" name=\"(\S*?)\" chips=\".*?([\d|,|\.]+)\"/;

var reButton = new Array();
reButton[PSTARS] = /Seat \#(\d+) is the button/;
reButton[FTP] = /The button is in seat \#(\d)/;
reButton[CEREUS] = /Seat \#(\d+) is the dealer/;
reButton[HEM] = /Seat (\d+) is the button/;
reButton[RPM] = /<players dealer=\"(\d+)\"/;
reButton[TITAN] = /<player seat=\"(\d+)\" name=\"\S*?\" chips=\"\S*?\" dealer=\"1\".*?\/>/;

var reGetHandPre = new Array();
var reGetHandPost = new Array();
var reGetHandPost2 = new Array();

reGetHandPre[PSTARS] = "(?:Dealt to|Seat \\d+:) ";
reGetHandPre[FTP] = "(?:Dealt to|Seat \\d+:) ";
reGetHandPre[CEREUS] = "(?:Seat \\d+: )?";
reGetHandPre[HEM] = "(?:Dealt to|Seat \\d+:) ";
reGetHandPre[RPM] = "<cards type"

reGetHandPost[PSTARS] = " (\\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\]■)";
reGetHandPost[FTP] = " (\\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\] \\[[2-9TJQKA][hdsc]\\]■)";
reGetHandPost[CEREUS] = " - (?:Pocket) (\\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\]■)";

reGetHandPost2[PSTARS] = " (?:mucked |showed )?(\\[(.*)\\])";
reGetHandPost2[FTP] = " (?:mucked |showed )?(\\[(.*)\\])";
reGetHandPost2[CEREUS] = " - (?:Pocket |Shows )?(\\[(.*)\\])";

var reTDGetHandPost = new Array();
reTDGetHandPost[PSTARS] = "( \\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\]■)";

var reBadugiGetHandPost = new Array();
reBadugiGetHandPost[PSTARS] = "( \\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\]■)";

var reMatchCard = new Array();
reMatchCard[PSTARS] = /([2-9TJQKA][hdsc])/g;
reMatchCard[FTP] = /([2-9TJQKA][hdsc])/g;
reMatchCard[CEREUS] = /([2-9TJQKA][hdsc])/g;

var reStreetMatch = new Array();
var reStreetMatchAlt = new Array();
reStreetMatch[PSTARS] = new Array(/3rd STREET \*\*\*■(.*)\*\*\* 4th/i, /4th STREET \*\*\*■(.*)\*\*\* 5th/i, /5th STREET \*\*\*■(.*)\*\*\* 6th/i, /6th STREET \*\*\*■(.*)\*\*\* RIVER/i, /RIVER \*\*\*■(.*)\*\*\* show/i);
reStreetMatch[FTP] = new Array(/3rd STREET \*\*\*■(.*)\*\*\* 4th/i, /4th STREET \*\*\*■(.*)\*\*\* 5th/i, /5th STREET \*\*\*■(.*)\*\*\* 6th/i, /6th STREET \*\*\*■(.*)\*\*\* 7th STREET/i, /7th STREET \*\*\*■(.*)\*\*\* show/i);
reStreetMatch[CEREUS] = new Array(/3rd STREET \*\*\*■(.*)\*\*\* 4th/i, /4th STREET \*\*\*■(.*)\*\*\* 5th/i, /5th STREET \*\*\*■(.*)\*\*\* 6th/i, /6th STREET \*\*\*■(.*)\*\*\* RIVER/i, /RIVER \*\*\*■(.*)\*\*\* show/i);
reStreetMatchAlt[PSTARS] = new Array(/3rd STREET \*\*\*■(.*)\*\*\* sum/i, /4th STREET \*\*\*■(.*)\*\*\* sum/i, /5th STREET \*\*\*■(.*)\*\*\* sum/i, /6th STREET \*\*\*■(.*)\*\*\* sum/i, /RIVER \*\*\*■(.*)\*\*\* sum/i);
reStreetMatchAlt[FTP] = new Array(/3RD STREET \*\*\*■(.*)\*\*\* SUM/i, /4th STREET \*\*\*■(.*)\*\*\* sum/i, /5th STREET \*\*\*■(.*)\*\*\* sum/i, /6th STREET \*\*\*■(.*)\*\*\* sum/i, /7th STREET \*\*\*■(.*)\*\*\* sum/i);
reStreetMatchAlt[CEREUS] = new Array(/3rd STREET \*\*\*■(.*)\*\*\* sum/i, /4th STREET \*\*\*■(.*)\*\*\* sum/i, /5th STREET \*\*\*■(.*)\*\*\* sum/i, /6th STREET \*\*\*■(.*)\*\*\* sum/i, /RIVER \*\*\*■(.*)\*\*\* sum/i);

var reTDStreetMatch = new Array();
var reTDStreetMatchAlt = new Array();
reTDStreetMatch[PSTARS] = new Array(/DEALING HANDS \*\*\*■(.*)\*\*\* FIRST/i, /FIRST DRAW \*\*\*■(.*)\*\*\* SECOND/i, /SECOND DRAW \*\*\*■(.*)\*\*\* THIRD/i, /THIRD DRAW \*\*\*■(.*)\*\*\* SHOW/i);
reTDStreetMatchAlt[PSTARS] = new Array(/DEALING HANDS \*\*\*■(.*)\*\*\* sum/i, /FIRST DRAW \*\*\*■(.*)\*\*\* sum/i, /SECOND DRAW \*\*\*■(.*)\*\*\* sum/i, /THIRD DRAW \*\*\*■(.*)\*\*\* sum/i);

var reSDStreetMatch = new Array();
var reSDStreetMatchAlt = new Array();
// original: reSDStreetMatch[PSTARS] = new Array(/DEALING HANDS \*\*\*■(.*?)■(.*?)\: (stands|discards)/i, /DEALING HANDS \*\*\*■.*?■(.*?\: (stands|discards) .*)■\*\*\* SHOW/i);
reSDStreetMatch[PSTARS] = /DEALING HANDS \*\*\*■(.*?)\: (?:stands|discards)/i;
reSDStreetMatchAlt[PSTARS] = /DEALING HANDS \*\*\*■(.*?)■\*\*\* sum/i;
//reSDStreetMatchAlt[PSTARS] = new Array(/DEALING HANDS \*\*\*■(.*?)■\*\*\* sum/i, /.*?■((.*?)\: (stands|discards) .*)■\*\*\* sum/i);

var re5CDStreetMatch = new Array();
var re5CDStreetMatchAlt = new Array();
re5CDStreetMatch[PSTARS] = new Array(/DEALING HANDS \*\*\*■(.*?)■(.*?)\: (stands|discards)/i, /DEALING HANDS \*\*\*■.*?■(.*?\: (stands|discards) .*)■\*\*\* SHOW/i);
re5CDStreetMatchAlt[PSTARS] = new Array(/DEALING HANDS \*\*\*■(.*?)■\*\*\* sum/i, /.*?■((.*?)\: (stands|discards) .*)■\*\*\* sum/i);

var reMatchSummary = new Array();
reMatchSummary[PSTARS] = /SUMMARY \*\*\*|(.*)/;
reMatchSummary[FTP] = /SUMMARY \*\*\*|(.*)/;
reMatchSummary[CEREUS] = /SUMMARY \*\*\*|(.*)/;
reMatchSummary[HEM] = /Dealing River \*\* \[ [2-9TJQKA][hdsc] \]■(.*)/;

var reSummaryExtraction1 = new Array();
reSummaryExtraction1[PSTARS] = /Seat \d+: (.*?) (?:\(small blind\) |\(big blind\) |\(button\) |\(dealer\) |)+(showed|mucked)(.*)/;
reSummaryExtraction1[FTP] = /Seat \d+: (.*?) (?:\(small blind\) |\(big blind\) |\(button\) |\(dealer\) |)+(showed|mucked|collected)(.*)/;
reSummaryExtraction1[CEREUS] = /Seat \d+: (.*?) (?:\(small blind\) |\(big blind\) |\(button\) |\(dealer\) |)+(showed|mucked|collected|won|(?:[A-Z]*:)lost)(.*)/;
reSummaryExtraction1[HEM] = /(.*) wins (.*) from main pot/;

var reHESummaryExtraction2 = new Array();
reHESummaryExtraction2[PSTARS] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\](.*?)?(?: with )?(.*)?/;
reHESummaryExtraction2[FTP] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\](.*?)?(?: with )?(.*)?/;
reHESummaryExtraction2[CEREUS] = /(.*?)(?:[:| ]with )(.*?)\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) /;
reHESummaryExtraction2[HEM] = /(.*) (?:shows|doesn\'t show) \[([2-9TJQKA][hdsc]), ([2-9TJQKA][hdsc]) \]/;

var reOSummaryExtraction2 = new Array();
reOSummaryExtraction2[PSTARS] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\](.*?)?(?: with )?(.*)?/;
//reOSummaryExtraction2[PSTARS] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\](.*?)?(?: with )?(.*)?/;
reOSummaryExtraction2[FTP] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\](.*?)?(?: with )?(.*)?/;
reOSummaryExtraction2[CEREUS] = /(.*?)(?:[:| ]with )(.*?)\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) /;
reOSummaryExtraction2[HEM] = /(.*) (?:shows|doesn\'t show) \[([2-9TJQKA][hdsc]), ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) \]/;

var reTDSummaryExtraction2 = new Array();
reTDSummaryExtraction2[PSTARS] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\](.*?)?(?: with )(.*)?/;

var reBadugiSummaryExtraction2 = new Array();
reBadugiSummaryExtraction2[PSTARS] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\](.*?)?(?: with )(.*)?/;

var reStudSummaryExtraction2 = new Array();
reStudSummaryExtraction2[PSTARS] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\](.*?)(?: with )(.*)/;
reStudSummaryExtraction2[FTP] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\](.*?)(?:with|\-)(.*)/;
reStudSummaryExtraction2[CEREUS] = /(.*?)(?:[:| ]with )(.*)\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) /;
reStudSummaryExtraction2[HEM]= / /;

var reTheMoney = new Array();
reTheMoney[PSTARS] = /\([\$]?([\d|,|\.]+)\)/;
reTheMoney[FTP] = /\([\$]?([\d|,|\.]+)\)/;
reTheMoney[CEREUS] = /\([\$]?([\d|,|\.]+)\)/;
reTheMoney[HEM] = / [\$]?([\d|,|\.]+) /;

var reRake = new Array();
reRake[PSTARS] = /Rake [\$]?([\d|,|\.]+)/;
reRake[FTP] = /Rake [\$]?([\d|,|\.]+)/;
reRake[CEREUS] = /Rake \([\$]?([\d|,|\.]+)\)/;

var reSmallBlind = new Array();
reSmallBlind[PSTARS] = /(.*)\: posts small blind [\$]?([\d|,|\.]+)/;
reSmallBlind[FTP] = /(.*) posts the small blind of [\$]?([\d|,|\.]+)/;
reSmallBlind[CEREUS] = /(.*) - Posts small blind [\$]?([\d|,|\.]+)/;
reSmallBlind[HEM] = /(.*) posts small blind \[[\$]?([\d|,|\.]+)/;
reSmallBlind[TITAN] = /player=\"(\S+?)\" type=\"1\" sum=\"\S+?([\d|,|\.]+)\"/;

var reBigBlind = new Array();
reBigBlind[PSTARS] = /(.*)\: posts big blind [\$]?([\d|,|\.]+)/;
reBigBlind[FTP] = /(.*) posts the big blind of [\$]?([\d|,|\.]+)/;
reBigBlind[CEREUS] = /(.*) - Posts big blind [\$]?([\d|,|\.]+)/;
reBigBlind[HEM] = /(.*) posts big blind \[[\$]?([\d|,|\.]+)/;
reBigBlind[TITAN] = /player=\"(\S+?)\" type=\"2\" sum=\"\S+?([\d|,|\.]+)\"/;

var reOHoleCards = new Array();
reOHoleCards[PSTARS] = /Dealt to (.*) \[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reOHoleCards[FTP] = /Dealt to (.*) \[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reOHoleCards[CEREUS] = /Dealt to (.*) \[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reOHoleCards[HEM] = /Dealt to (.*) \[ ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) \]/;

var reHEHoleCards = new Array();
reHEHoleCards[PSTARS] = /Dealt to (.*) \[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reHEHoleCards[FTP] = /Dealt to (.*) \[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reHEHoleCards[CEREUS] = /Dealt to (.*) \[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reHEHoleCards[HEM] = /Dealt to (.*) \[ [ ]?([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) \]/;
reHEHoleCards[TITAN] = /cards type=\"Pocket\" player=\"(\S+?)\">([HDSC][2-9TJQKA]) ([HDSC][2-9TJQKA])/;

var reHero = new Array();
reHero[TITAN] = /<nickname>(.*?)<\/nickname>/;

var rePreflopAction = new Array();
rePreflopAction[PSTARS] = /HOLE CARDS \*\*\*■(.*)\*\*\* FLOP/;
rePreflopAction[FTP] = /HOLE CARDS \*\*\*■(.*)\*\*\* FLOP/;
rePreflopAction[CEREUS] = /POCKET CARDS \*\*\*■(.*)\*\*\* FLOP/;
rePreflopAction[HEM] = /Dealing down cards \*\*■(.*)\*\* Dealing Flop/;
rePreflopAction[TITAN] = /<round no=\"1\">.*?<\/cards>(.*?)<\/round>/;

var rePreflopActionAlt = new Array();
rePreflopActionAlt[PSTARS] = /HOLE CARDS \*\*\*■(.*)\*\*\* (?:SUM)/;
rePreflopActionAlt[FTP] = /HOLE CARDS \*\*\*■(.*)\*\*\* (?:SUM)/;
rePreflopActionAlt[CEREUS] = /POCKET CARDS \*\*\*■(.*)\*\*\* (?:SUM)/;
rePreflopActionAlt[HEM] = /Dealing down cards \*\*■(.*)■(?:.*?) wins /;
rePreflopActionAlt[TITAN] = /<round no=\"1\">.*?<\/cards>(.*?)<\/round>/;


var reFlop = new Array();
reFlop[PSTARS] = /FLOP \*\*\* \[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reFlop[FTP] = /FLOP \*\*\* \[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reFlop[CEREUS] = /FLOP \*\*\* \[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reFlop[HEM] = /Dealing Flop \*\*\ \[ ([2-9TJQKA][hdsc]), ([2-9TJQKA][hdsc]), ([2-9TJQKA][hdsc]) \]/;
reFlop[TITAN] = /<cards type=\"Flop\" player=\"\">([HDSC][2-9TJQKA]) ([HDSC][2-9TJQKA]) ([HDSC][2-9TJQKA])/;

var reFlopRunIt = new Array();
reFlopRunIt[PSTARS] = "FLOP (\\d) \\*\\*\\* \\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\\]";
reFlopRunIt[FTP] = "FLOP (\\d) \\*\\*\\* \\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\\]";
reFlopRunIt[CEREUS] = "FLOP (\\d) \\*\\*\\* \\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\\]";
reFlopRunIt[HEM] = "Dealing Flop (\\d) \\*\\* \\[ ([2-9TJQKA][hdsc]), ([2-9TJQKA][hdsc]), ([2-9TJQKA][hdsc]) \\]";

var reFlopAction = new Array();
reFlopAction[PSTARS] = /FLOP \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:TURN)/;
reFlopAction[FTP] = /FLOP \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:TURN)/;
reFlopAction[CEREUS] = /FLOP \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:TURN)/;
reFlopAction[HEM] = /Dealing Flop \*\*\ \[ [2-9TJQKA][hdsc], [2-9TJQKA][hdsc], [2-9TJQKA][hdsc] \]■(.*)\*\* Dealing Turn/;
reFlopAction[TITAN] = /<round no=\"2\">.*?<\/cards>(.*?)<\/round>/;

var reFlopActionAlt = new Array();
reFlopActionAlt[PSTARS] = /FLOP \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SUM)/;
reFlopActionAlt[FTP] = /FLOP \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SUM)/;
reFlopActionAlt[CEREUS] = /FLOP \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SUM)/;
reFlopActionAlt[HEM] = /Dealing Flop \*\*\ \[ [2-9TJQKA][hdsc], [2-9TJQKA][hdsc], [2-9TJQKA][hdsc] \]■(.*)/;
reFlopActionAlt[TITAN] = /<round no=\"2\">.*?<\/cards>(.*?)<\/round>/;

var reTurn = new Array();
reTurn[PSTARS] = /TURN \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[([2-9TJQKA][hdsc])\]/;
reTurn[FTP] = /TURN \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[([2-9TJQKA][hdsc])\]/;
reTurn[CEREUS] = /TURN \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[([2-9TJQKA][hdsc])\]/;
reTurn[HEM] = /Dealing Turn \*\* \[ ([2-9TJQKA][hdsc]) \]/;
reTurn[TITAN] = /<cards type=\"Turn\" player=\"\">([HDSC][2-9TJQKA])/;

var reTurnRunIt = new Array();
reTurnRunIt[PSTARS] = "TURN (\\d) \\*\\*\\* \\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\] \\[([2-9TJQKA][hdsc])\\]";
reTurnRunIt[FTP] = "TURN (\\d) \\*\\*\\* \\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\] \\[([2-9TJQKA][hdsc])\\]";
reTurnRunIt[CEREUS] = "TURN (\\d) \\*\\*\\* \\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\] \\[([2-9TJQKA][hdsc])\\]";
reTurnRunIt[HEM] = "Dealing Turn (\\d) \\*\\* \\[ ([2-9TJQKA][hdsc]) \\]";

var reTurnAction = new Array();
reTurnAction[PSTARS] = /TURN \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:RIVER)/;
reTurnAction[FTP] = /TURN \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:RIVER)/;
reTurnAction[CEREUS] = /TURN \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:RIVER)/;
reTurnAction[HEM] = /Dealing Turn \*\* \[ [2-9TJQKA][hdsc] \]■(.*)\*\* (?:Dealing River)/;
reTurnAction[TITAN] = /<round no=\"3\">.*?<\/cards>(.*?)<\/round>/;

var reTurnActionAlt = new Array();
reTurnActionAlt[PSTARS] = /TURN \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SUM)/;
reTurnActionAlt[FTP] = /TURN \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SUM)/;
reTurnActionAlt[CEREUS] = /TURN \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SUM)/;
reTurnActionAlt[HEM] = /Dealing Turn \*\* \[ [2-9TJQKA][hdsc] \]■(.*)/;
reTurnActionAlt[TITAN] = /<round no=\"3\">.*?<\/cards>(.*?)<\/round>/;

var reRiver = new Array();
reRiver[PSTARS] = /RIVER \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[([2-9TJQKA][hdsc])\]/;
reRiver[FTP] = /RIVER \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[([2-9TJQKA][hdsc])\]/;
reRiver[CEREUS] = /RIVER \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[([2-9TJQKA][hdsc])\]/;
reRiver[HEM] = /Dealing River \*\* \[ ([2-9TJQKA][hdsc]) \]/;
reRiver[TITAN] = /<cards type=\"River\" player=\"\">([HDSC][2-9TJQKA])/;

var reRiverRunIt = new Array();
reRiverRunIt[PSTARS] = "RIVER (\\d) \\*\\*\\* \\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\] \\[([2-9TJQKA][hdsc])\\]";
reRiverRunIt[FTP] = "RIVER (\\d) \\*\\*\\* \\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\] \\[([2-9TJQKA][hdsc])\\]";
reRiverRunIt[CEREUS] = "RIVER (\\d) \\*\\*\\* \\[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\\] \\[([2-9TJQKA][hdsc])\\]";
reRiverRunIt[HEM] = "Dealing River (\\d) \\*\\* \\[ ([2-9TJQKA][hdsc]) \\]";

var reRiverAction = new Array();
reRiverAction[PSTARS] = /RIVER \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SHOW)/;
reRiverAction[FTP] = /RIVER \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SHOW)/;
reRiverAction[CEREUS] = /RIVER \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SHOW)/;
reRiverAction[HEM] = /Dealing River \*\* \[ [2-9TJQKA][hdsc] \]■(.*?) wins /;
reRiverAction[TITAN] = /<round no=\"4\">.*?<\/cards>(.*?)<\/round>/;

var reRiverActionAlt = new Array();
reRiverActionAlt[PSTARS] = /RIVER \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SUM)/;
reRiverActionAlt[FTP] = /RIVER \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SUM)/;
reRiverActionAlt[CEREUS] = /RIVER \*\*\* \[[2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc] [2-9TJQKA][hdsc]\] \[[2-9TJQKA][hdsc]\]■(.*)\*\*\* (?:SUM)/;
reRiverActionAlt[HEM] = /Dealing River \*\* \[ [2-9TJQKA][hdsc] \]■(?:.*?) wins /;
reRiverActionAlt[TITAN] = /<round no=\"4\">.*?<\/cards>(.*?)<\/round>/;

var reShowdownPlayers = new Array();
reShowdownPlayers[PSTARS] = /(.*): /;
reShowdownPlayers[FTP] = /(.*): /;
reShowdownPlayers[CEREUS] = /(.*) - /;

var reShowdownCards = new Array();
reShowdownCards[PSTARS] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reShowdownCards[FTP] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;
reShowdownCards[CEREUS] = /\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\]/;

var reMucks = new Array();
reMucks[PSTARS] = /mucks/;
reMucks[FTP] = /mucks/;
reMucks[CEREUS] = /Mucks/;

var reHEMuckedPre = new Array();
reHEMuckedPre[PSTARS] = "";
reHEMuckedPre[FTP] = "";
reHEMuckedPre[CEREUS] = "";
var reHEMuckedPost = new Array();
reHEMuckedPost[PSTARS] = ' mucked \\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\\]';
reHEMuckedPost[FTP] = ' mucked \\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\\]';
reHEMuckedPost[CEREUS] = ' .* [Mucked] \\[([2-9TJQKA][hdsc]) ([2-9TJQKA][hdsc])\\]';

var reGetShowdownHands = new Array();
reGetShowdownHands[PSTARS] = /\] \((.*)\)/;
reGetShowdownHands[FTP] = /\] \((.*)\)/;
reGetShowdownHands[CEREUS] = /\] \((.*)\)/;

var reGetResults = new Array();
reGetResults[PSTARS] = / collected /;
reGetResults[FTP] = / collected /;
reGetResults[CEREUS] = / Collects /;




function fcp_convert_hh(unformatted, outputType,showNames,showResults,cardType,debugOption) {

	
	
	var theHand = new hand(); //hand data structure
	
	//handle unformatted option
	if (outputType == 15) {theHand.formatted=unformatted; return(theHand); }
	
	var formatted; //the converted output text
	
	debug = debugOption;
	
	//default to Feral Cow Original (4bb) output type
	if (!outputType) {outputType = 0;}

	var myRegExp = new RegExp("(10)(h|c|d|s)([ |\\]])", "ig");
	unformatted = unformatted.replace(myRegExp, "T$2$3");
	//theHand.error = unformatted;
	theHand.unformatted = unformatted;
	theHand.unformattedNoBreaks = unformatted.replace(/\n/g, "■");
	//for IE, also remove the \r characacter
	theHand.unformattedNoBreaks = theHand.unformattedNoBreaks.replace(/\r/g, "");
	theHand.prefix = "";
	
	//default cards for style 20
	if (outputType == 0) {
		if (cardType == 0) {
			outputType = 0;
			cardFolder = '';
		} else if (cardType ==1 ) {
			outputType = 20;
			cardFolder = 'ouch';
		} else if (cardType ==2 ) {
			outputType = 20;
			cardFolder='inline';
		}
	} else {
	
		if (cardType == 0 ) {
			cardFolder = 'ouch';
		} else if (cardType ==1) {
			cardFolder = 'ouch';
		} else if (cardType ==2) {
			cardFolder = 'inline';
		}
	}
	
	
	
	
	//parse options embedded within HH
	if (theHand.unformatted.match(/^(?:pos|position|showpos|showposition)$/m)) {showNames = 0;}
	if (theHand.unformatted.match(/^newcards$/m)) {outputType = 20; cardFolder = 'inline';}
	if (theHand.unformatted.match(/^(?:cwikcards|cwik)$/m)) {outputType = 20; cardFolder = 'ouch';}
	if (theHand.unformatted.match(/^hideresults$/m)) {showResults = 1;}

	
	//split the text by line breaks
	var lines = new Array();
	lines = theHand.unformatted.split('\n');
	theHand.lines = lines;
	

	//find which site
	//theHand.firstLine = lines[0] + "|" + lines[1];

	for (linecounter = 0; linecounter <lines.length;++linecounter) {
	
		theHand.firstLine = theHand.lines[linecounter];
		
		if (theHand.firstLine.match(/PokerStars/)) {
			theHand.firstLine = theHand.lines[linecounter] + theHand.lines[linecounter+1];
			theHand.site = "PokerStars";
			theHand = parse_site_pokerstars(theHand);
			break;
		} else if ((theHand.firstLine.match(/Full Tilt Poker/)) || (theHand.firstLine.match(/FullTiltPoker/))) {			theHand.firstLine = theHand.lines[linecounter] + theHand.lines[linecounter+1];
			theHand.site = "Full Tilt";
			theHand = parse_site_ftp(theHand);
			break;
		} else if (theHand.firstLine.match(/Stage \#/)) {
			theHand.firstLine = theHand.lines[linecounter] + theHand.lines[linecounter+1];
			theHand.site = "Cereus";
			theHand = parse_site_cereus(theHand);
			break;
		} else if (theHand.firstLine.match(/\*\*\*\*\* Hand History /)) {
			theHand.firstLine = theHand.lines[linecounter] + theHand.lines[linecounter+1];
			theHand.site = "Holdem Manager";
			theHand = parse_site_hem(theHand);
			break;
		} else if (theHand.firstLine.match(/sessioncode/)) {
			theHand.site = "Titan";
			theHand = parse_site_titan(theHand);
			break;
		} else {
			theHand.site = "NONE";
			theHand.prefix = theHand.prefix + theHand.lines[linecounter] + "\n";
		}
	}
	
	
	if (theHand.site == "NONE") {
		theHand.formatted = "Site unknown or unsupported.  Could not parse history."; 
	}
	else {
		//Send the populated data structure to be formatted into output	
		theHand.formatted = handToText(theHand,outputType,showNames,showResults);
	}
	
	//we return the entire hand object
	return (theHand);

}

function hand() {
	//this is just an object structure
}

function parse_site_ftp(handin) {

	//determine which game is being played
	theResult = "Game: unknown\n";
	if (handin.firstLine.match(/Cap No Limit Hold\'em/)) { //'
		handin.gameLong = "Cap No-Limit Hold\'em";
		handin.gameShort = "NLHE";
		handin = parse_holdem(handin, FTP);
	} else if (handin.firstLine.match(/No Limit Hold\'em/)) {
		handin.gameLong = "No-Limit Hold\'em";
		handin.gameShort = "NLHE";
		handin = parse_holdem(handin, FTP);
	} else if (handin.firstLine.match(/Pot Limit Hold\'em/)) {
		handin.gameLong = "Pot Limit Hold\'em";
		handin.gameShort = "PLHE";
		handin = parse_holdem(handin, FTP);
	} else if (handin.firstLine.match(/Limit Hold\'em/)) { //'
		handin.gameLong = "Limit Hold\'em";
		handin.gameShort = "LHE";
		handin = parse_holdem(handin, FTP);

	} else if ((handin.firstLine.match(/Omaha/)) || (handin.firstLine.match(/omaha/i))) {

		handin.gameLong = "Limit Omaha";
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/Pot Limit/i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		if (handin.firstLine.match(/h\/l/i)) {
			handin.gameLong = handin.gameLong + " Hi/Lo";
		}
		handin.gameShort = "OMAHA";
		handin = parse_omaha(handin, FTP);

	} else if ((handin.firstLine.match(/(Razz)/i)) || (handin.firstLine.match(/(Stud)/i))) {

		handin.gameLong = "Limit " + RegExp.$1;
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/pot limit/i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		if (handin.firstLine.match(/hi\/lo/i)) {
			handin.gameLong = handin.gameLong + " Hi/Lo";
		}

		handin.gameShort = RegExp.$1.toUpperCase();
		handin = parse_stud(handin, FTP);
	} else {

		handin.error = "Game type not currently supported."
	}

	return handin;

}

function parse_site_pokerstars(handin) {
	
	//get tourney buyin amount
	if (handin.firstLine.match(/Tournament/)) {
		if (handin.firstLine.match(/(\$[\d|\.|\,]+\+\$[\d|\.|\,]+)/)){
			handin.tourneyBuyin = RegExp.$1;
		}
	
	}

	//determine which game is being played
	theResult = "Game: unknown\n";
	if (handin.firstLine.match(/Hold\'em No Limit/)) { //'
		handin.gameLong = "No-Limit Hold'em";
		handin.gameShort = "NLHE";
		handin = parse_holdem(handin, PSTARS);

	} else if (handin.firstLine.match(/Hold\'em Limit/)) { //'
		handin.gameLong = "Limit Hold'em";
		handin.gameShort = "LHE";
		handin = parse_holdem(handin, PSTARS);

	} else if ((handin.firstLine.match(/Omaha/)) || (handin.firstLine.match(/omaha/i))) {

		handin.gameLong = "Limit Omaha";
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/pot limit/i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		if (handin.firstLine.match(/hi\/lo/i)) {
			handin.gameLong = handin.gameLong + " Hi/Lo";
		}
		handin.gameShort = "OMAHA";
		handin = parse_omaha(handin, PSTARS);

	} else if ((handin.firstLine.match(/(Razz)/i)) || (handin.firstLine.match(/(Stud)/i))) {

		handin.gameLong = "Limit " + RegExp.$1;
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/pot limit/i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		if (handin.firstLine.match(/hi\/lo/i)) {
			handin.gameLong = handin.gameLong + " Hi/Lo";
		}
		handin.gameShort = "STUD";
		handin = parse_stud(handin, PSTARS);

	} else if ( (handin.firstLine.match(/(Triple Draw)/i)) )  {

		handin.gameLong = "Limit " + RegExp.$1;
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/pot limit/i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		handin.gameShort = "DRAW";
		handin = parse_tripledraw(handin, PSTARS);

	} else if (handin.firstLine.match(/(Single Draw)/i))  {

		handin.gameLong = "Limit " + RegExp.$1;
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/pot limit/i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		handin.gameShort = "DRAW";
		handin = parse_singledraw(handin, PSTARS);

	} else if (handin.firstLine.match(/(Badugi)/i)) {
	
		handin.gameLong = "Limit " + RegExp.$1;
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/pot limit/i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		handin.gameShort = "DRAW";
		handin = parse_badugi(handin, PSTARS);
	
	} else if (handin.firstLine.match(/(5 Card Draw)/i)) {
	
		handin.gameLong = "Limit " + RegExp.$1;
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/pot limit/i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		handin.gameShort = "DRAW";
		handin = parse_fivecarddraw(handin, PSTARS);
		
	} else {
	

		handin.error = "Game type not currently supported.";

	}
	
	

	return handin;

}

function parse_site_cereus(handin) {

	//determine which game is being played
	if (handin.firstLine.match(/Holdem .*(No|Pot) Limit/)) { //'
		handin.gameLong = RegExp.$1 + " Limit Hold\'em";
		handin.gameShort = "NLHE";
		handin = parse_holdem(handin, CEREUS);

	} else if (handin.firstLine.match(/Holdem .*Limit/)) { //'
		handin.gameLong = "Limit Hold\'em";
		handin.gameShort = "LHE";
		handin = parse_holdem(handin, CEREUS);

	} else if ((handin.firstLine.match(/Omaha/)) || (handin.firstLine.match(/omaha/i))) {

		handin.gameLong = "Omaha";
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No Limit " + handin.gameLong;
		} else if (handin.firstLine.match(/pot limit/i)) {
			handin.gameLong = "Pot Limit " + handin.gameLong;
		}
		if (handin.firstLine.match(/hi\/lo/i)) {
			handin.gameLong = handin.gameLong + " Hi/Lo";
		}
		handin.gameShort = "OMAHA";
		handin = parse_omaha(handin, CEREUS);

	} else if ((handin.firstLine.match(/(Razz)/i)) || (handin.firstLine.match(/(Seven Card)/i))) {

		handin.gameLong = "Limit " + RegExp.$1;
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/pot limit/i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		if (handin.firstLine.match(/hi\/lo/i)) {
			handin.gameLong = handin.gameLong + " Hi/Lo";
		}
		handin.gameShort = "STUD";
		handin = parse_stud(handin, CEREUS);

	} else {

		handin.error = "Game type not currently supported."
	}

	//turn off Cereus support here
	//handin.error = "Cereus support coming soon.  Hold your horses.  er.. cows.";
	return handin;

}

function parse_site_hem(handin) {

	//get original site
	if (handin.firstLine.match(/\((.*)\)/)) {
		handin.HEMOriginalSite = RegExp.$1;
	}
	
	//determine which game is being played
	if (handin.firstLine.match(/.* (NL|PL) Texas Hold/)) {
		handin.gameLong = RegExp.$1 + " Hold\'em";
		handin.gameShort = "NLHE";
		handin = parse_holdem(handin, HEM);

	} else if (handin.firstLine.match(/Holdem .*Limit/) || handin.firstLine.match(/Limit Texas Hold\'em/)) {
		handin.gameLong = "Limit Hold\'em";
		handin.gameShort = "LHE";
		handin = parse_holdem(handin, HEM);

	} else if ((handin.firstLine.match(/Omaha/)) || (handin.firstLine.match(/omaha/i))) {

		handin.gameLong = "Limit Omaha";
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/ PL /i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		if (handin.firstLine.match(/hi\/lo/i)) {
			handin.gameLong = handin.gameLong + " Hi/Lo";
		}
		handin.gameShort = "OMAHA";
		handin = parse_omaha(handin, HEM);

	} else if ((handin.firstLine.match(/(Razz)/i)) || (handin.firstLine.match(/(Seven Card)/i))) {

		handin.gameLong = "Limit " + RegExp.$1;
		if (handin.firstLine.match(/no limit/i)) {
			handin.gameLong = "No " + handin.gameLong;
		} else if (handin.firstLine.match(/ PL /i)) {
			handin.gameLong = "Pot " + handin.gameLong;
		}
		if (handin.firstLine.match(/hi\/lo/i)) {
			handin.gameLong = handin.gameLong + " Hi/Lo";
		}
		handin.gameShort = "STUD";
		handin = parse_stud(handin, HEM);

	} else {

		handin.error = "Game type not currently supported."
	}

	//turn off Cereus support here
	//handin.error = "Cereus support coming soon.  Hold your horses.  er.. cows.";
	return handin;

}


function parse_site_titan(handin) {


	//replace 10 cards with T cards - note currently is a global replace and will replace these strings
	//if they occur in player names too
	handin.unformattedNoBreaks = handin.unformattedNoBreaks.replace(/S10/g,"ST");
	handin.unformattedNoBreaks = handin.unformattedNoBreaks.replace(/C10/g,"CT");
	handin.unformattedNoBreaks = handin.unformattedNoBreaks.replace(/H10/g,"HT");
	handin.unformattedNoBreaks = handin.unformattedNoBreaks.replace(/D10/g,"DT");
	
	handin.unformatted = handin.unformatted.replace(/S10/g,"ST");
	handin.unformatted = handin.unformatted.replace(/C10/g,"CT");
	handin.unformatted = handin.unformatted.replace(/H10/g,"HT");
	handin.unformatted = handin.unformatted.replace(/D10/g,"DT");
	
	//get currency
	handin.unformattedNoBreaks.match(/<currency>(.*?)<\/currency>/);
	currText = RegExp.$1;
	if (currText == "EUR") {
		handin.currencyText = "€";
	} else if (currText == "GBP") {
		handin.currencyText = "£";
	} else if (currText = "USD") {
		handin.currencyText = "$";
	}
 	
	
	//determine which game is being played
	handin.unformattedNoBreaks.match(/<gametype>(.*)<\/gametype>/);

	gametype = RegExp.$1;
	
	
	if (gametype.match(/Holdem NL/)) {
		handin.gameLong = "No Limit Hold'em";
		handin.gameShort = "NLHE";
		if(gametype.match(/Holdem NL (.*?)\d/)) {
			handin.currency = RegExp.$1;
			
		}
		
		handin = parse_holdem(handin,TITAN);
	}
	
	return handin;
}

function parse_singledraw(handin, site) {


	//Cash or tournament?
	if (handin.firstLine.match(/Tournament/)) {
		handin.gameType = "T";
	} else {
		handin.gameType = "C";
	}

	//find blinds
	if (handin.firstLine.match(reBlinds[site])) {
		handin.smallBlind = RegExp.$1;
		handin.bigBlind = RegExp.$2;
	}

	handin.smallBlindPostedAmount = 0;
	handin.bigBlindPostedAmount = 0;

	//find game size
	if (handin.unformatted.match(reGameSize[site])) {
		handin.gameSize = RegExp.$1 + '-max';
	}
	else {
		handin.gameSize = "";
	}

	handin.antesTotal = 0;
	anteLines = new Array;
	//find antes
	anteText = handin.unformattedNoBreaks.match(reAnteText[site]);
   if (anteText) {
		anteLines = anteText[1].split(/■/);
		numAnteLines = anteLines.length;
		for (j=0;j<numAnteLines;j++) {
			if (anteLines[j].match(reAnteLines[site])) {
				handin.ante = RegExp.$1;
				handin.antesTotal = parseFloat(handin.antesTotal) + parseFloat(RegExp.$1);
			}
		}
	}
	
	
	result = handin.unformattedNoBreaks.match(reSeatingText[site]);
	if (result) {handin.seatText = result[1];}
	else {handin.seatText = " ";}

	handin.seatLines = handin.seatText.replace(/■/g, "\n");
	
	//find number of seats
	seats = handin.seatLines.match(reFindSeats[site]);
	handin.numPlayers = seats.length;
	
	// find button/bring-in?
	if (handin.unformatted.match(reButton[site])) {
		handin.button = RegExp.$1;
	}
	
	//find player names and stack sizes
	playerLines = handin.seatLines.match(reFindInfo[site]);
	handin.players = new Array;
	handin.stacks = new Array;
	handin.seatNumbers = new Array;

	j = 0;
	for (i = 0; i < handin.numPlayers; i = i + 1) {
		
		if (playerLines[i].match(rePlayerInfo[site])) {
			theSeat = RegExp.$1;
			thePlayer = RegExp.$2;
			theStack = RegExp.$3;
			if (!((playerLines[i].match(/sitting out/i) && (handin.gameType == "C") && (theSeat != handin.button)))){
				handin.seatNumbers[j] = theSeat;
				handin.players[j] = thePlayer;
				handin.stacks[j] = theStack;
				j++;
			}
		}
	}
	if (j > 0) { handin.numPlayers = j; }

	//find cards
	handin.holeCards = new Array;
	var myRegEx = new RegExp("");

	//get hero
	for (x = 0; x < handin.numPlayers; x++) {
		handin.holeCards[x] = new Array;
		myRegEx.compile(reGetHandPre[site] + handin.players[x] + reTDGetHandPost[site], "g");
		result = handin.unformattedNoBreaks.match(myRegEx);
		if (result) {
			handin.hero = handin.players[x];
			heropos = x;
			x = handin.numplayers;
		}
	}

	//initialize 2D arrays
	handin.action_types = new Array;
	handin.action_players = new Array;
	handin.action_values = new Array;
	handin.showdown_types = new Array;
	handin.action_addedToPot = new Array;
	handin.action_playersPot = new Array;

	for (r =0; r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}
	
	//get posted  blinds
	result = handin.unformatted.match(/(.+)\: posts small blind [\$]?(\d+\.\d+|\d+)/i);
	if (result) {
		handin.smallBlindPostedBy = result[1];
		handin.smallBlindPostedAmount = result[2];
		playerIndex = findIndex(handin.players, handin.smallBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.smallBlindPostedAmount;
		//handin.action_addedToPot[0] = handin.smallBlindPostedAmount;
	}

	
	result = handin.unformatted.match(/(.+)\: posts big blind [\$]?(\d+\.\d+|\d+)/i);
	if (result) {
		handin.bigBlindPostedBy = result[1];
		handin.bigBlindPostedAmount = result[2];
		playerIndex = findIndex(handin.players, handin.bigBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.bigBlindPostedAmount;
		//handin.action_addedToPot[0] += handin.bigBlindPostedAmount;
	}

	//get street cards named desire
	handin.communityCards = new Array;
	handin.communityCards[1] = new Array;
	cardCount = 0;
	var thisRegEx = new RegExp;
	
	//---first street - predraw
	x = 0;
	thisRegEx.compile(reSDStreetMatch[site]);
	outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
	
	if (!outerresult) {
		thisRegEx.compile(reTDStreetMatchAlt[site][x]);
		outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
	}
	if (outerresult) {
		
		//trim off final line
		var newRegEx = new RegExp;
		newRegEx.compile(/(.*)■.*?$/);
		trimmedresult = newRegEx.exec(outerresult[1]);
		
		handin = pokerStarsParseAction(handin, trimmedresult[1], x);
		myRegEx.compile("Dealt to " + handin.hero + "( \\[(.*)\\])");
		outerLines = outerresult[1].split(/■/);
		result = outerresult[1].match(myRegEx);
		if (!result) {
			myRegEx.compile(handin.hero + ": stands pat on (\\[(.*)\\])");
			result = outerresult[1].match(myRegEx);
		}
		if (result) {
			subresult = result[1].match(/([2-9TJQKA][hdsc])/g);
			numResults =subresult.length;
			for (y =0; y<numResults; ++y) {
				handin.holeCards[heropos][handin.holeCards[heropos].length] = subresult[y];
			}
		}
	}
	//zero out player contributions to pot for next street
	for (r=0;r< handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}
	//street match loop ended here

	//---second street - postdraw
	x = 1;
	var reSecondStreet = addslashes(trimmedresult[1]) + '(.*)■\\*\\*\\* SHOW DOWN';
	var reSecondStreetAlt = addslashes(trimmedresult[1]) + '(.*)■\\*\\*\\* SUMMARY';
	var thisRegEx = new RegExp;
	thisRegEx.compile(reSecondStreet);
	
	outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
	
	if (!outerresult) {
		thisRegEx.compile(reSecondStreetAlt);
		outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
	}
	if (outerresult) {
		
		
		
		handin = pokerStarsParseAction(handin, outerresult[1], x);
		myRegEx.compile("Dealt to " + handin.hero + "( \\[(.*)\\])");
		outerLines = outerresult[1].split(/■/);
		result = outerresult[1].match(myRegEx);
		if (!result) {
			myRegEx.compile(handin.hero + ": stands pat on (\\[(.*)\\])");
			result = outerresult[1].match(myRegEx);
		}
		if (result) {
			subresult = result[1].match(/([2-9TJQKA][hdsc])/g);
			numResults =subresult.length;
			for (y =0; y<numResults; ++y) {
				handin.holeCards[heropos][handin.holeCards[heropos].length] = subresult[y];
			}
		}
	}
	//zero out player contributions to pot for next street
	for (r =0;r< handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}
	
	//summary
	if (handin.unformattedNoBreaks.match(reMatchSummary[site])) {
		handin.showdownText = RegExp.$1;

		//if (handin.showdownText.match(reMatchSummary[site])) {
		//	handin.showdownText = RegExp.$1;
		//}
		handin.showdownLines = handin.showdownText.split(/■/);

		//initialize 2D arrays
		handin.showdown_hands = new Array;   // two pair, Fives and Fours
		handin.showdown_players = new Array; // <nick>
		handin.showdown_cards = new Array;   //  Jh Qs etc
		handin.showdown_types = new Array;   // won, lost, mucked, collected
		handin.result_players = new Array;
		handin.result_values = new Array;

		//loop through showdown lines
		playerCount = -1;
		resultCount = -1;
		for (i = 0; i < handin.showdownLines.length; i = i + 1) {
			if (site == HEM) {
				if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
					m = findIndex(handin.showdown_players,RegExp.$1);
					if (m == -1) { m = ++playercount; }
					//playerCount++;
					handin.showdown_players[m] = RegExp.$1;
					handin.showdown_types[m] = "won";
					if (handin.showdownLines[i].match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[m];
						handin.result_values[resultCount] = RegExp.$1;
					}
				}
				else if (result = handin.showdownLines[i].match(reTDSummaryExtraction2[site])) {
					m = findIndex(handin.showdown_players,result[1]);
					if (m > -1) {
						handin.showdown_cards[m] = new Array;
						handin.showdown_cards[m][0] = result[2];
						handin.showdown_cards[m][1] = result[3];
						handin.showdown_cards[m][2] = result[4];
						handin.showdown_cards[m][3] = result[5];
						handin.showdown_cards[m][4] = result[6];
						handin.showdown_hands[m] = " ";
					}
					else {
						playerCount++;
						handin.showdown_cards[playerCount] = new Array;
						handin.showdown_players[playerCount] = result[1];
						handin.showdown_types[playerCount] = "lost";
						handin.showdown_cards[playerCount][0] = result[2];
						handin.showdown_cards[playerCount][1] = result[3];
						handin.showdown_cards[playerCount][2] = result[4];
						handin.showdown_cards[playerCount][3] = result[5];
						handin.showdown_cards[playerCount][4] = result[6];
						handin.showdown_hands[playerCount] = " ";
					}
				}
			}
			else if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
				playerCount++;
				handin.showdown_players[playerCount] = RegExp.$1;
				handin.showdown_types[playerCount] = RegExp.$2;
				partTemp = RegExp.$3;
				if (site == CEREUS) { partTemp = RegExp.$2 + RegExp.$3; }
				if (partTemp.match(/( won | collected | wins )/)) {
					handin.showdown_types[playerCount] = "won";
				}
				//else {
				//	handin.showdown_types[playerCount] = "lost";
				//}
				handin.showdown_cards[playerCount] = new Array;
				if (partTemp) {
					if (partTemp.match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[playerCount];
						handin.result_values[resultCount] = RegExp.$1;
					}
					if (partTemp.match(reTDSummaryExtraction2[site])) {
						switch(site) {
						case PSTARS:
						case FTP:
							if (RegExp.$7) {
								handin.showdown_hands[playerCount] = RegExp.$7;
							}
							handin.showdown_cards[playerCount][0] = RegExp.$1;
							handin.showdown_cards[playerCount][1] = RegExp.$2;
							handin.showdown_cards[playerCount][2] = RegExp.$3;
							handin.showdown_cards[playerCount][3] = RegExp.$4;
							handin.showdown_cards[playerCount][4] = RegExp.$5;
							break;
						case CEREUS:
							handin.showdown_cards[playerCount][0] = RegExp.$3;
							handin.showdown_cards[playerCount][1] = RegExp.$4;
							handin.showdown_cards[playerCount][2] = RegExp.$5;
							handin.showdown_cards[playerCount][3] = RegExp.$6;
							handin.showdown_cards[playerCount][4] = RegExp.$7;
							handin.showdown_hands[playerCount] = RegExp.$2;
							break;
						}
					}
				}
				else { handin.showdown_cards[playerCount][0] = 'mucks'; }
			}
		}

		//rake
		if (handin.unformatted.match(reRake[site])) {
			handin.rake = RegExp.$1;
		}
	}

	return handin;

}

function parse_fivecarddraw(handin, site) {
//Cash or tournament?
	if (handin.firstLine.match(/Tournament/)) {
		handin.gameType = "T";
		//handin.error = "Tournament hands not yet supported.";
	} else {
		handin.gameType = "C";
	}

	//find blinds
	if (handin.firstLine.match(reBlinds[site])) {
		handin.smallBlind = RegExp.$1;
		handin.bigBlind = RegExp.$2;
	}

	handin.smallBlindPostedAmount = 0;
	handin.bigBlindPostedAmount = 0;

	//find game size
	if (handin.unformatted.match(reGameSize[site])) {
		handin.gameSize = RegExp.$1 + '-max';
	}
	else {
		handin.gameSize = "";
	}

	handin.antesTotal = 0;
	anteLines = new Array;
	//find antes
	anteText = handin.unformattedNoBreaks.match(reAnteText[site]);
   if (anteText) {
		anteLines = anteText[1].split(/■/);
		numAnteLines = anteLines.length;
		for (j=0;j<numAnteLines;j++) {
			if (anteLines[j].match(reAnteLines[site])) {
				handin.ante = RegExp.$1;
				handin.antesTotal = parseFloat(handin.antesTotal) + parseFloat(RegExp.$1);
			}
		}
	}
	
	result = handin.unformattedNoBreaks.match(reSeatingText[site]);
	if (result) {handin.seatText = result[1];}
	else {handin.seatText = " ";}

	handin.seatLines = handin.seatText.replace(/■/g, "\n");
	
	//find number of seats
	seats = handin.seatLines.match(reFindSeats[site]);
	handin.numPlayers = seats.length;
	
	// find button/bring-in?
	if (handin.unformatted.match(reButton[site])) {
		handin.button = RegExp.$1;
	}
	
	//find player names and stack sizes
	playerLines = handin.seatLines.match(reFindInfo[site]);
	handin.players = new Array;
	handin.stacks = new Array;
	handin.seatNumbers = new Array;

	j = 0;
	for (i = 0; i < handin.numPlayers; i = i + 1) {
		
		if (playerLines[i].match(rePlayerInfo[site])) {
			theSeat = RegExp.$1;
			thePlayer = RegExp.$2;
			theStack = RegExp.$3;
			if (!((playerLines[i].match(/sitting out/i) && (handin.gameType == "C") && (theSeat != handin.button)))){
				handin.seatNumbers[j] = theSeat;
				handin.players[j] = thePlayer;
				handin.stacks[j] = theStack;
				j++;
			}
		}
	}
	if (j > 0) { handin.numPlayers = j; }

	//find cards
	handin.holeCards = new Array;
	var myRegEx = new RegExp("");

	//get hero
	for (x = 0; x < handin.numPlayers; x++) {
		handin.holeCards[x] = new Array;
		myRegEx.compile(reGetHandPre[site] + addslashes(handin.players[x]) + reTDGetHandPost[site], "g");
		result = handin.unformattedNoBreaks.match(myRegEx);
		if (result) {
			handin.hero = handin.players[x];
			heropos = x;
			x = handin.numplayers;
		}
	}

	//initialize 2D arrays
	handin.action_types = new Array;
	handin.action_players = new Array;
	handin.action_values = new Array;
	handin.showdown_types = new Array;
	handin.action_addedToPot = new Array;
	handin.action_playersPot = new Array;

	for (r =0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}

	handin.antesTotal = 0;
	anteLines = new Array;
	anteText = handin.unformattedNoBreaks.match(/(.*?)\*\*\* DEAL/);
	anteLines = anteText[0].split(/■/);
	numAnteLines = anteLines.length;
	for (j=0;j<numAnteLines; ++j) {
		if (anteLines[j].match(/posts the ante [\$|](\d+\.\d+|\d+)/)) {
			handin.antesTotal = parseFloat(handin.antesTotal) + parseFloat(result[1]);
		}
	}
	
	result = handin.unformatted.match(/(.+)\: posts small blind [\$]?(\d+\.\d+|\d+)/i);
	if (result) {
		handin.smallBlindPostedBy = result[1];
		handin.smallBlindPostedAmount = result[2];
		playerIndex = findIndex(handin.players, handin.smallBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.smallBlindPostedAmount;
		
	}

	
	result = handin.unformatted.match(/(.+)\: posts big blind [\$]?(\d+\.\d+|\d+)/i);
	if (result) {
		handin.bigBlindPostedBy = result[1];
		handin.bigBlindPostedAmount = result[2];
		playerIndex = findIndex(handin.players, handin.bigBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.bigBlindPostedAmount;
		
	}

	//get street cards named desire
	handin.communityCards = new Array;
	handin.communityCards[1] = new Array;
	cardCount = 0;
	var thisRegEx = new RegExp;
	
	//---first street - predraw
	x = 0;
	thisRegEx.compile(reSDStreetMatch[site]);
	outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
			
	if (!outerresult) {
		thisRegEx.compile(reTDStreetMatchAlt[site][x]);
		outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
	}
	if (outerresult) {
		
		//trim off final line
		var newRegEx = new RegExp;
		newRegEx.compile(/(.*)■.*?$/);
		trimmedresult = newRegEx.exec(outerresult[1]);
		
		handin = pokerStarsParseAction(handin, trimmedresult[1], x);
		myRegEx.compile("Dealt to " + addslashes(handin.hero) + "( \\[(.*)\\])");
		outerLines = outerresult[1].split(/■/);
		result = outerresult[1].match(myRegEx);
		console.log('regex: %s',myRegEx);
		if (!result) {
			myRegEx.compile(addslashes(handin.hero) + ": stands pat on (\\[(.*)\\])");
			result = outerresult[1].match(myRegEx);
		}
		if (result) {
			console.log('matched');
			subresult = result[1].match(/([2-9TJQKA][hdsc])/g);
			numResults =subresult.length;
			for (y =0; y<numResults; ++y) {
				handin.holeCards[heropos][handin.holeCards[heropos].length] = subresult[y];
			}
		}
	}
	//zero out player contributions to pot for next street
	for (r=0; r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}
	//street match loope ended here

	//---second street - postdraw
	x = 1;
	var reSecondStreet = addslashes(trimmedresult[1]) + '(.*)■\\*\\*\\* SHOW DOWN';
	var reSecondStreetAlt = addslashes(trimmedresult[1]) + '(.*)■\\*\\*\\* SUMMARY';
	var thisRegEx = new RegExp;
	thisRegEx.compile(reSecondStreet);
	outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
			
	if (!outerresult) {
		thisRegEx.compile(reSecondStreetAlt);
		outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
	}
	if (outerresult) {
		
		
		
		handin = pokerStarsParseAction(handin, outerresult[1], x);
		myRegEx.compile("Dealt to " + addslashes(handin.hero) + "( \\[(.*)\\])");
		outerLines = outerresult[1].split(/■/);
		result = outerresult[1].match(myRegEx);
		if (!result) {
			myRegEx.compile(addslashes(handin.hero) + ": stands pat on (\\[(.*)\\])");
			result = outerresult[1].match(myRegEx);
		}
		if (result) {
			subresult = result[1].match(/([2-9TJQKA][hdsc])/g);
			numResults =subresult.length;
			for (y =0; y<numResults; ++y) {
				handin.holeCards[heropos][handin.holeCards[heropos].length] = subresult[y];
			}
		}
	}
	//zero out player contributions to pot for next street
	for (r=0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}
	
	//summary
	if (handin.unformattedNoBreaks.match(reMatchSummary[site])) {
		handin.showdownText = RegExp.$1;

		//if (handin.showdownText.match(reMatchSummary[site])) {
		//	handin.showdownText = RegExp.$1;
		//}
		handin.showdownLines = handin.showdownText.split(/■/);

		//initialize 2D arrays
		handin.showdown_hands = new Array;   // two pair, Fives and Fours
		handin.showdown_players = new Array; // <nick>
		handin.showdown_cards = new Array;   //  Jh Qs etc
		handin.showdown_types = new Array;   // won, lost, mucked, collected
		handin.result_players = new Array;
		handin.result_values = new Array;

		//loop through showdown lines
		playerCount = -1;
		resultCount = -1;
		for (i = 0; i < handin.showdownLines.length; i = i + 1) {
			if (site == HEM) {
				if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
					m = findIndex(handin.showdown_players,RegExp.$1);
					if (m == -1) { m = ++playercount; }
					//playerCount++;
					handin.showdown_players[m] = RegExp.$1;
					handin.showdown_types[m] = "won";
					if (handin.showdownLines[i].match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[m];
						handin.result_values[resultCount] = RegExp.$1;
					}
				}
				else if (result = handin.showdownLines[i].match(reTDSummaryExtraction2[site])) {
					m = findIndex(handin.showdown_players,result[1]);
					if (m > -1) {
						handin.showdown_cards[m] = new Array;
						handin.showdown_cards[m][0] = result[2];
						handin.showdown_cards[m][1] = result[3];
						handin.showdown_cards[m][2] = result[4];
						handin.showdown_cards[m][3] = result[5];
						handin.showdown_cards[m][4] = result[6];
						handin.showdown_hands[m] = " ";
					}
					else {
						playerCount++;
						handin.showdown_cards[playerCount] = new Array;
						handin.showdown_players[playerCount] = result[1];
						handin.showdown_types[playerCount] = "lost";
						handin.showdown_cards[playerCount][0] = result[2];
						handin.showdown_cards[playerCount][1] = result[3];
						handin.showdown_cards[playerCount][2] = result[4];
						handin.showdown_cards[playerCount][3] = result[5];
						handin.showdown_cards[playerCount][4] = result[6];
						handin.showdown_hands[playerCount] = " ";
					}
				}
			}
			else if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
				playerCount++;
				handin.showdown_players[playerCount] = RegExp.$1;
				handin.showdown_types[playerCount] = RegExp.$2;
				partTemp = RegExp.$3;
				if (site == CEREUS) { partTemp = RegExp.$2 + RegExp.$3; }
				if (partTemp.match(/( won | collected | wins )/)) {
					handin.showdown_types[playerCount] = "won";
				}
				//else {
				//	handin.showdown_types[playerCount] = "lost";
				//}
				handin.showdown_cards[playerCount] = new Array;
				if (partTemp) {
					if (partTemp.match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[playerCount];
						handin.result_values[resultCount] = RegExp.$1;
					}
					if (partTemp.match(reTDSummaryExtraction2[site])) {
						switch(site) {
						case PSTARS:
						case FTP:
							if (RegExp.$7) {
								handin.showdown_hands[playerCount] = RegExp.$7;
							}
							handin.showdown_cards[playerCount][0] = RegExp.$1;
							handin.showdown_cards[playerCount][1] = RegExp.$2;
							handin.showdown_cards[playerCount][2] = RegExp.$3;
							handin.showdown_cards[playerCount][3] = RegExp.$4;
							handin.showdown_cards[playerCount][4] = RegExp.$5;
							break;
						case CEREUS:
							handin.showdown_cards[playerCount][0] = RegExp.$3;
							handin.showdown_cards[playerCount][1] = RegExp.$4;
							handin.showdown_cards[playerCount][2] = RegExp.$5;
							handin.showdown_cards[playerCount][3] = RegExp.$6;
							handin.showdown_cards[playerCount][4] = RegExp.$7;
							handin.showdown_hands[playerCount] = RegExp.$2;
							break;
						}
					}
				}
				else { handin.showdown_cards[playerCount][0] = 'mucks'; }
			}
		}

		//rake
		if (handin.unformatted.match(reRake[site])) {
			handin.rake = RegExp.$1;
		}
	}

	return handin;

}

function parse_badugi(handin, site) {
	
	//Cash or tournament?
	if (handin.firstLine.match(/Tournament/)) {
		handin.gameType = "T";
		//handin.error = "Tournament hands not yet supported.";
	} else {
		handin.gameType = "C";
	}

	//find blinds
	if (handin.firstLine.match(reBlinds[site])) {
		handin.smallBlind = RegExp.$1;
		handin.bigBlind = RegExp.$2;
	}

	handin.smallBlindPostedAmount = 0;
	handin.bigBlindPostedAmount = 0;

	//find game size
	if (handin.unformatted.match(reGameSize[site])) {
		handin.gameSize = RegExp.$1 + '-max';
	}
	else {
		handin.gameSize = "";
	}

		
	result = handin.unformattedNoBreaks.match(reSeatingText[site]);
	if (result) {handin.seatText = result[1];}
	else {handin.seatText = " ";}

	handin.seatLines = handin.seatText.replace(/■/g, "\n");
	
	//find number of seats
	seats = handin.seatLines.match(reFindSeats[site]);
	handin.numPlayers = seats.length;
	
	// find button/bring-in?
	if (handin.unformatted.match(reButton[site])) {
		handin.button = RegExp.$1;
	}
	
	//find player names and stack sizes
	playerLines = handin.seatLines.match(reFindInfo[site]);
	handin.players = new Array;
	handin.stacks = new Array;
	handin.seatNumbers = new Array;

	j = 0;
	for (i = 0; i < handin.numPlayers; i = i + 1) {
		
		if (playerLines[i].match(rePlayerInfo[site])) {
			theSeat = RegExp.$1;
			thePlayer = RegExp.$2;
			theStack = RegExp.$3;
			if (!((playerLines[i].match(/sitting out/i) && (handin.gameType == "C") && (theSeat != handin.button)))){
				handin.seatNumbers[j] = theSeat;
				handin.players[j] = thePlayer;
				handin.stacks[j] = theStack;
				j++;
			}
		}
	}
	if (j > 0) { handin.numPlayers = j; }

	//find cards
	handin.holeCards = new Array;
	var myRegEx = new RegExp("");

	//get hero
	for (x = 0; x < handin.numPlayers; x++) {
		handin.holeCards[x] = new Array;
		myRegEx.compile(reGetHandPre[site] + handin.players[x] + reBadugiGetHandPost[site], "g");
		result = handin.unformattedNoBreaks.match(myRegEx);
		if (result) {
			handin.hero = handin.players[x];
			heropos = x;
			x = handin.numplayers;
		}
	}

	//initialize 2D arrays
	handin.action_types = new Array;
	handin.action_players = new Array;
	handin.action_values = new Array;
	handin.showdown_types = new Array;
	handin.action_addedToPot = new Array;
	handin.action_playersPot = new Array;

	for (r=0; r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}

	handin.antesTotal = 0;
	anteLines = new Array;
	anteText = handin.unformattedNoBreaks.match(/(.*?)\*\*\* DEAL/);
	anteLines = anteText[0].split(/■/);
	numAnteLines = anteLines.length;
	for (j=0;j<numAnteLines;j++) {
		if (anteLines[j].match(/posts the ante [\$|](\d+\.\d+|\d+)/)) {
			handin.antesTotal = parseFloat(handin.antesTotal) + parseFloat(result[1]);
		}
	}
	
	result = handin.unformatted.match(/(.+)\: posts small blind [\$]?(\d+\.\d+|\d+)/i);
	if (result) {
		handin.smallBlindPostedBy = result[1];
		handin.smallBlindPostedAmount = result[2];
		playerIndex = findIndex(handin.players, handin.smallBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.smallBlindPostedAmount;
		//handin.action_addedToPot[0] = handin.smallBlindPostedAmount;
	}

	
	result = handin.unformatted.match(/(.+)\: posts big blind [\$]?(\d+\.\d+|\d+)/i);
	if (result) {
		handin.bigBlindPostedBy = result[1];
		handin.bigBlindPostedAmount = result[2];
		playerIndex = findIndex(handin.players, handin.bigBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.bigBlindPostedAmount;
		//handin.action_addedToPot[0] += handin.bigBlindPostedAmount;
	}

	//get street cards named desire
	handin.communityCards = new Array;
	handin.communityCards[1] = new Array;
	cardCount = 0;
	var thisRegEx = new RegExp;
	for (x =0;x<reTDStreetMatch[site].length;x++) {
		thisRegEx.compile(reTDStreetMatch[site][x]);
		outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
		if (!outerresult) {
			thisRegEx.compile(reTDStreetMatchAlt[site][x]);
			outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
		}
		if (outerresult) {
			handin = pokerStarsParseAction(handin, outerresult[1], x);
			myRegEx.compile("Dealt to " + addslashes(handin.hero) + "( \\[(.*)\\])");
			outerLines = outerresult[1].split(/■/);
			result = outerresult[1].match(myRegEx);
			if (!result) {
				myRegEx.compile(addslashes(handin.hero) + ": stands pat on (\\[(.*)\\])");
				result = outerresult[1].match(myRegEx);
			}
			if (result) {
				subresult = result[1].match(/([2-9TJQKA][hdsc])/g);
				numResults =subresult.length;
				for (y =0; y<numResults; ++y) {
					handin.holeCards[heropos][handin.holeCards[heropos].length] = subresult[y];
				}
			}
		}
		//zero out player contributions to pot for next street
		for (r=0; r<handin.players.length;r++) {
			handin.action_playersPot[r] = 0;
		}
	}

	//summary
	if (handin.unformattedNoBreaks.match(reMatchSummary[site])) {
		handin.showdownText = RegExp.$1;

		//if (handin.showdownText.match(reMatchSummary[site])) {
		//	handin.showdownText = RegExp.$1;
		//}
		handin.showdownLines = handin.showdownText.split(/■/);

		//initialize 2D arrays
		handin.showdown_hands = new Array;   // two pair, Fives and Fours
		handin.showdown_players = new Array; // <nick>
		handin.showdown_cards = new Array;   //  Jh Qs etc
		handin.showdown_types = new Array;   // won, lost, mucked, collected
		handin.result_players = new Array;
		handin.result_values = new Array;

		//loop through showdown lines
		playerCount = -1;
		resultCount = -1;
		for (i = 0; i < handin.showdownLines.length; i = i + 1) {
			if (site == HEM) {
				if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
					m = findIndex(handin.showdown_players,RegExp.$1);
					if (m == -1) { m = ++playercount; }
					//playerCount++;
					handin.showdown_players[m] = RegExp.$1;
					handin.showdown_types[m] = "won";
					if (handin.showdownLines[i].match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[m];
						handin.result_values[resultCount] = RegExp.$1;
					}
				}
				else if (result = handin.showdownLines[i].match(reBadugiSummaryExtraction2[site])) {
					m = findIndex(handin.showdown_players,result[1]);
					if (m > -1) {
						handin.showdown_cards[m] = new Array;
						handin.showdown_cards[m][0] = result[2];
						handin.showdown_cards[m][1] = result[3];
						handin.showdown_cards[m][2] = result[4];
						handin.showdown_cards[m][3] = result[5];
						handin.showdown_hands[m] = " ";
					}
					else {
						playerCount++;
						handin.showdown_cards[playerCount] = new Array;
						handin.showdown_players[playerCount] = result[1];
						handin.showdown_types[playerCount] = "lost";
						handin.showdown_cards[playerCount][0] = result[2];
						handin.showdown_cards[playerCount][1] = result[3];
						handin.showdown_cards[playerCount][2] = result[4];
						handin.showdown_cards[playerCount][3] = result[5];
						handin.showdown_hands[playerCount] = " ";
					}
				}
			}
			else if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
				playerCount++;
				handin.showdown_players[playerCount] = RegExp.$1;
				handin.showdown_types[playerCount] = RegExp.$2;
				partTemp = RegExp.$3;
				if (site == CEREUS) { partTemp = RegExp.$2 + RegExp.$3; }
				if (partTemp.match(/( won | collected | wins )/)) {
					handin.showdown_types[playerCount] = "won";
				}
				//else {
				//	handin.showdown_types[playerCount] = "lost";
				//}
				handin.showdown_cards[playerCount] = new Array;
				if (partTemp) {
					if (partTemp.match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[playerCount];
						handin.result_values[resultCount] = RegExp.$1;
					}
					if (partTemp.match(reBadugiSummaryExtraction2[site])) {
						switch(site) {
						case PSTARS:
						case FTP:
							if (RegExp.$6) {
								handin.showdown_hands[playerCount] = RegExp.$6;
							}
							handin.showdown_cards[playerCount][0] = RegExp.$1;
							handin.showdown_cards[playerCount][1] = RegExp.$2;
							handin.showdown_cards[playerCount][2] = RegExp.$3;
							handin.showdown_cards[playerCount][3] = RegExp.$4;
							break;
						case CEREUS:
							handin.showdown_cards[playerCount][0] = RegExp.$3;
							handin.showdown_cards[playerCount][1] = RegExp.$4;
							handin.showdown_cards[playerCount][2] = RegExp.$5;
							handin.showdown_cards[playerCount][3] = RegExp.$6;
							handin.showdown_hands[playerCount] = RegExp.$2;
							break;
						}
					}
				}
				else { handin.showdown_cards[playerCount][0] = 'mucks'; }
			}
		}
		

		//rake
		if (handin.unformatted.match(reRake[site])) {
			handin.rake = RegExp.$1;
		}
	}

	return handin;



}

function parse_stud(handin, site) {

	//Cash or tournament?
	if (handin.firstLine.match(/Tournament/)) {
		handin.gameType = "T";
		//handin.error = "Tournament hands not yet supported.";
	} else {
		handin.gameType = "C";
	}

	//find blinds
	if (handin.firstLine.match(reBlinds[site])) {
		handin.smallBlind = RegExp.$1;
		handin.bigBlind = RegExp.$2;
	}

	handin.smallBlindPostedAmount = 0;
	handin.bigBlindPostedAmount = 0;

	//find game size
	if (handin.unformatted.match(reGameSize[site])) {
		handin.gameSize = RegExp.$1 + '-max';
	}
	else {
		handin.gameSize = "";
	}

	handin.antesTotal = 0;
	anteLines = new Array;
	//find antes
	anteText = handin.unformattedNoBreaks.match(reAnteText[site]);
	anteLines = anteText[1].split(/■/);
	numAnteLines = anteLines.length;
		for (j=0;j<numAnteLines;++j) {
		if (anteLines[j].match(reAnteLines[site])) {
			handin.ante = RegExp.$1;
			handin.antesTotal = parseFloat(handin.antesTotal) + parseFloat(RegExp.$1);
		}
	}

	result = handin.unformattedNoBreaks.match(reSeatingText[site]);
	if (result) {handin.seatText = result[1];}
	else {handin.seatText = " ";}

	handin.seatLines = handin.seatText.replace(/■/g, "\n");
	
	//find number of seats
	seats = handin.seatLines.match(reFindSeats[site]);
	handin.numPlayers = seats.length;
	
	// find button/bring-in?
	if (handin.unformatted.match(reButton[site])) {
		handin.button = RegExp.$1;
	}
	
	//find player names and stack sizes
	playerLines = handin.seatLines.match(reFindInfo[site]);
	handin.players = new Array;
	handin.stacks = new Array;
	handin.seatNumbers = new Array;

	j = 0;
	for (i = 0; i < handin.numPlayers; i = i + 1) {
		
		if (playerLines[i].match(rePlayerInfo[site])) {
			theSeat = RegExp.$1;
			thePlayer = RegExp.$2;
			theStack = RegExp.$3;
			if (!((playerLines[i].match(/sitting out/i) && (handin.gameType == "C") && (theSeat != handin.button)))){
				handin.seatNumbers[j] = theSeat;
				handin.players[j] = thePlayer;
				handin.stacks[j] = theStack;
				j++;
			}
		}
	}
	if (j > 0) { handin.numPlayers = j; }

	// find button/bring-in?
	if (handin.unformatted.match(reButton[site])) {
		handin.button = RegExp.$1;
	}

	//find cards
	handin.holeCards = new Array;
	var myRegEx = new RegExp("");

	//get hero
	var thisRegEx = new RegExp;
	thisRegEx.compile(reStreetMatch[site][0]);
	dealtCards = thisRegEx.exec(handin.unformattedNoBreaks);
	if (!dealtCards) { 
		thisRegEx.compile(reStreetMatchAlt[site][0]);
		dealtCards = thisRegEx.exec(handin.unformattedNoBreaks);
	}
	for (x = 0; x < handin.numPlayers; x++) {
		handin.holeCards[x] = new Array;
		myRegEx.compile(reGetHandPre[site] + handin.players[x] + reGetHandPost[site], "g");
		subresult = dealtCards.join("■").match(myRegEx);
		if (subresult) {
			handin.hero = handin.players[x];
		}
		myRegEx.compile(reGetHandPre[site] + escapeText(handin.players[x]) + reGetHandPost2[site], "g");
		result = handin.unformatted.match(myRegEx);
		if (result) {
			z = result.length - 1;
		} else {
			z = -1;
		}
		w = 0;
		if (z >= 0) {
			subresult = result[z].match(reMatchCard[site]);
			handOffset = 0;
			if ((handin.players[x] != handin.hero) && (subresult.length < 7)) {
				handOffset = 2;
				handin.holeCards[x][0] = '1s';
				handin.holeCards[x][1] = '1s';
			}
			else if ((handin.players[x] == handin.hero) && (subresult.length == 7) && (result[z-1].match(reMatchCard[site]).length == 7)) {
				subresult = result[z-1].match(reMatchCard[site]);
			}
			numResults =subresult.length;
			for (y =0; y<numResults; ++y) {
				handin.holeCards[x][w + handOffset] = subresult[y];
				w++;
			}
			z--;
		}
	}

	//initialize 2D arrays
	handin.action_types = new Array;
	handin.action_players = new Array;
	handin.action_values = new Array;
	handin.showdown_types = new Array;
	handin.action_addedToPot = new Array;
	handin.action_playersPot = new Array;

	//get street cards named desire
	handin.communityCards = new Array;
	handin.communityCards[1] = new Array;
	cardCount = 0;
	var thisRegEx = new RegExp;
	for (x = 0; x < 5; x++) {
		//zero out player contributions to pot for this street
		for (r=0;r<handin.players.length;r++) {
			handin.action_playersPot[r] = 0;
		}
		thisRegEx.compile(reStreetMatch[site][x]);
		result = thisRegEx.exec(handin.unformattedNoBreaks);
		if (!result) {
			thisRegEx.compile(reStreetMatchAlt[site][x]);
			result = thisRegEx.exec(handin.unformattedNoBreaks);
		}
		if (result) {
			if (site == PSTARS) {
				handin = pokerStarsParseAction(handin, result[1], x);
			}
			else if (site == FTP) {
				handin = ftpParseAction(handin, result[1], x);
			}
			else if (site == CEREUS) {
				handin = cereusParseAction(handin, result[1], x);
			}
		}
	}

	//summary
	if (handin.unformattedNoBreaks.match(reMatchSummary[site])) {
		handin.showdownText = RegExp.$1;

		//if (handin.showdownText.match(reMatchSummary[site])) {
		//	handin.showdownText = RegExp.$1;
		//}
		handin.showdownLines = handin.showdownText.split(/■/);

		//initialize 2D arrays
		handin.showdown_hands = new Array;   // two pair, Fives and Fours
		handin.showdown_players = new Array; // <nick>
		handin.showdown_cards = new Array;   //  Jh Qs etc
		handin.showdown_types = new Array;   // won, lost, mucked, collected
		handin.result_players = new Array;
		handin.result_values = new Array;

		//loop through showdown lines
		playerCount = -1;
		resultCount = -1;
		for (i = 0; i < handin.showdownLines.length; i = i + 1) {
			if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
				playerCount++;
				handin.showdown_players[playerCount] = RegExp.$1;
				handin.showdown_types[playerCount] = RegExp.$2;
				partTemp = RegExp.$3;
				if (site == CEREUS) { partTemp = RegExp.$2 + RegExp.$3; }
				if (partTemp.match(/( won | collected )/)) {
					handin.showdown_types[playerCount] = "won";
				}
				//else {
				//	handin.showdown_types[playerCount] = "lost";
				//}
				handin.showdown_cards[playerCount] = new Array;
				if (partTemp) {
					if (partTemp.match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[playerCount];
						handin.result_values[resultCount] = RegExp.$1;
					}
					if (partTemp.match(reStudSummaryExtraction2[site])) {
						switch(site) {
						case PSTARS:
						case FTP:
							if (RegExp.$9) {
								handin.showdown_hands[playerCount] = RegExp.$9;
							}
							else { handin.showdown_hands[playerCount] = " "; }
							break;
						case CEREUS:
							handin.showdown_hands[playerCount] = RegExp.$2;
							break;
						}
					}
				}
				else { handin.showdown_cards[playerCount][0] = 'mucks'; }
			}
		}

		//rake
		if (handin.unformatted.match(reRake[site])) {
			handin.rake = RegExp.$1;
		}
	}

	return handin;

}

function parse_holdem(handin, site) {

	//Cash or tournament?
	if (handin.unformatted.match(reGameType[site])) {
		handin.gameType = "T";
	} else {
		handin.gameType = "C";
	}


	//find blinds
	if (handin.unformatted.match(reBlinds[site])) {
		handin.smallBlind = RegExp.$1;
		handin.bigBlind = RegExp.$2;
	}

	handin.smallBlindPostedAmount = 0;
	handin.bigBlindPostedAmount = 0;

	//find game size
	if (handin.unformatted.match(reGameSize[site])) {
		handin.gameSize = RegExp.$1 + '-max';
	}
	else {
		handin.gameSize = "";
	}

	handin.antesTotal = 0;
	anteLines = new Array;
	//find antes
	anteText = handin.unformattedNoBreaks.match(reAnteText[site]);
   if (anteText) {
		anteLines = anteText[1].split(/■/);
		numAnteLines = anteLines.length;
		for (j=0;j<numAnteLines;++j) {
			if (anteLines[j].match(reAnteLines[site])) {
				handin.ante = RegExp.$1;
				handin.antesTotal = parseFloat(handin.antesTotal) + parseFloat(RegExp.$1);
			}
		}
	}
	
	result = handin.unformattedNoBreaks.match(reSeatingText[site]);
	if (result) {handin.seatText = result[1];}
	else {handin.seatText = " ";}

	
	handin.seatLines = handin.seatText.replace(/■/g, "\n");
	
	//find number of seats
	seats = handin.seatLines.match(reFindSeats[site]);
	handin.numPlayers = seats.length;
	
	// find button/bring-in?
	if (handin.unformatted.match(reButton[site])) {
		handin.button = RegExp.$1;
	}
	
	//find player names and stack sizes
	playerLines = handin.seatLines.match(reFindInfo[site]);
	handin.players = new Array;
	handin.stacks = new Array;
	handin.seatNumbers = new Array;

	j = 0;
	for (i = 0; i < handin.numPlayers; i = i + 1) {
		
		if (playerLines[i].match(rePlayerInfo[site])) {
			theSeat = RegExp.$1;
			thePlayer = RegExp.$2;
			theStack = RegExp.$3;
			if (!((playerLines[i].match(/sitting out/i) && (handin.gameType == "C") && (theSeat != handin.button)))){
				handin.seatNumbers[j] = theSeat;
				handin.players[j] = thePlayer;
				handin.stacks[j] = theStack;
				j++;
			}
		}
	}
	if (j > 0) { handin.numPlayers = j; }


	//find hole cards
	handin.holeCards = new Array;
	handin.holeCards[0] = new Array;
	
	if (handin.site == "Titan") {
		
		
		//have to get hero first since hole cards for all showdown players listed together
		handin.unformatted.match(reHero[site]);
		handin.hero=RegExp.$1;
		
		//make regex to get hero's hole cards
		reHeroHoleCards = 'cards type=\"Pocket\" player=\"' + addslashes(handin.hero)+ '\">([HDSC][2-9TJQKA]) ([HDSC][2-9TJQKA])';
		
		if (handin.unformatted.match(reHeroHoleCards)) {
		
			
			handin.holeCards[0][0] = RegExp.$1;
			handin.holeCards[0][1] = RegExp.$2;
			
			//swap card text
			handin.holeCards[0][0] = reverseCards(handin.holeCards[0][0]).capitalize();
			handin.holeCards[0][1] = reverseCards(handin.holeCards[0][1]).capitalize();
			
		}	
		

		
				
	} else {
		
		if (handin.unformatted.match(reHEHoleCards[site])) {
			
			handin.hero = RegExp.$1;
			handin.holeCards[0][0] = RegExp.$2;
			handin.holeCards[0][1] = RegExp.$3;
		}
	}
	//initialize 2D arrays
	handin.action_types = new Array;
	handin.action_players = new Array;
	handin.action_values = new Array;
	handin.action_addedToPot = new Array;
	handin.action_playersPot = new Array;

	//zero out player contributions to pot for this street
	for (r=0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}

	handin.currentAction = 0;
	//but add in SB
	if (handin.unformatted.match(reSmallBlind[site])) {
		handin.smallBlindPostedBy = RegExp.$1;
		handin.smallBlindPostedAmount = RegExp.$2;;
		//playerIndex = handin.players.indexOf(handin.smallBlindPostedBy);
		playerIndex = findIndex(handin.players, handin.smallBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.smallBlindPostedAmount;
	}
	//and BB
	if (handin.unformatted.match(reBigBlind[site])) {
		handin.bigBlindPostedBy = RegExp.$1;
		handin.bigBlindPostedAmount = RegExp.$2;
		playerIndex = findIndex(handin.players, handin.bigBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.bigBlindPostedAmount;
		//for titan, find action number of Big Blind
		if (site==TITAN) {
			
			reBBaction = '<action no=\"(\\d)\" player=\"' +handin.bigBlindPostedBy+'\" type=\"2\"';
			if (handin.unformatted.match(reBBaction)) {
				handin.currentAction = cleanNum(RegExp.$1);
				
			}  
		
		}
	}
	
	if (!handin.smallBlind) {
		handin.smallBlind = handin.smallBlindPostedAmount;
		handin.bigBlind = handin.bigBlindPostedAmount;
	}	
	//find preflop action
	result = handin.unformattedNoBreaks.match(rePreflopAction[site]);
	if (!result) { result = handin.unformattedNoBreaks.match(rePreflopActionAlt[site]); }
	if (result) {
		handin.preflopText = RegExp.$1;
		if (site == PSTARS) { handin = pokerStarsParseAction(handin, handin.preflopText, 0); }
		if (site == FTP) { handin = ftpParseAction(handin, handin.preflopText, 0); }
		else if (site == CEREUS) { handin = cereusParseAction(handin, handin.preflopText, 0); }
		else if (site == HEM) {handin = HEMParseAction(handin,handin.preflopText,0);}
		else if (site == TITAN) {handin = titanParseAction(handin,handin.preflopText,0);}
	}

	//get flop cards
	handin.communityCards = new Array;
	handin.communityCards[1] = new Array;
	if (handin.unformatted.match(reFlop[site])) {
		handin.communityCards[1][0] = RegExp.$1;
		handin.communityCards[1][1] = RegExp.$2;
		handin.communityCards[1][2] = RegExp.$3;
		
		if (site == TITAN) {
			handin.communityCards[1][0] = reverseCards(handin.communityCards[1][0]).capitalize();
			handin.communityCards[1][1] = reverseCards(handin.communityCards[1][1]).capitalize();
			handin.communityCards[1][2] = reverseCards(handin.communityCards[1][2]).capitalize();
		}
	}
	else {
		myRegEx = new RegExp;
		myRegEx = myRegEx.compile(reFlopRunIt[site],"g");
	   result = handin.unformatted.match(myRegEx);
		if (result) {
		   i = 0; j = 0;
			myRegEx = myRegEx.compile(reFlopRunIt[site]);
			while (result[i]) {
			   subresult = result[i].match(myRegEx);
			   handin.communityCards[1][j++] = subresult[2];
			   handin.communityCards[1][j++] = subresult[3];
			   handin.communityCards[1][j++] = subresult[4];
				i++;
			}
		}
	}

	//zero out player contributions to pot for this street
	for (r=0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}

	//find flop action
	result = handin.unformattedNoBreaks.match(reFlopAction[site]);
	if (!result) { result = handin.unformattedNoBreaks.match(reFlopActionAlt[site]); }
	if (result) {
		handin.flopText = RegExp.$1;
		if (site == PSTARS) { handin = pokerStarsParseAction(handin, handin.flopText, 1); }
		else if (site == FTP) { handin = ftpParseAction(handin, handin.flopText, 1); }
		else if (site == CEREUS) { handin = cereusParseAction(handin, handin.flopText, 1); }
		else if (site == HEM) {handin = HEMParseAction(handin,handin.flopText,1);}
		else if (site == TITAN) {handin = titanParseAction(handin,handin.flopText,1);}
	}

	//get turn card
	handin.communityCards[2] = new Array;
	if (handin.unformatted.match(reTurn[site])) {
		handin.communityCards[2][0] = RegExp.$1;
		if (site == TITAN) {
			handin.communityCards[2][0] = reverseCards(handin.communityCards[2][0]).capitalize();
		}
	}
	else {
		myRegEx = new RegExp;
		myRegEx = myRegEx.compile(reTurnRunIt[site],"g");
	   result = handin.unformatted.match(myRegEx);
		if (result) {
		   i = 0; j = 0;
			myRegEx = myRegEx.compile(reTurnRunIt[site]);
			while (result[i]) {
			   subresult = result[i].match(myRegEx);
			   handin.communityCards[2][j++] = subresult[2];
				i++;
			}
		}
	}
	//zero out player contributions to pot for this street
	for (r=0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}

	//find turn action
	result = handin.unformattedNoBreaks.match(reTurnAction[site]);
	if (!result) { result = handin.unformattedNoBreaks.match(reTurnActionAlt[site]); }
	if (result) {
		handin.turnText = RegExp.$1;
		if (site == PSTARS) { handin = pokerStarsParseAction(handin, handin.turnText, 2); }
		else if (site == FTP) { handin = ftpParseAction(handin, handin.turnText, 2); }
		else if (site == CEREUS) { handin = cereusParseAction(handin, handin.turnText, 2); }
		else if (site == HEM) {handin = HEMParseAction(handin,handin.turnText,2);}
		else if (site == TITAN) {handin = titanParseAction(handin,handin.turnText,2);}
	}

	//get river card
	handin.communityCards[3] = new Array;
	if (handin.unformatted.match(reRiver[site])) {
		handin.communityCards[3][0] = RegExp.$1;
		if (site == TITAN) {
			handin.communityCards[3][0] = reverseCards(handin.communityCards[3][0]).capitalize();
		}
	}
	else {
		myRegEx = new RegExp;
		myRegEx = myRegEx.compile(reRiverRunIt[site],"g");
	   result = handin.unformatted.match(myRegEx);
		if (result) {
		   i = 0; j = 0;
		   myRegEx = new RegExp;
			myRegEx = myRegEx.compile(reRiverRunIt[site]);
			while (result[i]) {
				//myRegEx = myRegEx.compile(reRiverRunIt[site]);
			   subresult = result[i].match(myRegEx);
			   handin.communityCards[3][j++] = subresult[2];
				i++;
			}
		}
	}
	//zero out player contributions to pot for this street
	for (r=0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}

	//find river action
	result = handin.unformattedNoBreaks.match(reRiverAction[site]);
	if (!result) { result = handin.unformattedNoBreaks.match(reRiverActionAlt[site]); }
	if (result) {
		handin.riverText = RegExp.$1;
		if (site == PSTARS) { handin = pokerStarsParseAction(handin, handin.riverText, 3); }
		else if (site == FTP) { handin = ftpParseAction(handin, handin.riverText, 3); }
		else if (site == CEREUS) { handin = cereusParseAction(handin, handin.riverText, 3); }
		else if (site == HEM) {handin = HEMParseAction(handin,handin.riverText,3);}
		else if (site == TITAN) {handin = titanParseAction(handin,handin.riverText,3);}
	}

	//summary
	
	//initialize 2D arrays
	handin.showdown_hands = new Array;   // two pair, Fives and Fours
	handin.showdown_players = new Array; // <nick>
	handin.showdown_cards = new Array;   //  Jh Qs etc
	handin.showdown_types = new Array;   // won, lost, mucked, collected
	handin.result_players = new Array;
	handin.result_values = new Array;
	
	//has to be done differently for XML hhs like Titan or RPM
	if (site!=TITAN){
		if (handin.unformattedNoBreaks.match(reMatchSummary[site])) {
		
			handin.showdownText = RegExp.$1;
	
			handin.showdownLines = handin.showdownText.split(/■/);
	
		
	
			//loop through showdown lines
			playerCount = -1;
			resultCount = -1;
			
			for (i = 0; i < handin.showdownLines.length; i = i + 1) {
				if (site == HEM) {
					
					if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
						m = findIndex(handin.showdown_players,RegExp.$1);
						if (m == -1) { m = ++playerCount; }
						//playerCount++;
						handin.showdown_players[m] = RegExp.$1;
						handin.showdown_types[m] = "won";
						if (handin.showdownLines[i].match(reTheMoney[site])) {
							resultCount++;
							handin.result_players[resultCount] = handin.showdown_players[m];
							handin.result_values[resultCount] = RegExp.$1;
						}
						
	
					}
					else if (result = handin.showdownLines[i].match(reHESummaryExtraction2[site])) {
						
						m = findIndex(handin.showdown_players,result[1]);
						if (m > -1) {
							handin.showdown_cards[m] = new Array;
							handin.showdown_cards[m][0] = result[2];
							handin.showdown_cards[m][1] = result[3];
							handin.showdown_hands[m] = " ";
						}
						else {
							playerCount++;
							handin.showdown_cards[playerCount] = new Array;
							handin.showdown_players[playerCount] = result[1];
							handin.showdown_types[playerCount] = "lost";
							handin.showdown_cards[playerCount][0] = result[2];
							handin.showdown_cards[playerCount][1] = result[3];
							handin.showdown_hands[playerCount] = " ";
						}
						
					}
				}
				else if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
					playerCount++;
					handin.showdown_players[playerCount] = RegExp.$1;
					handin.showdown_types[playerCount] = RegExp.$2;
					partTemp = RegExp.$3;
					if (site == CEREUS) { partTemp = RegExp.$2 + RegExp.$3; }
					if (partTemp.match(/( won | collected )/)) {
						handin.showdown_types[playerCount] = "won";
					}
					//else {
					//	handin.showdown_types[playerCount] = "lost";
					//}
					handin.showdown_cards[playerCount] = new Array;
					if (partTemp) {
						if (partTemp.match(reTheMoney[site])) {
							resultCount++;
							handin.result_players[resultCount] = handin.showdown_players[playerCount];
							handin.result_values[resultCount] = RegExp.$1;
						}
						if (partTemp.match(reHESummaryExtraction2[site])) {
							switch(site) {
							case PSTARS:
							case FTP:
								handin.showdown_cards[playerCount][0] = RegExp.$1;
								handin.showdown_cards[playerCount][1] = RegExp.$2;
								if (RegExp.$4) {
									handin.showdown_hands[playerCount] = RegExp.$4;
								}
								break;
							case CEREUS:
								handin.showdown_cards[playerCount][0] = RegExp.$3;
								handin.showdown_cards[playerCount][1] = RegExp.$4;
								handin.showdown_hands[playerCount] = RegExp.$2;
								break;
							}
						}
					}
					else { handin.showdown_cards[playerCount][0] = 'mucks'; }
				}
			}
	
			//rake
			if (handin.unformatted.match(reRake[site])) {
				handin.rake = RegExp.$1;
			}
		}
	} else if (site==TITAN) {
		//Summary extraction for Titan
		
		
		//loop through players, find any with hole cards who are not hero -- these went to showdown
		
		showdownCount = 0;
		resultCount = 0;
		heroWon = 0;
		for (i =0;i<handin.players.length;i++) {
		
			if (handin.players[i] != handin.hero) {
			
				
				//check for hole cards
				reHoleCards = 'cards type=\"Pocket\" player=\"' + handin.players[i]+ '\">([HDSC][2-9TJQKA]) ([HDSC][2-9TJQKA])';
				if (handin.unformatted.match(reHoleCards)) {
				
				   handin.showdown_players[showdownCount] = handin.players[i];
				   handin.showdown_cards[showdownCount] = new Array;
				   handin.showdown_cards[showdownCount][0] = RegExp.$1;
				   handin.showdown_cards[showdownCount][1] = RegExp.$2;
				   
				   handin.showdown_cards[showdownCount][0] = reverseCards(handin.showdown_cards[showdownCount][0]).capitalize();
				   handin.showdown_cards[showdownCount][1] = reverseCards(handin.showdown_cards[showdownCount][1]).capitalize();
				   
				   handin.showdown_hands[showdownCount] = '';
										
				   showdownCount = showdownCount + 1;
				}
			}
			//check for winner
			reWinner = '<player seat=\".*?\" name=\"' + handin.players[i] + '\" chips=\".*?\" dealer=\".*?\" win=\"' + addslashes(handin.currency) + '(.*?)\" bet';
			
			if (handin.unformatted.match(reWinner)) {
				won = RegExp.$1;
				
				if (won != "0") {
							
					handin.result_players[resultCount] = handin.players[i];
					handin.result_values[resultCount] = won;
					resultCount = resultCount + 1;
					if (handin.players[i] == handin.hero) {heroWon = 1;}
				}
			}
			
			//show hero's cards? only if his are not the only hole cards and he won
			if (showdownCount > 0) {
			
				if (heroWon) {
					handin.showdown_players[showdownCount] = handin.hero;
					handin.showdown_cards[showdownCount] = new Array;
					handin.showdown_cards[showdownCount][0] = handin.holeCards[0][0];
					handin.showdown_cards[showdownCount][1] = handin.holeCards[0][1];
					handin.showdown_hands[showdownCount] = '';
				}
			}
			
		}
	}
	return handin;

}

function parse_omaha(handin, site) {

	//Cash or tournament?
	if (handin.firstLine.match(/\$\d/)) {
		handin.gameType = "C";
		//handin.error = "Tournament hands not yet supported.";
	} else {
		handin.gameType = "T";
	}

	//find blinds
	if (handin.firstLine.match(reBlinds[site])) {
		handin.smallBlind = RegExp.$1;
		handin.bigBlind = RegExp.$2;
	}

	handin.smallBlindPostedAmount = 0;
	handin.bigBlindPostedAmount = 0;

	//find game size
	if (handin.unformatted.match(reGameSize[site])) {
		handin.gameSize = RegExp.$1 + '-max';
	}
	else {
		handin.gameSize = "";
	}

	handin.antesTotal = 0;
	anteLines = new Array;
	//find antes
	anteText = handin.unformattedNoBreaks.match(reAnteText[site]);
   if (anteText) {
		anteLines = anteText[1].split(/■/);
		numAnteLines = anteLines.length;
		for (j=0;j<numAnteLines;++j) {
			if (anteLines[j].match(reAnteLines[site])) {
				handin.ante = RegExp.$1;
				handin.antesTotal = parseFloat(handin.antesTotal) + parseFloat(RegExp.$1);
			}
		}
	}
	
	result = handin.unformattedNoBreaks.match(reSeatingText[site]);
	if (result) {handin.seatText = result[1];}
	else {handin.seatText = " ";}

	handin.seatLines = handin.seatText.replace(/■/g, "\n");
	
	//find number of seats
	seats = handin.seatLines.match(reFindSeats[site]);
	handin.numPlayers = seats.length;
	
	// find button/bring-in?
	if (handin.unformatted.match(reButton[site])) {
		handin.button = RegExp.$1;
	}
	
	//find player names and stack sizes
	playerLines = handin.seatLines.match(reFindInfo[site]);
	handin.players = new Array;
	handin.stacks = new Array;
	handin.seatNumbers = new Array;

	j = 0;
	for (i = 0; i < handin.numPlayers; i = i + 1) {
	
		if (playerLines[i].match(rePlayerInfo[site])) {
			theSeat = RegExp.$1;
			thePlayer = RegExp.$2;
			theStack = RegExp.$3;
			if (!((playerLines[i].match(/sitting out/i) && (handin.gameType == "C") && (theSeat != handin.button)))){
				handin.seatNumbers[j] = theSeat;
				handin.players[j] = thePlayer
				handin.stacks[j] = theStack;
				j++;
			}
		}
	}
	if (j > 0) { handin.numPlayers = j; }


	//find hole cards
	handin.holeCards = new Array;
	handin.holeCards[0] = new Array;
	if (handin.unformatted.match(reOHoleCards[site])) {
		handin.hero = RegExp.$1
		handin.holeCards[0][0] = RegExp.$2;
		handin.holeCards[0][1] = RegExp.$3;
		handin.holeCards[0][2] = RegExp.$4;
		handin.holeCards[0][3] = RegExp.$5;
	}

	//initialize 2D arrays
	handin.action_types = new Array;
	handin.action_players = new Array;
	handin.action_values = new Array;
	handin.action_addedToPot = new Array;
	handin.action_playersPot = new Array;

	//zero out player contributions to pot for this street
	for (r=0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}

	//but add in SB
	if (handin.unformatted.match(reSmallBlind[site])) {
		handin.smallBlindPostedBy = RegExp.$1;
		handin.smallBlindPostedAmount = RegExp.$2;
		//playerIndex = handin.players.indexOf(handin.smallBlindPostedBy);
		playerIndex = findIndex(handin.players, handin.smallBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.smallBlindPostedAmount;
	}
	//and BB
	if (handin.unformatted.match(reBigBlind[site])) {
		handin.bigBlindPostedBy = RegExp.$1;
		handin.bigBlindPostedAmount = RegExp.$2;
		//playerIndex = handin.players.indexOf(handin.bigBlindPostedBy);
		playerIndex = findIndex(handin.players, handin.bigBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.bigBlindPostedAmount;
	}
	
	if (!handin.smallBlind) {
		handin.smallBlind = handin.smallBlindPostedAmount;
		handin.bigBlind = handin.bigBlindPostedAmount;
	}	
	//find preflop action
	result = handin.unformattedNoBreaks.match(rePreflopAction[site]);
	if (!result) { result = handin.unformattedNoBreaks.match(rePreflopActionAlt[site]); }
	if (result) {
		handin.preflopText = RegExp.$1;
		if (site == PSTARS) { handin = pokerStarsParseAction(handin, handin.preflopText, 0); }
		if (site == FTP) { handin = ftpParseAction(handin, handin.preflopText, 0); }
		else if (site == CEREUS) { handin = cereusParseAction(handin, handin.preflopText, 0); }
		else if (site == HEM) {handin = HEMParseAction(handin,handin.preflopText,0);}
	}

	//get flop cards
	handin.communityCards = new Array;
	handin.communityCards[1] = new Array;
	if (handin.unformatted.match(reFlop[site])) {
		handin.communityCards[1][0] = RegExp.$1;
		handin.communityCards[1][1] = RegExp.$2;
		handin.communityCards[1][2] = RegExp.$3;
	}

	//zero out player contributions to pot for this street
	for (r=0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}

	//find flop action
	result = handin.unformattedNoBreaks.match(reFlopAction[site]);
	if (!result) { result = handin.unformattedNoBreaks.match(reFlopActionAlt[site]); }
	if (result) {
		handin.flopText = RegExp.$1;
		if (site == PSTARS) { handin = pokerStarsParseAction(handin, handin.flopText, 1); }
		else if (site == FTP) { handin = ftpParseAction(handin, handin.flopText, 1); }
		else if (site == CEREUS) { handin = cereusParseAction(handin, handin.flopText, 1); }
		else if (site == HEM) {handin = HEMParseAction(handin,handin.flopText,1);}
	}

	//get turn card
	handin.communityCards[2] = new Array;
	if (handin.unformatted.match(reTurn[site])) {
		handin.communityCards[2][0] = RegExp.$1;
	}

	//zero out player contributions to pot for this street
	for (r=0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}

	//find turn action
	result = handin.unformattedNoBreaks.match(reTurnAction[site]);
	if (!result) { result = handin.unformattedNoBreaks.match(reTurnActionAlt[site]); }
	if (result) {
		handin.turnText = RegExp.$1;
		if (site == PSTARS) { handin = pokerStarsParseAction(handin, handin.turnText, 2); }
		else if (site == FTP) { handin = ftpParseAction(handin, handin.turnText, 2); }
		else if (site == CEREUS) { handin = cereusParseAction(handin, handin.turnText, 2); }
		else if (site == HEM) {handin = HEMParseAction(handin,handin.turnText,2);}
	}

	//get river card
	handin.communityCards[3] = new Array;
	if (handin.unformatted.match(reRiver[site])) {
		handin.communityCards[3][0] = RegExp.$1;
	}

	//zero out player contributions to pot for this street
	for (r=0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}

	//find river action
	result = handin.unformattedNoBreaks.match(reRiverAction[site]);
	if (!result) { result = handin.unformattedNoBreaks.match(reRiverActionAlt[site]); }
	if (result) {
		handin.riverText = RegExp.$1;
		if (site == PSTARS) { handin = pokerStarsParseAction(handin, handin.riverText, 3); }
		else if (site == FTP) { handin = ftpParseAction(handin, handin.riverText, 3); }
		else if (site == CEREUS) { handin = cereusParseAction(handin, handin.riverText, 3); }
		else if (site == HEM) {handin = HEMParseAction(handin,handin.riverText,3);}
	}

	//summary
	if (handin.unformattedNoBreaks.match(reMatchSummary[site])) {
		handin.showdownText = RegExp.$1;

		//if (handin.showdownText.match(reMatchSummary[site])) {
		//	handin.showdownText = RegExp.$1;
		//}
		handin.showdownLines = handin.showdownText.split(/■/);

		//initialize 2D arrays
		handin.showdown_hands = new Array;   // two pair, Fives and Fours
		handin.showdown_players = new Array; // <nick>
		handin.showdown_cards = new Array;   //  Jh Qs etc
		handin.showdown_types = new Array;   // won, lost, mucked, collected
		handin.result_players = new Array;
		handin.result_values = new Array;

		//loop through showdown lines
		playerCount = -1;
		resultCount = -1;
		for (i = 0; i < handin.showdownLines.length; i = i + 1) {
			if (site == HEM) {
				if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
					m = findIndex(handin.showdown_players,RegExp.$1);
					if (m == -1) { m = ++playerCount; }
					//playerCount++;
					handin.showdown_players[m] = RegExp.$1;
					handin.showdown_types[m] = "won";
					if (handin.showdownLines[i].match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[m];
						handin.result_values[resultCount] = RegExp.$1;
					}
				}
				else if (result = handin.showdownLines[i].match(reOSummaryExtraction2[site])) {
					m = findIndex(handin.showdown_players,result[1]);
					if (m > -1) {
						handin.showdown_cards[m] = new Array;
						handin.showdown_cards[m][0] = result[2];
						handin.showdown_cards[m][1] = result[3];
						handin.showdown_cards[m][2] = result[4];
						handin.showdown_cards[m][3] = result[5];
						handin.showdown_hands[m] = " ";
					}
					else {
						playerCount++;
						handin.showdown_cards[playerCount] = new Array;
						handin.showdown_players[playerCount] = result[1];
						handin.showdown_types[playerCount] = "lost";
						handin.showdown_cards[playerCount][0] = result[2];
						handin.showdown_cards[playerCount][1] = result[3];
						handin.showdown_cards[playerCount][2] = result[4];
						handin.showdown_cards[playerCount][3] = result[5];
						handin.showdown_hands[playerCount] = " ";
					}
				}
			}
			else if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
				playerCount++;
				handin.showdown_players[playerCount] = RegExp.$1;
				handin.showdown_types[playerCount] = RegExp.$2;
				partTemp = RegExp.$3;
				if (site == CEREUS) { partTemp = RegExp.$2 + RegExp.$3; }
				if (partTemp.match(/( won | collected | wins )/)) {
					handin.showdown_types[playerCount] = "won";
				}
				//else {
				//	handin.showdown_types[playerCount] = "lost";
				//}
				handin.showdown_cards[playerCount] = new Array;
				if (partTemp) {
					if (partTemp.match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[playerCount];
						handin.result_values[resultCount] = RegExp.$1;
					}
					if (partTemp.match(reOSummaryExtraction2[site])) {
						switch(site) {
						case PSTARS:
						case FTP:
							if (RegExp.$6) {
								handin.showdown_hands[playerCount] = RegExp.$6;
							}
							handin.showdown_cards[playerCount][0] = RegExp.$1;
							handin.showdown_cards[playerCount][1] = RegExp.$2;
							handin.showdown_cards[playerCount][2] = RegExp.$3;
							handin.showdown_cards[playerCount][3] = RegExp.$4;
							break;
						case CEREUS:
							handin.showdown_cards[playerCount][0] = RegExp.$3;
							handin.showdown_cards[playerCount][1] = RegExp.$4;
							handin.showdown_cards[playerCount][2] = RegExp.$5;
							handin.showdown_cards[playerCount][3] = RegExp.$6;
							handin.showdown_hands[playerCount] = RegExp.$2;
							break;
						}
					}
				}
				else { handin.showdown_cards[playerCount][0] = 'mucks'; }
			}
		}
		

		//rake
		if (handin.unformatted.match(reRake[site])) {
			handin.rake = RegExp.$1;
		}
	}

	return handin;

}

function parse_tripledraw(handin, site) {

	//Cash or tournament?
	if (handin.firstLine.match(/Tournament/)) {
		handin.gameType = "T";
	} else {
		handin.gameType = "C";
	}

	//find blinds
	if (handin.firstLine.match(reBlinds[site])) {
		handin.smallBlind = RegExp.$1;
		handin.bigBlind = RegExp.$2;
	}

	handin.smallBlindPostedAmount = 0;
	handin.bigBlindPostedAmount = 0;

	//find game size
	if (handin.unformatted.match(reGameSize[site])) {
		handin.gameSize = RegExp.$1 + '-max';
	}
	else {
		handin.gameSize = "";
	}

	handin.antesTotal = 0;
	anteLines = new Array;
	//find antes
	anteText = handin.unformattedNoBreaks.match(reAnteText[site]);
   if (anteText) {
		anteLines = anteText[1].split(/■/);
		numAnteLines = anteLines.length;
		for (j=0;j<numAnteLines;j++) {
			if (anteLines[j].match(reAnteLines[site])) {
				handin.ante = RegExp.$1;
				handin.antesTotal = parseFloat(handin.antesTotal) + parseFloat(RegExp.$1);
			}
		}
	}
	
	result = handin.unformattedNoBreaks.match(reSeatingText[site]);
	if (result) {handin.seatText = result[1];}
	else {handin.seatText = " ";}

	handin.seatLines = handin.seatText.replace(/■/g, "\n");
	
	//find number of seats
	seats = handin.seatLines.match(reFindSeats[site]);
	handin.numPlayers = seats.length;
	
	// find button/bring-in?
	if (handin.unformatted.match(reButton[site])) {
		handin.button = RegExp.$1;
	}
	
	//find player names and stack sizes
	playerLines = handin.seatLines.match(reFindInfo[site]);
	handin.players = new Array;
	handin.stacks = new Array;
	handin.seatNumbers = new Array;

	j = 0;
	for (i = 0; i < handin.numPlayers; i = i + 1) {
		
		if (playerLines[i].match(rePlayerInfo[site])) {
			theSeat = RegExp.$1;
			thePlayer = RegExp.$2;
			theStack = RegExp.$3;
			if (!((playerLines[i].match(/sitting out/i) && (handin.gameType == "C") && (theSeat != handin.button)))){
				handin.seatNumbers[j] = theSeat;
				handin.players[j] = thePlayer;
				handin.stacks[j] = theStack;
				j++;
			}
		}
	}
	if (j > 0) { handin.numPlayers = j; }

	//find cards
	handin.holeCards = new Array;
	var myRegEx = new RegExp("");

	//get hero
	for (x = 0; x < handin.numPlayers; x++) {
		handin.holeCards[x] = new Array;
		myRegEx.compile(reGetHandPre[site] + handin.players[x] + reTDGetHandPost[site], "g");
		result = handin.unformattedNoBreaks.match(myRegEx);
		if (result) {
			handin.hero = handin.players[x];
			heropos = x;
			x = handin.numplayers;
		}
	}

	//initialize 2D arrays
	handin.action_types = new Array;
	handin.action_players = new Array;
	handin.action_values = new Array;
	handin.showdown_types = new Array;
	handin.action_addedToPot = new Array;
	handin.action_playersPot = new Array;

	for (r=0;r<handin.players.length;r++) {
		handin.action_playersPot[r] = 0;
	}


	// regexstring = /(.+)\: posts small blind [\$|](\d+|\d+\.\d+)/;
	result = handin.unformatted.match(/(.+)\: posts small blind [\$]?(\d+\.\d+|\d+)/i);
	if (result) {
		handin.smallBlindPostedBy = result[1];
		handin.smallBlindPostedAmount = result[2];
		playerIndex = findIndex(handin.players, handin.smallBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.smallBlindPostedAmount;
		//handin.action_addedToPot[0] = handin.smallBlindPostedAmount;
	}

	// regexstring = /(.+)\: posts big blind [\$|](\d+\.\d+|\d+)/;
	result = handin.unformatted.match(/(.+)\: posts big blind [\$]?(\d+\.\d+|\d+)/i);
	if (result) {
		handin.bigBlindPostedBy = result[1];
		handin.bigBlindPostedAmount = result[2];
		playerIndex = findIndex(handin.players, handin.bigBlindPostedBy);
		handin.action_playersPot[playerIndex] = handin.bigBlindPostedAmount;
		//handin.action_addedToPot[0] += handin.bigBlindPostedAmount;
	}

	//get street cards named desire
	handin.communityCards = new Array;
	handin.communityCards[1] = new Array;
	cardCount = 0;
	var thisRegEx = new RegExp;
	for (x =0;x<reTDStreetMatch[site].length;x++) {
		thisRegEx.compile(reTDStreetMatch[site][x]);
		outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
		if (!outerresult) {
			thisRegEx.compile(reTDStreetMatchAlt[site][x]);
			outerresult = thisRegEx.exec(handin.unformattedNoBreaks);
		}
		if (outerresult) {
			handin = pokerStarsParseAction(handin, outerresult[1], x);
			myRegEx.compile("Dealt to " + addslashes(handin.hero) + "( \\[(.*)\\])");
			outerLines = outerresult[1].split(/■/);
			result = outerresult[1].match(myRegEx);
			if (!result) {
				myRegEx.compile(addslashes(handin.hero) + ": stands pat on (\\[(.*)\\])");
				result = outerresult[1].match(myRegEx);
			}
			if (result) {
				subresult = result[1].match(/([2-9TJQKA][hdsc])/g);
				numResults =subresult.length;
				for (y =0; y<numResults; ++y) {
					handin.holeCards[heropos][handin.holeCards[heropos].length] = subresult[y];
				}
			}
		}
		//zero out player contributions to pot for next street
		for (r=0;r<handin.players.length;r++) {
			handin.action_playersPot[r] = 0;
		}
	}

	//summary
	if (handin.unformattedNoBreaks.match(reMatchSummary[site])) {
		handin.showdownText = RegExp.$1;

		//if (handin.showdownText.match(reMatchSummary[site])) {
		//	handin.showdownText = RegExp.$1;
		//}
		handin.showdownLines = handin.showdownText.split(/■/);

		//initialize 2D arrays
		handin.showdown_hands = new Array;   // two pair, Fives and Fours
		handin.showdown_players = new Array; // <nick>
		handin.showdown_cards = new Array;   //  Jh Qs etc
		handin.showdown_types = new Array;   // won, lost, mucked, collected
		handin.result_players = new Array;
		handin.result_values = new Array;

		//loop through showdown lines
		playerCount = -1;
		resultCount = -1;
		for (i = 0; i < handin.showdownLines.length; i = i + 1) {
			if (site == HEM) {
				if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
					m = findIndex(handin.showdown_players,RegExp.$1);
					if (m == -1) { m = ++playercount; }
					//playerCount++;
					handin.showdown_players[m] = RegExp.$1;
					handin.showdown_types[m] = "won";
					if (handin.showdownLines[i].match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[m];
						handin.result_values[resultCount] = RegExp.$1;
					}
				}
				else if (result = handin.showdownLines[i].match(reTDSummaryExtraction2[site])) {
					m = findIndex(handin.showdown_players,result[1]);
					if (m > -1) {
						handin.showdown_cards[m] = new Array;
						handin.showdown_cards[m][0] = result[2];
						handin.showdown_cards[m][1] = result[3];
						handin.showdown_cards[m][2] = result[4];
						handin.showdown_cards[m][3] = result[5];
						handin.showdown_cards[m][4] = result[6];
						handin.showdown_hands[m] = " ";
					}
					else {
						playerCount++;
						handin.showdown_cards[playerCount] = new Array;
						handin.showdown_players[playerCount] = result[1];
						handin.showdown_types[playerCount] = "lost";
						handin.showdown_cards[playerCount][0] = result[2];
						handin.showdown_cards[playerCount][1] = result[3];
						handin.showdown_cards[playerCount][2] = result[4];
						handin.showdown_cards[playerCount][3] = result[5];
						handin.showdown_cards[playerCount][4] = result[6];
						handin.showdown_hands[playerCount] = " ";
					}
				}
			}
			else if (handin.showdownLines[i].match(reSummaryExtraction1[site])) {
				playerCount++;
				handin.showdown_players[playerCount] = RegExp.$1;
				handin.showdown_types[playerCount] = RegExp.$2;
				partTemp = RegExp.$3;
				if (site == CEREUS) { partTemp = RegExp.$2 + RegExp.$3; }
				if (partTemp.match(/( won | collected | wins )/)) {
					handin.showdown_types[playerCount] = "won";
				}
				//else {
				//	handin.showdown_types[playerCount] = "lost";
				//}
				handin.showdown_cards[playerCount] = new Array;
				if (partTemp) {
					if (partTemp.match(reTheMoney[site])) {
						resultCount++;
						handin.result_players[resultCount] = handin.showdown_players[playerCount];
						handin.result_values[resultCount] = RegExp.$1;
					}
					if (partTemp.match(reTDSummaryExtraction2[site])) {
						switch(site) {
						case PSTARS:
						case FTP:
							if (RegExp.$7) {
								handin.showdown_hands[playerCount] = RegExp.$7;
							}
							handin.showdown_cards[playerCount][0] = RegExp.$1;
							handin.showdown_cards[playerCount][1] = RegExp.$2;
							handin.showdown_cards[playerCount][2] = RegExp.$3;
							handin.showdown_cards[playerCount][3] = RegExp.$4;
							handin.showdown_cards[playerCount][4] = RegExp.$5;
							break;
						case CEREUS:
							handin.showdown_cards[playerCount][0] = RegExp.$3;
							handin.showdown_cards[playerCount][1] = RegExp.$4;
							handin.showdown_cards[playerCount][2] = RegExp.$5;
							handin.showdown_cards[playerCount][3] = RegExp.$6;
							handin.showdown_cards[playerCount][4] = RegExp.$7;
							handin.showdown_hands[playerCount] = RegExp.$2;
							break;
						}
					}
				}
				else { handin.showdown_cards[playerCount][0] = 'mucks'; }
			}
		}
		

		//rake
		if (handin.unformatted.match(reRake[site])) {
			handin.rake = RegExp.$1;
		}
	}

	return handin;

}

String.prototype.capitalize = function(){ //v1.0
    return this.replace(/\w+/g, function(a){
        return a.charAt(0).toUpperCase() + a.substr(1).toLowerCase();
    });
};

function handToText(handin, outputType,showNames,showResults) {

	//call ev calculator for debugging
	//var EVresults = fcp_EV_Calculator(handin,10);
	
	// this function takes the hand structure and formats the text output
	
	skipshowdown = 0;

	//output Formats
	var FCO = 0; // Feral Cow Original / 4betbluff.com
	var FCP = 1; //Full Contact Poker
	var TPT = 2; //Two Plus Two
	var TPT2 = 3; //Twp Plus Two with emoticons
	var TPT3 = 4; //Two Plus Two text only
	//5 is poker road, like 2
	var IRC = 6; //IRC
	var HTML = 7; //html
	//8 is html formatted, like 7
	var AIM = 9; //AIM
	//10 is P5s, like html 7
	//11 is generic bbcode, like TPT 2
	//12 is html text, like AIM 9
	var DC = 13;
	var DCB = 14;
	var MID = 16;
	
	var FCONC = 20; // Feral Cow Original with new cards
	ot = outputType;
    if (outputType == 5) {ot = 2;}; //poker road
	if (outputType == 8) {ot = 7;}; //html formatted same as HTML
	if (outputType == 10)  {ot =7;}; //Pocket 5's takes HTML
	if (outputType == 11) {ot = 2;}; //generic bbcode
	if (outputType ==12) {ot=9;}; //text-only HTML is unformatted AIM
	
	
	//color settings
	titleColor = '#0000AA';
	betColor = '#AA0000';
	textColor = '#000000';
	foldColor = '#888888';
	playersLeftColor = '#006600';
	
	//format-specific text
	var lineBreaks = new Array();
	lineBreaks[FCO] = "\n";
	lineBreaks[FCP] = "\n";
	lineBreaks[TPT] = "\n";
	lineBreaks[TPT2] = "\n";
	lineBreaks[TPT3] = "\n";
	lineBreaks[IRC] = "\n";
	lineBreaks[HTML] = "<br>";
	lineBreaks[AIM] = "<br>";
	lineBreaks[FCONC] = "\n";
	lineBreaks[DC] = "\n";
	lineBreaks[DCB] = "\n";
	lineBreaks[MID] = "\n";
	
	var feralcowicon = new Array();
	feralcowicon[FCO] = "[img]http://www.feralcowpoker.com/images/feral_cow_icon.gif[/img]";
	feralcowicon[FCONC] = "[img]http://www.feralcowpoker.com/images/feral_cow_icon.gif[/img]";
	feralcowicon[FCP] = "[img]http://www.feralcowpoker.com/images/feral_cow_icon.gif[/img]";
	feralcowicon[TPT] = "[img]http://www.feralcowpoker.com/images/feral_cow_icon.gif[/img]";
	feralcowicon[TPT2] = "[img]http://www.feralcowpoker.com/images/feral_cow_icon.gif[/img]";
	feralcowicon[TPT3] = "[img]http://www.feralcowpoker.com/images/feral_cow_icon.gif[/img]";
	feralcowicon[IRC] = "`O.o' ";
	feralcowicon[HTML] = "<img src=http://www.feralcowpoker.com/images/feral_cow_icon.gif>";
	feralcowicon[AIM] = "";
	feralcowicon[DC] = "";
	feralcowicon[DCB] = "!http://www.feralcowpoker.com/images/feral_cow_icon.gif!";
	feralcowicon[MID] = "[img]http://www.feralcowpoker.com/images/feral_cow_icon.gif[/img]";

	var cardPrefix = new Array();
	var cardPostfix = new Array();
	cardPrefix[FCO] = ':';
	cardPostfix[FCO] = ':';
	cardPrefix[FCONC] = '[img]http://www.feralcowpoker.com/images/cards/' + cardFolder + '/';
	cardPostfix[FCONC] = '.gif[/img]';
	cardPrefix[FCP] = ':';
	cardPostfix[FCP] = '';
	cardPrefix[TPT] = '[img]http://www.feralcowpoker.com/images/cards/'+ cardFolder + '/';
	cardPostfix[TPT] = '.gif[/img]';
	cardPrefix[TPT2] = '';
	cardPostfix[TPT2] = '';
	cardPrefix[TPT3] = '[b]';
	cardPostfix[TPT3] = '[/b]';
	cardPrefix[DC] = '[b]';
	cardPostfix[DC] = '[/b]';
	cardPrefix[DCB] = '!http://www.feralcowpoker.com/images/cards/'+ cardFolder + '/';
	cardPostfix[DCB] = '.gif!';
	cardPrefix[IRC] = String.fromCharCode(2);;
	cardPostfix[IRC] = String.fromCharCode(2);;
	cardPrefix[HTML] = '<img src=http://www.feralcowpoker.com/images/cards/'+ cardFolder + '/';
	cardPostfix[HTML] = '.gif>';
	cardPrefix[AIM] = '';
	cardPostfix[AIM] = '';
	cardPrefix[MID] = '';
	cardPostfix[MID] = '';


	
	var tagLinePrefix = new Array();
	var tagLinePostfix = new Array();
	tagLinePrefix[FCO] = '[color=' +  titleColor + '][size=1]v'+version+'[/size][/color]';
	tagLinePostfix[FCO] = '';
	tagLinePrefix[FCONC] = '[color=' +  titleColor + '][size=1]v'+version+'[/size][/color]';
	tagLinePostfix[FCONC] = '';
	tagLinePrefix[FCP] = '[url=http://www.feralcowpoker.com/poker-hand-history-converter.php?version=' + version +']';
	tagLinePostfix[FCP] = '[/url]';
	tagLinePrefix[TPT] = '[url=http://www.feralcowpoker.com/poker-hand-history-converter.php?version=' + version +']';
	tagLinePostfix[TPT] = '[/url]';
	tagLinePrefix[TPT2] = '[url=http://www.feralcowpoker.com/poker-hand-history-converter.php?version=' + version +']';
	tagLinePostfix[TPT2] = '[/url]';
	tagLinePrefix[TPT3] = '[url=http://www.feralcowpoker.com/poker-hand-history-converter.php?version=' + version +']';
	tagLinePostfix[TPT3] = '[/url]';
	tagLinePrefix[IRC] = String.fromCharCode(2);
	tagLinePostfix[IRC] = String.fromCharCode(2);
	tagLinePrefix[HTML] = '<a href=http://www.feralcowpoker.com/poker-hand-history-converter.php?version='+version+'>';
	tagLinePostfix[HTML] = '</a>';
	tagLinePrefix[AIM] = '<a href=http://www.feralcowpoker.com/poker-hand-history-converter.php?version='+version+'>';
	tagLinePostfix[AIM] = '</a>';
	tagLinePrefix[DC] = '[url=http://www.feralcowpoker.com/poker-hand-history-converter.php?version=' + version +']';
	tagLinePostfix[DC] = '[/url]';
	tagLinePrefix[DC] = '[url=http://www.feralcowpoker.com/poker-hand-history-converter.php?version=' + version +']';
	tagLinePostfix[DC] = '[/url]';
	tagLinePrefix[DCB] = '"';
	tagLinePostfix[DCB] = '":http://www.feralcowpoker.com/poker-hand-history-converter.php?version=' + version ;
	tagLinePrefix[MID] = '[url=http://www.feralcowpoker.com/poker-hand-history-converter.php?version=' + version +']';
	tagLinePostfix[MID] = '[/url]';

	
	var gameInfoPre = new Array();
	var gameInfoPost = new Array();
	gameInfoPre[FCO] = "";
	gameInfoPost[FCO] = "";
	gameInfoPre[FCONC] = "";
	gameInfoPost[FCONC] = "";
	gameInfoPre[FCP] = "";
	gameInfoPost[FCP] = "";
	gameInfoPre[TPT] = "";
	gameInfoPost[TPT] = "";
	gameInfoPre[TPT2] = "";
	gameInfoPost[TPT2] = "";
	gameInfoPre[TPT3] = "";
	gameInfoPost[TPT3] = "";
	gameInfoPre[IRC] = String.fromCharCode(3) + "0,14" + String.fromCharCode(2) + String.fromCharCode(31);
	gameInfoPost[IRC] = String.fromCharCode(3) + "1" + String.fromCharCode(2) + String.fromCharCode(31);
	gameInfoPre[HTML] = "<b>";
	gameInfoPost[HTML] = "</b>";
	gameInfoPre[AIM] = "<b>";
	gameInfoPost[AIM] = "</b>";
	gameInfoPre[DC] = "";
	gameInfoPost[DC] = "";
	gameInfoPre[DCB] = "";
	gameInfoPost[DCB] = "";
	gameInfoPre[MID] = "";
	gameInfoPost[MID] = "";

	var holecardPre = new Array();
	var holecardPost = new Array();
	holecardPre[FCO] = "[holecard]";
	holecardPost[FCO] = "[/holecard]";
	holecardPre[FCONC] = "[holecard]";
	holecardPost[FCONC] = "[/holecard]";
	holecardPre[FCP] = "[:";
	holecardPost[FCP] = "]";
	holecardPre[TPT] = "[[img]http://www.feralcowpoker.com/images/cards/"+ cardFolder + '/';
	holecardPost[TPT] = ".gif[/img]]";
	holecardPre[TPT2] = "[";
	holecardPost[TPT2]= "]";
	holecardPre[TPT3] = "[";
	holecardPost[TPT3]= "]";
	holecardPre[IRC] = "[";
	holecardPost[IRC] = "]";
	holecardPre[HTML] = "[";
	holecardPost[HTML] = "]";
	holecardPre[AIM] = "[";
	holecardPost[AIM] = "]";
	holecardPre[DC] = "[";
	holecardPost[DC]= "]";
	holecardPre[DCB] = "[";
	holecardPost[DCB]= "]";
	holecardPre[MID] = "[";
	holecardPost[MID]= "]";
	
	var unknownCard = new Array();
	unknownCard[FCO] = ":1s:";
	unknownCard[FCONC] = ":1s:";
	unknownCard[FCP] = "[X]";
	unknownCard[TPT] = "[X]";
	unknownCard[TPT2] = "[X]";
	unknownCard[TPT3] = "[X]";
	unknownCard[IRC] = "[X]";
	unknownCard[HTML] = "[X]";
	unknownCard[AIM] = "[X]";
	unknownCard[DC] = "[X]";
	unknownCard[DCB] = "[X]";
	unknownCard[MID] = "[X]";
	
	var positionPre = new Array();
	var positionPost = new Array();
	positionPre[FCO] = "";
	positionPost[FCO] = "";
	positionPre[FCONC] = "";
	positionPost[FCONC] = "";
	positionPre[FCP] = "";
	positionPost[FCP] = "";
	positionPre[TPT] = "";
	positionPost[TPT] = "";
	positionPre[TPT2] = "";
	positionPost[TPT2] = "";
	positionPre[TPT3] = "";
	positionPost[TPT3] = "";
	positionPre[IRC] = String.fromCharCode(2);
	positionPost[IRC] = String.fromCharCode(2);	
	positionPre[HTML] = "";
	positionPost[HTML] = "";
	positionPre[AIM] = "";
	positionPost[AIM] = "";
	positionPre[DC] = "";
	positionPost[DC] = "";
	positionPre[DCB] = "";
	positionPost[DCB] = "";
	positionPre[MID] = "";
	positionPost[MID] = "";
	
	var playerNamePre = new Array();
	var playerNamePost = new Array();
	playerNamePre[FCO] = "[color=#4B0082]";
	playerNamePost[FCO] = "[/color]";
	playerNamePre[FCONC] = "[color=#4B0082]";
	playerNamePost[FCONC] = "[/color]";
	playerNamePre[FCP] = "[color=#4B0082]";
	playerNamePost[FCP] = "[/color]";
	playerNamePre[TPT] = "[color=#4B0082]";
	playerNamePost[TPT] = "[/color]";
	playerNamePre[TPT2] = "[color=#4B0082]";
	playerNamePost[TPT2] = "[/color]";
	playerNamePre[TPT3] = "[color=#4B0082]";
	playerNamePost[TPT3] = "[/color]";
	playerNamePre[IRC] = "";
	playerNamePost[IRC] = "";	
	playerNamePre[HTML] = "<font color=#4B0082>";
	playerNamePost[HTML] = "</font>";
	playerNamePre[AIM] = "<font color=#4B0082>";
	playerNamePost[AIM] = "</font>";
	playerNamePre[DC] = "[color=#4B0082]";
	playerNamePost[DC] = "[/color]";
	playerNamePre[DCB] = "";
	playerNamePost[DCB] = "";
	
	var endStackLine = new Array();
	endStackLine[FCO] = "\n";
	endStackLine[FCONC] = "\n";
	endStackLine[FCP] = "\n";
	endStackLine[TPT] = "\n";
	endStackLine[TPT2] = "\n";
	endStackLine[TPT3] = "\n";
	endStackLine[IRC] = " | ";
	endStackLine[HTML] = "<br>";
	endStackLine[AIM] = "<br>";
	endStackLine[DC] = "\n";
	endStackLine[DCB] = "\n";
	endStackLine[MID] = "\n";
	
	var streetNamePre = new Array();
	var streetNamePost = new Array();
	streetNamePre[FCO] = "[b]";
	streetNamePost[FCO] = "[/b]";
	streetNamePre[FCONC] = "[b]";
	streetNamePost[FCONC] = "[/b]";
	streetNamePre[FCP] = "[b]";
	streetNamePost[FCP] = "[/b]";
	streetNamePre[TPT] = "[b]";
	streetNamePost[TPT] = "[/b]";
	streetNamePre[TPT2] = "[b]";
	streetNamePost[TPT2] = "[/b]";
	streetNamePre[TPT3] = "[b]";
	streetNamePost[TPT3] = "[/b]";
	streetNamePre[IRC] = String.fromCharCode(2) + String.fromCharCode(31);
	streetNamePost[IRC] = String.fromCharCode(2) + String.fromCharCode(31);
	streetNamePre[HTML] = "<b>";
	streetNamePost[HTML] = "</b>";
	streetNamePre[AIM] = "<b>";
	streetNamePost[AIM] = "</b>";
	streetNamePre[DC] = "[b]";
	streetNamePost[DC] = "[/b]";
	streetNamePre[DCB] = "*";
	streetNamePost[DCB] = "*";
	streetNamePre[MID] = "[b]";
	streetNamePost[MID] = "[/b]";
	
	var playersLeftPre = new Array();
	var playersLeftPost = new Array();
	playersLeftPre[FCO] = "[color=" + playersLeftColor + "]";
	playersLeftPost[FCO] = "[/color]";
	playersLeftPre[FCONC] = "[color=" + playersLeftColor + "]";
	playersLeftPost[FCONC] = "[/color]";
	playersLeftPre[FCP] = "[color=" + playersLeftColor + "]";
	playersLeftPost[FCP] = "[/color]";
	playersLeftPre[TPT] = "[color=" + playersLeftColor + "]";
	playersLeftPost[TPT] = "[/color]";
	playersLeftPre[TPT2] = "[color=" + playersLeftColor + "]";
	playersLeftPost[TPT2] = "[/color]";
	playersLeftPre[TPT3] = "[color=" + playersLeftColor + "]";
	playersLeftPost[TPT3] = "[/color]";
	playersLeftPre[IRC] = String.fromCharCode(3) + "6";
	playersLeftPost[IRC] = String.fromCharCode(3) + "1";
	playersLeftPre[HTML] = "<font color=" + playersLeftColor + ">";
	playersLeftPost[HTML] = "</font>";
	playersLeftPre[AIM] = "<font color=" + playersLeftColor + ">";
	playersLeftPost[AIM] = "</font>";
	playersLeftPre[DC] = "[color=" + playersLeftColor + "]";
	playersLeftPost[DC] = "[/color]";
	playersLeftPre[DCB] = "";
	playersLeftPost[DCB] = "";
	playersLeftPre[MID] = "[color=" + playersLeftColor + "]";
	playersLeftPost[MID] = "[/color]";

	var foldsPre = new Array();
	var foldsPost = new Array();
	foldsPre[FCO] = "[i][color=" + foldColor + "]";
	foldsPost[FCO] = "[/i][/color]";
	foldsPre[FCONC] = "[i][color=" + foldColor + "]";
	foldsPost[FCONC] = "[/i][/color]";
	foldsPre[FCP] = "[i][color=" + foldColor + "]";
	foldsPost[FCP] = "[/i][/color]";
	foldsPre[TPT] = "[i][color=" + foldColor + "]";
	foldsPost[TPT] = "[/color][/i]";
	foldsPre[TPT2] = "[i][color=" + foldColor + "]";
	foldsPost[TPT2] = "[/color][/i]";
	foldsPre[TPT3] = "[i][color=" + foldColor + "]";
	foldsPost[TPT3] = "[/i][/color]";
	foldsPre[IRC] = "";
	foldsPost[IRC] = "";
	foldsPre[HTML] = "<i><font color =" + foldColor + ">";
	foldsPost[HTML] = "</i></font>";
	foldsPre[AIM] = "<i><font color =" + foldColor + ">";
	foldsPost[AIM] = "</i></font>";
	foldsPre[DC] = "[i][color=" + foldColor + "]";
	foldsPost[DC] = "[/i][/color]";
	foldsPre[DCB] = "_";
	foldsPost[DCB] = "_";
	foldsPre[MID] = "[i][color=" + foldColor + "]";
	foldsPost[MID] = "[/color][/i]";
	
	var betActionPre = new Array();
	var betActionPost = new Array();
	betActionPre[FCO] = "[color=" + betColor + "]"; 
	betActionPost[FCO] = "[/color]";
	betActionPre[FCONC] = "[color=" + betColor + "]"; 
	betActionPost[FCONC] = "[/color]";
	betActionPre[FCP] = "[color=" + betColor + "]"; 
	betActionPost[FCP] = "[/color]";
	betActionPre[TPT] = "[color=" + betColor + "]"; 
	betActionPost[TPT] = "[/color]";
	betActionPre[TPT2] = "[color=" + betColor + "]"; 
	betActionPost[TPT2] = "[/color]";
	betActionPre[TPT3] = "[color=" + betColor + "]"; 
	betActionPost[TPT3] = "[/color]";
	betActionPre[IRC] = ""; 
	betActionPost[IRC] = "";
	betActionPre[HTML] = "<font color=" + betColor + ">"; 
	betActionPost[HTML] = "</font>";
	betActionPre[AIM] = "<font color=" + betColor + ">"; 
	betActionPost[AIM] = "</font>";
	betActionPre[DC] = "[color=" + betColor + "]"; 
	betActionPost[DC] = "[/color]";
	betActionPre[DCB] = ""; 
	betActionPost[DCB] = "";
	betActionPre[MID] = "[color=" + betColor + "]"; 
	betActionPost[MID] = "[/color]";
	
	var regActionPre = new Array();
	var regActionPost = new Array();
	regActionPre[FCO] = "[color=" + textColor + "]"; 
	regActionPost[FCO] = "[/color]";
	regActionPre[FCONC] = "[color=" + textColor + "]"; 
	regActionPost[FCONC] = "[/color]";
	regActionPre[FCP] = "[color=" + textColor + "]"; 
	regActionPost[FCP] = "[/color]";
	regActionPre[TPT] = "[color=" + textColor + "]"; 
	regActionPost[TPT] = "[/color]";
	regActionPre[TPT2] = "[color=" + textColor + "]"; 
	regActionPost[TPT2] = "[/color]";
	regActionPre[TPT3] = "[color=" + textColor + "]"; 
	regActionPost[TPT3] = "[/color]";
	regActionPre[IRC] = ""; 
	regActionPost[IRC] = "";
	regActionPre[HTML] = "<font color=" + textColor + ">"; 
	regActionPost[HTML] = "</font>";
	regActionPre[AIM] = "<font color=" + textColor + ">"; 
	regActionPost[AIM] = "</font>";
	regActionPre[DC] = "[color=" + textColor + "]"; 
	regActionPost[DC] = "[/color]";
	regActionPre[DCB] = ""; 
	regActionPost[DCB] = "";
	regActionPre[MID] = "[color=" + textColor + "]"; 
	regActionPost[MID] = "[/color]";

	
	var suitPre = new Array();
	var suitPost = new Array();
	suitPre['h'] = new Array();
	suitPost['h'] = new Array();
	suitPre['h'][FCO] = "";
	suitPost['h'][FCO] = ""; 
	suitPre['h'][FCONC] = "";
	suitPost['h'][FCONC] = ""; 
	suitPre['h'][FCP] = "";
	suitPost['h'][FCP] = ""; 
	suitPre['h'][TPT] = "";
	suitPost['h'][TPT] = ""; 
	suitPre['h'][TPT2] = "";
	suitPost['h'][TPT2] = "";
	suitPre['h'][MID] = "";
	suitPost['h'][MID] = "";
	suitPre['h'][DC] = "";
	suitPost['h'][DC] = "";
	suitPre['h'][DCB] = "";
	suitPost['h'][DCB] = "";
	suitPre['h'][TPT3] = "[color=red]";
	suitPost['h'][TPT3] = "[/color]";
	suitPre['h'][IRC] = String.fromCharCode(3) + "4 ";
	suitPost['h'][IRC] = String.fromCharCode(3) + "1 ";
	suitPre['h'][HTML] = "";
	suitPost['h'][HTML] = ""; 
	suitPre['h'][AIM] = "<b><font color=#AA0000>";
	suitPost['h'][AIM] = "</font></b>"; 
	suitPre['c'] = new Array();
	suitPost['c'] = new Array();
	suitPre['c'][FCO] = "";
	suitPost['c'][FCO] = ""; 
	suitPre['c'][FCONC] = "";
	suitPost['c'][FCONC] = "";
	suitPre['c'][FCP] = "";
	suitPost['c'][FCP] = ""; 
	suitPre['c'][TPT] = "";
	suitPost['c'][TPT] = ""; 
	suitPre['c'][TPT2] = "";
	suitPost['c'][TPT2] = ""; 
	suitPre['c'][MID] = "";
	suitPost['c'][MID] = ""; 
	suitPre['c'][DC] = "";
	suitPost['c'][DC] = ""; 
	suitPre['c'][DCB] = "";
	suitPost['c'][DCB] = "";
	suitPre['c'][TPT3] = "[color=green]";
	suitPost['c'][TPT3] = "[/color]";
	suitPre['c'][IRC] = String.fromCharCode(3) + "3 ";
	suitPost['c'][IRC] = String.fromCharCode(3) + "1 ";
	suitPre['c'][HTML] = "";
	suitPre['c'][AIM] = "<b><font color=#00AA00>"; 
	suitPost['c'][AIM] = "</font></b>";
	suitPost['c'][HTML] = "";
	suitPre['s'] = new Array();
	suitPost['s'] = new Array();
	suitPre['s'][FCO] = "";
	suitPost['s'][FCO] = ""; 
	suitPre['s'][FCONC] = "";
	suitPost['s'][FCONC] = ""; 
	suitPre['s'][FCP] = "";
	suitPost['s'][FCP] = ""; 
	suitPre['s'][TPT] = "";
	suitPost['s'][TPT] = ""; 
	suitPre['s'][TPT2] = "";
	suitPost['s'][TPT2] = ""; 
	suitPre['s'][MID] = "";
	suitPost['s'][MID] = ""; 
	suitPre['s'][DC] = "";
	suitPost['s'][DC] = ""; 
	suitPre['s'][DCB] = "";
	suitPost['s'][DCB] = ""; 
	suitPre['s'][TPT3] = "[color=black]";
	suitPost['s'][TPT3] = "[/color]"; 
	suitPre['s'][IRC] = String.fromCharCode(3) + "14 ";
	suitPost['s'][IRC] = String.fromCharCode(3) + "1 ";
	suitPre['s'][HTML] = "";
	suitPost['s'][HTML] = ""; 
	suitPre['s'][AIM] = "<b>";
	suitPost['s'][AIM] = "</b>";
	suitPre['d'] = new Array();
	suitPost['d'] = new Array();
	suitPre['d'][FCO] = "";
	suitPost['d'][FCO] = "";
	suitPre['d'][FCONC] = "";
	suitPost['d'][FCONC] = ""; 
	suitPre['d'][FCP] = "";
	suitPost['d'][FCP] = ""; 
	suitPre['d'][TPT] = "";
	suitPost['d'][TPT] = ""; 
	suitPre['d'][TPT2] = "";
	suitPost['d'][TPT2] = ""; 
	suitPre['d'][MID] = "";
	suitPost['d'][MID] = "";
	suitPre['d'][DC] = "";
	suitPost['d'][DC] = "";
	suitPre['d'][DCB] = "";
	suitPost['d'][DCB] = ""; 
	suitPre['d'][TPT3] = "[color=blue]";
	suitPost['d'][TPT3] = "[/color]"; 
	suitPre['d'][IRC] = String.fromCharCode(3) + "12 ";
	suitPost['d'][IRC] = String.fromCharCode(3) + "1 ";
	suitPre['d'][HTML] = "";
	suitPost['d'][HTML] = ""; 
	suitPre['d'][AIM] = "<b><font color=#0000AA>";
	suitPost['d'][AIM] = "</font></b>"; 
	
	var suitText = new Array();
	suitText['h'] = new Array();
	suitText['s'] = new Array();
	suitText['d'] = new Array();
	suitText['c'] = new Array();
	suitText['h'][FCO] = 'h';
	suitText['s'][FCO] = 's';
	suitText['d'][FCO] = 'd';
	suitText['c'][FCO] = 'c';
	suitText['h'][FCONC] = 'h';
	suitText['s'][FCONC] = 's';
	suitText['d'][FCONC] = 'd';
	suitText['c'][FCONC] = 'c';
	suitText['h'][FCP] = 'h';
	suitText['s'][FCP] = 's';
	suitText['d'][FCP] = 'd';
	suitText['c'][FCP] = 'c';
	suitText['h'][TPT] = 'h';
	suitText['s'][TPT] = 's';
	suitText['d'][TPT] = 'd';
	suitText['c'][TPT] = 'c';
	suitText['h'][TPT2] = ':heart:';
	suitText['s'][TPT2] = ':spade:';
	suitText['d'][TPT2] = ':diamond:';
	suitText['c'][TPT2] = ':club:';
	suitText['h'][DC] = ':heart:';
	suitText['s'][DC] = ':spade:';
	suitText['d'][DC] = ':diamond:';
	suitText['c'][DC] = ':club:';
	suitText['h'][DCB] = 'h';
	suitText['s'][DCB] = 's';
	suitText['d'][DCB] = 'd';
	suitText['c'][DCB] = 'c';
	suitText['h'][TPT3] = 'h';
	suitText['s'][TPT3] = 's';
	suitText['d'][TPT3] = 'd';
	suitText['c'][TPT3] = 'c';
	suitText['h'][IRC] = 'h';
	suitText['s'][IRC] = 's';
	suitText['d'][IRC] = 'd';
	suitText['c'][IRC] = 'c';
	suitText['h'][HTML] = 'h';
	suitText['s'][HTML] = 's';
	suitText['d'][HTML] = 'd';
	suitText['c'][HTML] = 'c';
	suitText['h'][AIM] = 'h';
	suitText['s'][AIM] = 's';
	suitText['d'][AIM] = 'd';
	suitText['c'][AIM] = 'c';
	suitText['h'][MID] = 'h';
	suitText['s'][MID] = 's';
	suitText['d'][MID] = 'd';
	suitText['c'][MID] = 'c';
	
	var whiteResultsPre = new Array();
	var whiteResultsPost = new Array();
	whiteResultsPre[FCO] = "[spoiler]";
	whiteResultsPost[FCO] = "[/spoiler]";
	whiteResultsPre[FCONC] = "[spoiler]";
	whiteResultsPost[FCONC] = "[/spoiler]";
	whiteResultsPre[FCP] = "[spoiler]";
	whiteResultsPost[FCP] = "[/spoiler]";
	whiteResultsPre[TPT] = "[color=#FFFFFF]";
	whiteResultsPost[TPT] = "[/color]";
	whiteResultsPre[TPT2] = "[color=#FFFFFF]";
	whiteResultsPost[TPT2] = "[/color]";
	whiteResultsPre[TPT3] = "[color=#FFFFFF]";
	whiteResultsPost[TPT3] = "[/color]";
	whiteResultsPre[IRC] = String.fromCharCode(3) + "0 ";
	whiteResultsPost[IRC] = String.fromCharCode(3) + "1 ";
	whiteResultsPre[HTML] = "<font color=#FFFFFF>";
	whiteResultsPost[HTML] = "</font>";
	whiteResultsPre[AIM] = "<font color=#FFFFFF>";
	whiteResultsPost[AIM] = "</font>";
	whiteResultsPre[DC] = "[color=#FFFFFF]";
	whiteResultsPost[DC] = "[/color]";
	whiteResultsPre[DCB] = "";
	whiteResultsPost[DCB] = "";
	whiteResultsPre[MID] = "[color=#FFFFFF]";
	whiteResultsPost[MID] = "[/color]";
	
	var whiteCardsPre = new Array();
	var whiteCardsPost = new Array();
	whiteCardsPre[FCO] = "";
	whiteCardsPost[FCO] = "";
	whiteCardsPre[FCONC] = "";
	whiteCardsPost[FCONC] = "";
	whiteCardsPre[FCP] = "";
	whiteCardsPost[FCP] = "";
	whiteCardsPre[TPT] = "";
	whiteCardsPost[TPT] = "";
	whiteCardsPre[TPT2] = "";
	whiteCardsPost[TPT2] = "";
	whiteCardsPre[TPT3] = "";
	whiteCardsPost[TPT3] = "";
	whiteCardsPre[IRC] = "";
	whiteCardsPost[IRC] = "";
	whiteCardsPre[HTML] = "";
	whiteCardsPost[HTML] = "";
	whiteCardsPre[AIM] = "";
	whiteCardsPost[AIM] = "";
	whiteCardsPre[DC] = "";
	whiteCardsPost[DC] = "";
	whiteCardsPre[DCB] = "";
	whiteCardsPost[DCB] = "";
	whiteCardsPre[MID] = "";
	whiteCardsPost[MID] = "";

	
	
	if (handin.error) {

		tx = handin.error;

	} else if (debug) {

		//for firebug
		
		
		//print out all the info unformatted for debugging purposes
		tx = '[b]Feral Converter[/b]\n';
		tx = tx + 'site: \n' + handin.site;
		tx = tx + '\ngamelong: ' + handin.gameLong;
		tx = tx + '\ngamesize: ' + handin.gameSize;
		tx = tx + '\nblinds: ' + handin.smallBlind + '/' + handin.bigBlind + '\n';
		tx = tx + 'Gametype: ' + handin.gameType + '\n';
		tx = tx + 'Players: ' + handin.numPlayers;
		tx = tx + '\nPlayers: ' + handin.players;
		tx = tx + '\nseat numbers: ' + handin.seatNumbers;
		tx = tx + '\nStacks: ' + handin.stacks;
		tx = tx + '\nButton: Seat ' + handin.button;
		tx = tx + '\nHole cards: '
		numX = handin.holeCards.length;
		for (x = 0; x<numX; x++) {
			numY = handin.holeCards[x].length;
			for (y=0;y<numY;y++) {
				tx = tx + handin.holeCards[x][y];
			}
			tx = tx + '\n';
		}
		tx = tx + '\n\npf names: ' + handin.action_players[0];
		tx = tx + '\nhero: ' + handin.hero;
		tx = tx + '\nbig blind posted by ' + handin.bigBlindPostedBy + ', amount = ' + handin.bigBlindPostedAmount;
		tx = tx + '\nsmall blind posted by ' + handin.smallBlindPostedBy + ', amount = ' + handin.smallBlindPostedAmount;
		tx = tx + '\nante: ' + handin.ante;
		tx = tx + '\nantestotal: ' + handin.antesTotal;
		tx = tx + '\npf actions: ' + handin.action_types[0];
		tx = tx + '\npf values: ' + handin.action_values[0];
		tx = tx + '\npf added: ' + handin.action_addedToPot[0];
		tx = tx + '\n\nflop: ' + handin.communityCards[1];
		tx = tx + '\nf names: ' + handin.action_players[1];
		tx = tx + '\nf actions: ' + handin.action_types[1];
		tx = tx + '\nf values: ' + handin.action_values[1];
		tx = tx + '\nf added: ' + handin.action_addedToPot[1];
		tx = tx + '\n\nturn: ' + handin.communityCards[2];
		tx = tx + '\nt names: ' + handin.action_players[2];
		tx = tx + '\nt actions: ' + handin.action_types[2];
		tx = tx + '\nt values: ' + handin.action_values[2];
		tx = tx + '\nt added: ' + handin.action_addedToPot[2];
		tx = tx + '\n\nriver: ' + handin.communityCards[3];
		tx = tx + '\nr names: ' + handin.action_players[3];
		tx = tx + '\nr actions: ' + handin.action_types[3];
		tx = tx + '\nr values: ' + handin.action_values[3];
		tx = tx + '\nr added: ' + handin.action_addedToPot[3];
		tx = tx + '\n\nsd players: ' + handin.showdown_players;
		tx = tx + '\nsd cards: ' + handin.showdown_cards;
		tx = tx + '\nsd hands: ' + handin.showdown_hands;
		tx = tx + '\nresult players: ' + handin.result_players;
		tx = tx + '\nresult players: ' + handin.result_values;
		tx = tx + '\nrake: ' + handin.rake;

		tx = tx + '\n\nmessage: ' + handin.message;
	} else {
		
		// !HandToText Meat
		if (handin.gameType == "C") {
			if (handin.currencyText) {
				chipPrefix = handin.currencyText;
			} else {
				chipPrefix = '$';
			}
		}
		else {
			chipPrefix = 't';
		}

		//are we playing a limit game? 
		if (handin.gameShort == 'LHE' || handin.gameLong == 'Limit Omaha' || handin.gameLong == 'Limit Omaha Hi/Lo') {
			isLimitGame = 1;
		} else {
			isLimitGame = 0;
		}
		
		//For draw games, how many cards are there? 
		if (handin.gameLong.match(/Draw/)) {
			maxCards = 5;
		} else if (handin.gameLong.match(/Badugi/)) {
			maxCards = 4;
		}
		
		//any garbage that was rejected prior to first line
		tx = handin.prefix;
		if (handin.prefix.length > 0) {tx = tx + '\n';}
		
		//tagline
		tagLine = getRandomTagLine();
		tx = tx + feralcowicon[ot] + tagLinePrefix[ot] + tagLine + tagLinePostfix[ot] + lineBreaks[ot];

		//game info
		if (handin.HEMOriginalSite) {
			tx = tx + gameInfoPre[ot] + 'HEM/' + handin.HEMOriginalSite + ' ' + handin.gameLong + ' ';
		} else {
			tx = tx + gameInfoPre[ot] + handin.site + ' ' + handin.gameLong + ' ';
		}
		
		//tourney buyin
		if (handin.tourneyBuyin) {
			tx = tx + '(' + handin.tourneyBuyin + ') ';
		}

		//blinds
		tx = tx + chipPrefix + handin.smallBlind + '/' + chipPrefix + handin.bigBlind + ' ';

		//antes
		if (handin.ante) {
			tx = tx + 'ante ' + chipPrefix + handin.ante + ' ';
		}

		//number of players
		tx = tx + '- ' + handin.numPlayers + ' players' + gameInfoPost[ot] + lineBreaks[ot];

		//street & position names
		handin.streetName = new Array;
		if (handin.gameShort == 'NLHE' | handin.gameShort == 'LHE' | handin.gameShort == 'OMAHA' | handin.gameShort == 'PLHE') {
			handin.streetName[0] = 'Preflop';
			handin.streetName[1] = 'Flop';
			handin.streetName[2] = 'Turn';
			handin.streetName[3] = 'River';

			//figure out position labels
			getPositionNames(handin);
		}
		else if (handin.gameShort == 'STUD' | handin.gameShort == 'RAZZ') {
			handin.streetName[0] = '3rd Street';
			handin.streetName[1] = '4th Street';
			handin.streetName[2] = '5th Street';
			handin.streetName[3] = '6th Street';
			handin.streetName[4] = 'River';

			//figure out position labels
			getPositionNamesStud(handin);
		}
		else if (handin.gameShort == 'DRAW') {
			handin.streetName[0] = 'Dealing Hands';
			handin.streetName[1] = 'First Draw';
			handin.streetName[2] = 'Second Draw';
			handin.streetName[3] = 'Third Draw';

			//figure out position labels
			getPositionNames(handin);
		}
	
		
		numDigits = 0;
		//number of digits to print out pot sizes to
		if (handin.gameType == "C") {
			numDigits = 2;
			numDigitsPot = 2;
		} else {
			numDigits = 0;
			if (isLimitGame) {
				numDigitsPot = 2;
			} else {
				numDigitsPot = 0;
			}
		}

		//stack sizes
		tx = tx + lineBreaks[ot];
		maxi = handin.players.length;
		for (i=0;i<maxi;i++) {
			if (handin.players[i] == handin.hero) {
				if (!showNames) {
					herotext = ' (Hero)';
				} else {
					herotext = '';
				}
			} else {
				herotext = '';
			}
			
			var tempStack = cleanNum(handin.stacks[i]);
						
			// tempStack.toFloat(handin.stacks[i]);
			tx = tx + positionPre[ot] + handin.positions[i] + positionPost[ot];
			if (showNames) {
				if (handin.players[i] == handin.hero) {
					//even though we show names, we hide hero's name
					tx = tx + playerNamePre[ot]+ " Hero" + playerNamePost[ot]; 
				} else {
					tx = tx + playerNamePre[ot]+ " " + handin.players[i] + playerNamePost[ot];
				}
			}
			tx = tx + ': ' + chipPrefix + addCommas(tempStack.toFixed(numDigits));
			if (handin.gameShort == 'STUD' | handin.gameShort == 'RAZZ') {
				maxK = handin.holeCards[i].length;
				
				for (k=0;k<maxK;k++) {
					if ((handin.holeCards[i].length == 7) && (herotext == '') && ((k < 2) || (k == 6))) {
						tx = tx + ' ' + holecardPre[ot] + handin.holeCards[i][k].capitalize() + holecardPost[ot];
						
					}
					else {
						if (handin.holeCards[i][k] == '1s') {
							tx = tx + ' ' + unknownCard[ot];
						} else {
							tx = tx + ' ' + cardPrefix[ot] + handin.holeCards[i][k].capitalize() + cardPostfix[ot];
						}
					}
				}
			}
			tx = tx + ' ' + herotext + endStackLine[ot];
		}

		tx = tx + lineBreaks[ot];

		

		handin.potSize = cleanNum(handin.antesTotal);

		numPlayersLeft = handin.numPlayers;

		//actions by street    
		cardout = 0;
		maxX = handin.action_players.length;
		for (x =0;x < maxX; x++) {

			dpDisco = 1
			//street name and street-specific stuff    
			if (numPlayersLeft > 1) {
				tx = tx + streetNamePre[ot] + handin.streetName[x] + ':' + streetNamePost[ot];
			}
			if ((handin.streetName[x] == 'Preflop') || (handin.streetName[x] == 'Dealing Hands')) {
				//preflop has special headings
				handin.potSize = cleanNum(handin.potSize) + cleanNum(handin.smallBlindPostedAmount) + cleanNum(handin.bigBlindPostedAmount);
				if (isLimitGame) {
					//for limit games convert pot size to SB
					potsizeinbets = handin.potSize/handin.smallBlind;
					tx = tx + ' (' + potsizeinbets.toFixed(numDigitsPot) + ' SB) ';
				} else {
					tx = tx + ' (' + chipPrefix + addCommas(handin.potSize.toFixed(numDigitsPot)) + ') ';
				}
				if (handin.hero) {
					if (handin.gameShort == 'DRAW') {
						
						for (countCard = 0; countCard < maxCards; countCard++) {
							tx = tx + ' ' +cardPrefix[ot] + suitPre[handin.holeCards[findIndex(handin.players, handin.hero)][cardout].substring(1)][ot] + handin.holeCards[findIndex(handin.players, handin.hero)][cardout].substring(0,1).capitalize() + suitText[handin.holeCards[findIndex(handin.players, handin.hero)][cardout].substring(1)][ot] + suitPost[handin.holeCards[findIndex(handin.players, handin.hero)][cardout].substring(1)][ot] + cardPostfix[ot];
							cardout++
						}
					}
					else {
						//tx = tx + ' Hero is ' + handin.positions[handin.players.indexOf(handin.hero)];
						tx = tx + ' Hero is ' + handin.positions[findIndex(handin.players, handin.hero)];
						tx = tx + ' with';
						maxW = handin.holeCards.length;
						for (w =0;w<maxW;w++) {
							maxV = handin.holeCards[w].length;
							for (v =0;v < maxV; v++) {
								
								tx = tx + ' ' + cardPrefix[ot] + suitPre[handin.holeCards[w][v].substring(1)][ot] + handin.holeCards[w][v].substring(0,1).capitalize() + suitText[handin.holeCards[w][v].substring(1)][ot] + suitPost[handin.holeCards[w][v].substring(1)][ot]+ cardPostfix[ot];
							}
						}
					}
				}
				tx = tx + playersLeftPre[ot]+ ' (' + numPlayersLeft + ' players)' + playersLeftPost[ot];

			} else {
				
				//for other streets we just print out name of street, pot size, cards, and number of players
				//for limit games, convert pot size to number of bets
				if (numPlayersLeft > 1) {
					if (isLimitGame) {
						if (x<2) {
							potsizeinbets = handin.potSize/handin.smallBlind;
							bettext = "SB";
						} else {
							potsizeinbets = handin.potSize/handin.bigBlind;
							bettext = "BB";
						}
						
						tx = tx + ' (' + potsizeinbets.toFixed(numDigitsPot) + ' ' + bettext+ ') ';
					} else {
						tx = tx + ' (' + chipPrefix + addCommas(handin.potSize.toFixed(numDigitsPot)) + ') ';
					}
					if (handin.communityCards[x]) {
						maxY = handin.communityCards[x].length;
					} else {
						maxY=0;
					}
					
					for (y = 0; y<maxY;y++) {
	
						tx = tx + ' ' + cardPrefix[ot] + suitPre[handin.communityCards[x][y].substring(1)][ot]+ handin.communityCards[x][y].substring(0,1).capitalize() + suitText[handin.communityCards[x][y].substring(1)][ot]+ suitPost[handin.communityCards[x][y].substring(1)][ot] + cardPostfix[ot];
	
					}
					tx = tx + playersLeftPre[ot] + ' (' + numPlayersLeft + ' players)' + playersLeftPost[ot];
				}
			}

			tx = tx + lineBreaks[ot];

			//action on this street
			numFolds = 0;
			foldsDone = 0;
			dpDiscoNum = 0;
			
			//sometimes in 5CD there is no first actor on second street, so we start with next in list
			//should really fix 5CD action_players on first draw
			if (handin.action_players[1]){
				if (handin.action_players[1][0]) {
					startNum = 0;
				} else {
					startNum = 1;
				}
			}

			for (i =0;i<handin.action_players[x].length;i++) {
				if (handin.action_players[x][i]) {
					if ((handin.action_players[x][i] == handin.hero) && (handin.action_types[x][i] == 'discards')) {
						dpDiscoNum = handin.action_values[x][i];
						
					}
	
					if ((handin.gameShort == 'DRAW')  && (handin.hero) && (handin.action_types[x][i] != 'discards') && (handin.action_types[x][i] != 'stands') && (dpDisco == 1) && (x > 0)) {
						//print out heros hole cards, only if there is a hero and the discarding/standing action is over
						//also, only if there are more hole cards, i.e. the hero didn't stand pat on the last action
						if (cardout < handin.holeCards[findIndex(handin.players, handin.hero)].length) {
							tx = tx + lineBreaks[ot];
							for (countCard = 0; countCard < maxCards; countCard++) {
								
								if ((dpDiscoNum > 0) && (countCard == (maxCards - dpDiscoNum))) {
									tx = tx + ' ||';
								}
								tx = tx + ' ' + cardPrefix[ot] + suitPre[handin.holeCards[findIndex(handin.players, handin.hero)][cardout].substring(1)][ot] + handin.holeCards[findIndex(handin.players, handin.hero)][cardout].substring(0,1).capitalize() + suitText[handin.holeCards[findIndex(handin.players, handin.hero)][cardout].substring(1)][ot] + suitPost[handin.holeCards[findIndex(handin.players, handin.hero)][cardout].substring(1)][ot] + cardPostfix[ot];
								cardout++
							}
							dpDisco = 0;
							tx = tx + lineBreaks[ot];
					 }
					}
	
					//the action
					if (handin.action_types[x][i] == 'raises' | handin.action_types[x][i] == 'bets') {
						
						actionPre = betActionPre[ot];
						actionPost = betActionPost[ot];
						
						if (isLimitGame) {
							//convert to 3bet and 4bet
							if (handin.action_types[x][i]=='raises') {
								raisecounter = 0;
								for (b = 0; b <= i; ++b) {
									if (handin.action_types[x][b] == 'raises' || handin.action_types[x][b] == '3-bets' || handin.action_types[x][b] == '4-bets'|| handin.action_types[x][b] == '5-bets') {++raisecounter;}
									
								}
								if (raisecounter==2) {handin.action_types[x][i] = '3-bets';}
								if (raisecounter==3) {handin.action_types[x][i] = '4-bets';}
								if (raisecounter==4) {handin.action_types[x][i] = '5-bets';}
								if (raisecounter==5) {handin.action_types[x][i] = '6-bets';}							
							}
						}
						
					} else if (handin.action_types[x][i] == 'folds') {
						//multiple consecutive folds will be collapsed
						numPlayersLeft = numPlayersLeft - 1;
						numFolds = numFolds + 1;
						actionColor = foldColor;
						stylestart = '[i]';
						styleend = '[/i]';
						if (handin.action_types[x][parseInt(i) + 1] == 'folds') {
							//if we are hero, it doesn't get collapsed
							if (handin.action_players[x][i] == handin.hero) {
								foldsDone = 1;
							} else {
								//there's another fold coming up    
								if (handin.action_players[x][parseInt(i) + 1] == handin.hero) {
									//but its hero, so we're done
									foldsDone = 1;
								} else {
									//its not hero, collapse this one in
									foldsDone = 0;
								}
							}
						} else {
							//no more folds, were done
							foldsDone = 1;
						}
	
					} else {
						actionPre = regActionPre[ot];
						actionPost = regActionPost[ot];
					}
	
					//the actor
					//actor = handin.positions[handin.players.indexOf(handin.action_players[x][i])];
					if (showNames) {
						actor = handin.action_players[x][i];
					} else {
						actor = handin.positions[findIndex(handin.players, handin.action_players[x][i])];
					}
	
					if (handin.action_players[x][i] == handin.hero) {
						actor = "Hero";
					}
	
					//print player and action
					//collapse folds
					if (handin.action_types[x][i] == 'folds') {
						if (foldsDone) {
							//print out folds
							if (numFolds == 1) {
								//just a single one
								tx = tx + foldsPre[ot] + actor + ' ' + handin.action_types[x][i];
								numFolds = 0;
							} else {
								//several
								tx = tx + foldsPre[ot]  + numFolds + ' folds';
								numFolds = 0;
							}
							tx = tx + foldsPost[ot];
	
							//if this is the last action we want a new line, otherwise a comma
							if (i < handin.action_players[x].length - 1 && handin.action_types[x][parseFloat(i) + 1] != 'collected') {
								tx = tx + ', ';
							} else if (handin.action_types[x][parseFloat(i) + 1] == 'collected') {
								tx = tx + lineBreaks[ot] + lineBreaks[ot];
								if (handin.site !='Holdem Manager') {skipshowdown = 1;}
	
							} else {
								tx = tx + lineBreaks[ot];
							}
	
						} else {
							//do nothing -- folds collapsed
						}
					} else {
						//nonfold action
						tx = tx + actionPre + actor + ' ' + handin.action_types[x][i];
						//the values
						if (handin.action_values[x][i]) {
							if (!isLimitGame) {
								//for limit games we dont print the values
								if (handin.action_types[x][i] == 'raises') {
									tx = tx + ' to ' + chipPrefix + handin.action_values[x][i];
		
								} else if (handin.action_types[x][i] == 'discards') {
									tx = tx + ' ' + handin.action_values[x][i];
								} else {
									tx = tx + ' ' + chipPrefix + handin.action_values[x][i];
								}
								
						   } else {
						   	  	//for limit games we do show values collected
						   	  	if (handin.action_types[x][i] == 'collected') {
						   	  		tx = tx + ' ' + chipPrefix + handin.action_values[x][i];
						   	  	}
						   
						   }
						}
						tx = tx + actionPost;
	
						//if this is the last action we want a new line, otherwise a comma
						if (i < handin.action_players[x].length - 1 && handin.action_types[x][parseInt(i) + 1] != 'collected') {
							tx = tx + ', ';
						} else if (handin.action_types[x][parseInt(i) + 1] == 'collected') {
							tx = tx + lineBreaks[ot] + lineBreaks[ot];
							if (handin.site !='Holdem Manager') {skipshowdown = 1;}
	
						} else {
							tx = tx + lineBreaks[ot];
						}
	
					}
				}
			}

			tx = tx + lineBreaks[ot];

			//update pot size
			handin.potSize = cleanNum(handin.potSize) + cleanNum(handin.action_addedToPot[x]);
		}
		
		if (showResults == 2) {skipshowdown=1;}

		//showdown
		if (!skipshowdown) {
			
			if (showResults==1) {
				tx = tx + whiteResultsPre[ot];
				cardsPre = whiteCardsPre[ot];
				cardsPost = whiteCardsPost[ot];
			} else {
				cardsPre = cardPrefix[ot];
				cardsPost = cardPostfix[ot];
			}
			maxi = handin.showdown_players.length;
			for (i =0;i<maxi;i++) {
				// convert player name to position/hero for showdown
				if (handin.showdown_players[i] == handin.hero) {
					showdownplayer = 'Hero';
				}
				else {
					if (showNames) {
						showdownplayer = handin.showdown_players[i];
					} else {
						showdownplayer = handin.positions[findIndex(handin.players, handin.showdown_players[i])];
					}
				}
				if (handin.showdown_cards[i]){
					if (handin.showdown_cards[i][0] == 'mucks') {
						tx = tx + showdownplayer + ' mucked' + lineBreaks[ot];
					} else {
						if (handin.showdown_types[i] == 'mucked') {
							typetext = "mucked";
						} else {
							typetext = "showed";
						}
						if (handin.showdown_types[i] != 'collected') {
							tx = tx + showdownplayer + ' ' + typetext;
							if (handin.showdown_cards[i][1]) {
								for (w =0;w<handin.showdown_cards[i].length;w++) {
									if (showResults ==0) {
										cardText = handin.showdown_cards[i][w].substring(0,1).capitalize() + suitText[handin.showdown_cards[i][w].substring(1)][ot];
									} else {
										cardText = handin.showdown_cards[i][w].capitalize();
									}
									tx = tx + ' ' + cardsPre + suitPre[handin.showdown_cards[i][w].substring(1)][ot] + cardText + suitPost[handin.showdown_cards[i][w].substring(1)][ot] + cardsPost;
								}
							}
							if (handin.showdown_types[i] != "mucked") {
								tx = tx + ', ' + handin.showdown_hands[i];
							}
							tx = tx + lineBreaks[ot];
						}
					}
				}
				//}
			}
			//results
			for (i=0;i< handin.result_players.length;i++) {
				//convert player name to position/hero for showdown
				if (handin.result_players[i] == handin.hero) {
					resultplayer = 'Hero';
				} else {
					if (showNames) {
						resultplayer = handin.result_players[i];
					} else {
						resultplayer = handin.positions[findIndex(handin.players, handin.result_players[i])];
					}

				}
				tx = tx + resultplayer + ' won ' + chipPrefix + handin.result_values[i] + lineBreaks[ot];
			}
			if (showResults==1) {
				tx = tx + whiteResultsPost[ot];
			}
		}
		if (handin.rake && handin.gameType == "C") {
			tx = tx + '(Rake: ' + chipPrefix + handin.rake + ')' + lineBreaks[ot];
		}

		if (handin.error) {
			tx = tx + '\n\n' + handin.error;
		}

	}

	return tx;

}




function getPositionNamesStud(handin) {
	//takes list of players and seats and figures out position labels
	handin.positions = new Array;
	for (x =0;x<handin.seatNumbers.length;++x) {
		handin.positions[x] = "Seat " + handin.seatNumbers[x];
	}
	return handin;
}

function getPositionNames(handin) {

	//takes list of players and seats and figures out position labels
	//buttonIndex = handin.seatNumbers.indexOf(handin.button);
	buttonIndex = findIndex(handin.seatNumbers, handin.button)
	handin.positions = new Array;
	handin.positions[buttonIndex] = 'Button';
	maxIndex = handin.numPlayers - 1;

	if (handin.numPlayers == 2) {
		//heads up the guy not on button is BB
		bbIndex = buttonIndex + 1;
		if (bbIndex > maxIndex) {
			bbIndex = 0;
		}
		handin.positions[bbIndex] = 'BB';

	} else {

		sbIndex = buttonIndex + 1;
		if (sbIndex > maxIndex) {
			sbIndex = 0;
		}
		handin.positions[sbIndex] = 'SB';

		bbIndex = sbIndex + 1;
		if (bbIndex > maxIndex) {
			bbIndex = 0;
		}
		handin.positions[bbIndex] = 'BB';

		if (handin.numPlayers > 3) {

			utgIndex = bbIndex + 1;
			if (utgIndex > maxIndex) {
				utgIndex = 0;
			}
			handin.positions[utgIndex] = 'UTG';

			if (handin.numPlayers > 4) {

				coIndex = buttonIndex - 1;
				if (coIndex < 0) {
					coIndex = handin.numPlayers - 1;
				}
				handin.positions[coIndex] = "CO";

				if (handin.numPlayers > 5) {
					utg1Index = utgIndex + 1;
					if (utg1Index > maxIndex) {
						utg1Index = 0;
					}
					handin.positions[utg1Index] = "UTG+1";

					if (handin.numPlayers > 6) {
						hjIndex = coIndex - 1;
						if (hjIndex < 0) {
							hjIndex = maxIndex;
						}
						handin.positions[hjIndex] = "HJ";

						if (handin.numPlayers > 7) {
							mpIndex = utg1Index + 1;
							if (mpIndex > maxIndex) {
								mpIndex = 0;
							}
							handin.positions[mpIndex] = "MP";

							if (handin.numPlayers > 8) {
								mp2Index = mpIndex + 1;
								if (mp2Index > maxIndex) {
									mp2Index = 0;
								}
								handin.positions[mp2Index] = "MP2";

								if (handin.numPlayers > 9) {
									mp3Index = mp2Index + 1;
									if (mp3Index > maxIndex) {
										mp3Index = 0;
									}
									handin.positions[mp3Index] = "MP3";

									if (handin.numPlayers > 10) {

										handin.error = "WTF, more than 10 players?! I cannot handle this.";

									}
								}
							}
						}
					}
				}
			}
		}
	}

	return handin;

}

function getRandomTagLine() {

	//returns a random tagline from the list
	tagLines = ['Milked from the teat of a feral cow', 'Converted by a herd of feral cows', 'A pack of feral cows chewed their cuds for .0043 seconds to convert this hand', 'Moooooooooooraaawwwr.', 'Feral Cow Poker Hand Converter', 'Feral Cow Poker Hand Converter', 'Feral Cow Poker Hand Converter', 'Feral Cow Poker Hand Converter', 'Feral Cow Poker Hand Converter', 'Converting hands till the cows come home', 'Cows play poker with cow chips', 'Dont have a cow, heres your converted hand', 'This converter is going to be a cash cow...', 'Your converted hand, now with more cowbell.', 'Feral Cow Poker', 'Feral Cow Poker', 'Feral Cow Poker', 'once a cow has a taste for violence, it reverts. it becomes feral.', 'beware the feral cow packs. they hunger.', 'Converted by the cows of Feral Cow Poker', 'Feral Cow Converter: By old guys, for old guys'

	];

	rand_no = Math.floor(Math.random() * (tagLines.length - 1));
	theLine = tagLines[rand_no];

	return theLine;

}

function HEMParseAction (handin,text,street) {

		//this function parses the action lines on each street

		lines = text.split(/■/);
		
		handin.action_types[street] = new Array;
		handin.action_players[street] = new Array;
		handin.action_values[street] = new Array;
		handin.action_addedToPot[street] = new Array;
		handin.action_addedToPot[street] = 0;
		
		//loop through action lines
		playerCount = 0;
		currentMaxBet = 0;
		
		for(i = 0; i < lines.length; i = i + 1) {
			
			//skip the lines that have stuff we don't want to treat as action
			if (!lines[i].match(/Dealt to/) && !lines[i].match(/\*/) && !lines[i].match(/doesn\'t/)) { //'
				
				if (lines[i].match(/ wins/)) {
				
					//if there is an uncalled bet, subtract that amount from the pot
					regexstring = /(.*) wins [\$]?([\d|\.|\,]+)/;
					result = lines[i].match(regexstring);
					if (result) {
						uncalledAmount = result[2];
						uncalledPlayer = result[1];
										
						handin.action_addedToPot[street] = parseFloat(handin.action_addedToPot[street]) - parseFloat(uncalledAmount);
					}
				} else {

					
					//get action names
					result=lines[i].match(/(.*) (?:folds|raises|calls|bets|checks)/);
					if (result) {handin.action_players[street][playerCount] = result[1];}
					
					//get action types
					result=lines[i].match(/((?:folds|raises|calls|bets|checks))/);
					if (result) {handin.action_types[street][playerCount] = result[1];}
					
					if (lines[i].match(/((?:folds|raises|calls|bets|checks))/)) {
						//get action values
						regexstring=/\[[\$]?([\d|\.|\,]+).*\]/;
						result=lines[i].match(regexstring);
						if (result) {
							handin.action_values[street][playerCount] = result[1];
							actionDigits = getPrecision(handin.action_values[street][playerCount]);	
						} else if (handin.action_types[street][playerCount] == 'discards') {
		                    // discards
		                    regexstring=/discards (\d+)/;
		                    result=lines[i].match(regexstring);
		                    if (result) {
		                        handin.action_values[street][playerCount] = result[1];
		                    }
	                	}   					
						//get $ added to pot
						if (handin.action_values[street][playerCount]){
							
							playerIndex = findIndex(handin.players,handin.action_players[street][playerCount]);					
							
							if (handin.action_types[street][playerCount] == 'raises'){
									
									newval = parseFloat(handin.action_values[street][playerCount]) + parseFloat(handin.action_playersPot[playerIndex]);
									handin.action_playersPot[playerIndex] = newval;
									handin.action_addedToPot[street] = parseFloat(handin.action_addedToPot[street]) + parseFloat(handin.action_values[street][playerCount]);
									handin.action_values[street][playerCount] = newval.toFixed(actionDigits);
								
								
							
							} else {
								//for bets and calls just add the amount bet or called
								newval = parseFloat(handin.action_playersPot[playerIndex]) + parseFloat(handin.action_values[street][playerCount]);
								handin.action_playersPot[playerIndex] = newval;
								handin.action_addedToPot[street] = parseFloat(handin.action_addedToPot[street]) + parseFloat(handin.action_values[street][playerCount]);
								
								
							}
						
						}
					}
					//deal with action ending and someone collecting
					if (lines[i].match(/ wins/)) {
						result = lines[i].match(/(.+) wins/);
						if (result) {handin.action_players[street][playerCount] = result[1];}
						
						handin.action_types[street][playerCount] = 'collected';
						
						regexstring = /wins [\$]?([\d|\.|\,]+)/;
							
						result=lines[i].match(regexstring);
						if (result) {handin.action_values[street][playerCount] = result[1];}
					}
					
					playerCount = playerCount + 1;
				}
				
				
				
			}
		
		}

		return handin;
}


function pokerStarsParseAction (handin,text,street) {

		//this function parses the action lines on each street

		lines = text.split(/■/);
		
		handin.action_types[street] = new Array;
		handin.action_players[street] = new Array;
		handin.action_values[street] = new Array;
		handin.action_addedToPot[street] = new Array;
		handin.action_addedToPot[street] = 0;
		
		//loop through action lines
		playerCount = 0;
		for(i = 0; i < lines.length; i = i + 1) {
			
			//skip the lines that have stuff we don't want to treat as action
			if (!lines[i].match(/Dealt to/) && !lines[i].match(/\*/) && !lines[i].match(/doesn\'t/)) { //'
				
				if (lines[i].match(/Uncalled bet/)) {
				
					//if there is an uncalled bet, subtract that amount from the pot
					if (handin.gameType == "C") {regexstring = /Uncalled bet \(\$(\S+)\) returned to (.*)/;}
					else {regexstring = /Uncalled bet \((\S+)\) returned to (.*)/;}
					result = lines[i].match(regexstring);
					if (result) {
						uncalledAmount = result[1];
						uncalledPlayer = result[2];
										
						handin.action_addedToPot[street] = parseFloat(handin.action_addedToPot[street]) - parseFloat(uncalledAmount);
					}
				} else {

				
					//get action names
					result=lines[i].match(/(.*)\: /);
					if (result) {handin.action_players[street][playerCount] = result[1];}
					
					//get action types
					result=lines[i].match(/\: (\S*)/);
					if (result) {handin.action_types[street][playerCount] = result[1];}
					
					//get action values
					regexstring = /(?:checks|raises|bets|folds|calls) [\$]?(.+)/;
					result=lines[i].match(regexstring);
					if (result) {handin.action_values[street][playerCount] = result[1];
					
					} else if (handin.action_types[street][playerCount] == 'discards') {
	                    // discards
	                    regexstring=/discards (\d+)/;
	                    result=lines[i].match(regexstring);
	                    if (result) {
	                        handin.action_values[street][playerCount] = result[1];
	                    }
                	}   					
					//get $ added to pot
					if (handin.action_values[street][playerCount]){
						
						//playerIndex = handin.players.indexOf(handin.action_players[street][playerCount]);
						playerIndex = findIndex(handin.players,handin.action_players[street][playerCount]);					
						
						if (handin.action_types[street][playerCount] == 'raises'){
							//for raises, we have to subtract amount already bet by the same player
							regexstring = /to [\$]?([\d|,|\.]+)/;
							result=handin.action_values[street][playerCount].match(regexstring);
							if (result) {newval = parseFloat(result[1]) - parseFloat(handin.action_playersPot[playerIndex]);
								handin.action_playersPot[playerIndex] = newval;
								handin.action_addedToPot[street] = parseFloat(handin.action_addedToPot[street]) + parseFloat(newval);
								//take of beginning for formatting
								result = handin.action_values[street][playerCount].match(/to [\$]?(.*)/);
								if (result) {handin.action_values[street][playerCount] = result[1];}
							 }
						
						} else if ((handin.action_types[street][playerCount] == 'bets') || (handin.action_types[street][playerCount] == 'calls')) {
						    
							//for bets and calls just add the amount bet or called
							regexstring = /[\$]?([\d|,|\.]+)/;
							result=handin.action_values[street][playerCount].match(regexstring);
							if (result) {
								newval = parseFloat(handin.action_playersPot[playerIndex]) + parseFloat(result[1]);
								handin.action_playersPot[playerIndex] = newval;
								handin.action_addedToPot[street] = parseFloat(handin.action_addedToPot[street]) + parseFloat(result[1]);
							}
							
							
						}
					
					}
					//deal with action ending and someone collecting
					if (lines[i].match(/collected/)) {
						result = lines[i].match(/(.+) collected/);
						if (result) {handin.action_players[street][playerCount] = result[1];}
						handin.action_types[street][playerCount] = 'collected';
						
						regexstring = /collected [\$]?([\d|,|\.]+) from/;
						result=lines[i].match(regexstring);
						if (result) {handin.action_values[street][playerCount] = result[1];}
						
					}
					
					playerCount = playerCount + 1;
				}
				
				
				
			}
		
		}

		return handin;
}


function ftpParseAction(handin, text, street) {

	//this function parses the action lines on each street
	lines = text.split(/■/);

	handin.action_types[street] = new Array;
	handin.action_players[street] = new Array;
	handin.action_values[street] = new Array;
	handin.action_addedToPot[street] = new Array;
	handin.action_addedToPot[street] = 0;

	//loop through action lines
	playerCount = 0;
	for (i = 0; i < lines.length; i = i + 1) {

		//skip the lines that have stuff we don't want to treat as action			
		if (!lines[i].match(/(?:Dealt to|\*|doesn\'t|\[|blinds|\:|mucks|sitting out|adds|disconnected|reconnected|seconds|stands up|has returned)/)) { //'
			if (lines[i].match(/Uncalled bet/)) {
								
				//if there is an uncalled bet, subtract that amount from the pot
				regexstring = /Uncalled bet of [?:\$]([\d|,|\.]+) returned to (.*)/;
				
				result = lines[i].match(regexstring);
				if (result) {
					uncalledAmount = result[1];
					uncalledPlayer = result[2];
					handin.action_addedToPot[street] = cleanNum(handin.action_addedToPot[street]) - cleanNum(uncalledAmount);
						
				}
			} else {

				//get action names
				result = lines[i].match(/(.*?) (checks|raises|bets|folds|calls)/);
				if (result) {
					handin.action_players[street][playerCount] = result[1];
				}

				//get action types
				result = lines[i].match(/ (checks|raises|bets|folds|calls)/);
				if (result) {
					handin.action_types[street][playerCount] = result[1];
				}

				//get action values
				regexstring = /(?:checks|raises|bets|folds|calls) [\$]?(.+)/;
				//	else {regexstring=/ (?:checks|raises to|bets|folds|calls) (.+)/;}
				result = lines[i].match(regexstring);
				if (result) {
					handin.action_values[street][playerCount] = result[1];
				}

				
				//adjust for lhe
				if (handin.gameShort == "LHE") {
					if (handin.action_types[street][playerCount] == "raises") {
						handin.action_values[street][playerCount] = "to " + handin.action_values[street][playerCount];
					}
				}

				//get $ added to pot
				if (handin.action_values[street][playerCount]) {

					//playerIndex = handin.players.indexOf(handin.action_players[street][playerCount]);
					playerIndex = findIndex(handin.players, handin.action_players[street][playerCount]);

					if (handin.action_types[street][playerCount] == 'raises') {
						//for raises, we have to subtract amount already bet by the same player
						
						result = handin.action_values[street][playerCount].match(/to [\$]?([\d|,|\.]+)/);
						if (result) {
							newval = cleanNum(result[1]) - cleanNum(handin.action_playersPot[playerIndex]);
							handin.action_playersPot[playerIndex] = newval;
							handin.action_addedToPot[street] = cleanNum(handin.action_addedToPot[street]) + cleanNum(newval);
							result = handin.action_values[street][playerCount].match(/to [\$]?(.*)/);
							if (result) {handin.action_values[street][playerCount] = result[1];}
						}

					} else {
						//for bets and calls just add the amount bet or called
						regexstring = /([\d|,|\.]+)/;
						
						result = handin.action_values[street][playerCount].match(regexstring);
						if (result) {
							newval = cleanNum(handin.action_playersPot[playerIndex]) + cleanNum(result[1]);
							handin.action_playersPot[playerIndex] = newval;
							handin.action_addedToPot[street] = cleanNum(handin.action_addedToPot[street]) + cleanNum(result[1]);
						}

					}

				}
				//deal with action ending and someone collecting
				if (lines[i].match(/ wins/)) {
					/*
result = lines[i].match(/(.+) wins/);
						if (result) {handin.action_players[street][playerCount] = result[1];}
						
						handin.action_types[street][playerCount] = 'collected';
						
						if (handin.gameType == "C") {regexstring = /wins the pot \((\$.+)\)/;}
							else {regexstring=/wins the pot \((.+)\)/;}
						result=lines[i].match(regexstring);
						if (result) {handin.action_values[street][playerCount] = result[1];}
*/

				}

				playerCount = playerCount + 1;
			}

		}

	}

	return handin;
}

function cereusParseAction(handin, text, street) {

	//this function parses the action lines on each street
	lines = text.split(/■/);

	handin.action_types[street] = new Array;
	handin.action_players[street] = new Array;
	handin.action_values[street] = new Array;
	handin.action_addedToPot[street] = new Array;
	handin.action_addedToPot[street] = 0;

	//loop through action lines
	playerCount = 0;
	for (i = 0; i < lines.length; i = i + 1) {

		//skip the lines that have stuff we don't want to treat as action			
		if (!lines[i].match(/(?:Dealt to|\*|doesn\'t|\[|blinds|\:|mucks|sitting out|adds)/)) { //'
			if (lines[i].match(/Uncalled bet/)) {

				//if there is an uncalled bet, subtract that amount from the pot
				if (handin.gameType == "C") {
					//regexstring = /Uncalled bet \(\$(\S+)\) returned to (.*)/;
					regexstring = /(.*) \- returned \(\$(\S+)\) \: not called/;
				}
				else {
					regexstring = /(.*) \- returned \((\S+)\) \: not called/;
				}
				result = lines[i].match(regexstring);
				if (result) {
					uncalledAmount = result[2];
					uncalledPlayer = result[1];
					handin.action_addedToPot[street] = cleanNum(handin.action_addedToPot[street]) - cleanNum(uncalledAmount);
				}
			} else {

				//get action names
				result = lines[i].match(/(.*?) \- (Checks|Raises|Bets|Folds|Calls|All\-In)/);
				if (result) {
					handin.action_players[street][playerCount] = result[1];
				}

				//get action types
				result = lines[i].match(/\- (Checks|Raises|Bets|Folds|Calls|All\-In)/);
				if (result) {
					handin.action_types[street][playerCount] = result[1].toLowerCase();
				}

				//get action values
				if (handin.gameType == "C") {
					regexstring = /\$(.*)/;
				}
				else {
					regexstring = / (?:Checks|Raises|Bets|Folds|Calls|All\-In).*? (.+)/;
				}
				result = lines[i].match(regexstring);
				if (result) {
					handin.action_values[street][playerCount] = result[1];
				}

				//deal with cereus all-in nonsense
				if (handin.action_types[street][playerCount] == 'all-in') {
										
					if (playerCount > 0) {
						
						prevValue = handin.action_values[street][playerCount-1];
						currentValue = handin.action_values[street][playerCount];
						
						
						
						if (prevValue) {
					
							
							if (cleanNum(prevValue) < cleanNum(currentValue)) {
								handin.action_types[street][playerCount] = 'raises';
								handin.action_values[street][playerCount] = handin.action_values[street][playerCount] + ' and is all-in';
							} else {
								handin.action_types[street][playerCount] = 'calls';
								handin.action_values[street][playerCount] = handin.action_values[street][playerCount] + ' and is all-in';
							
							}
						} else {
							
							handin.action_types[street][playerCount] = 'bets';
							handin.action_values[street][playerCount] = handin.action_values[street][playerCount] + ' and is all-in';

						}
					} else {
						
						handin.action_types[street][playerCount] = 'bets';
						handin.action_values[street][playerCount] = handin.action_values[street][playerCount] + ' and is all-in';
					}
				
				}
			
				//get $ added to pot
				if (handin.action_values[street][playerCount]) {

					//playerIndex = handin.players.indexOf(handin.action_players[street][playerCount]);
					playerIndex = findIndex(handin.players, handin.action_players[street][playerCount]);

					if (handin.action_types[street][playerCount] == 'raises') {
						
						//for raises, we have to subtract amount already bet by the same player
						if (handin.gameType == "C") {
							regexstring = /to \$(.+)/;
						}
						else {
							regexstring = /to (\d+.*)/;
						}
						result = handin.action_values[street][playerCount].match(regexstring);
						if (result) {
							newval = cleanNum(result[1]) - cleanNum(handin.action_playersPot[playerIndex]);
							handin.action_values[street][playerCount] = result[1];
							handin.action_playersPot[playerIndex] = newval;
							handin.action_addedToPot[street] = cleanNum(handin.action_addedToPot[street]) + cleanNum(newval);
						}

					} else {
						//for bets and calls just add the amount bet or called	
						newval = cleanNum(handin.action_playersPot[playerIndex]) + cleanNum(handin.action_values[street][playerCount]);
						handin.action_playersPot[playerIndex] = newval;
						handin.action_addedToPot[street] = cleanNum(handin.action_addedToPot[street]) + cleanNum(handin.action_values[street][playerCount]);

					}

				}
				//deal with action ending and someone collecting
				if (lines[i].match(/wins/)) {
					/*
result = lines[i].match(/(.+) wins/);
						if (result) {handin.action_players[street][playerCount] = result[1];}
						
						handin.action_types[street][playerCount] = 'collected';
						
						if (handin.gameType == "C") {regexstring = /wins the pot \((\$.+)\)/;}
							else {regexstring=/wins the pot \((.+)\)/;}
						result=lines[i].match(regexstring);
						if (result) {handin.action_values[street][playerCount] = result[1];}
*/

				}

				playerCount = playerCount + 1;
			}

		}

	}

	return handin;
}

function titanParseAction(handin, text, street) {

	
	handin.action_types[street] = new Array;
	handin.action_players[street] = new Array;
	handin.action_values[street] = new Array;
	handin.action_addedToPot[street] = new Array;
	handin.action_addedToPot[street] = 0;
	
	currentAction = handin.currentAction + 1;
	moreToGo = 1;
	actionThisStreet = 0;
	maxBet = 0;
	while (moreToGo) {
	
		
		myRegEx = new RegExp;
		myRegEx.compile('(action no=\"' + currentAction +'\".*?/>)');
		result = myRegEx.exec(text);
		if(result) {
			thisAction = result[1];
			
			//get name
			name = thisAction.match(/player=\"(.*?)\"/);
			if(name) {handin.action_players[street][actionThisStreet] = RegExp.$1;}
			
			
			//get action type
			type = thisAction.match(/type=\"(\d+)\"/);
			if (type) {
				
				
				if(type[1] == 0) {typename = "folds";}
				if(type[1] == 3) {typename = "calls";}
				if(type[1] == 4) {typename = "checks";}
				if(type[1] == 5) {typename = "bets";}
				if(type[1] == 7) {typename = "calls all-in";}
				if(type[1] == 23) {typename = "raises";}
				
				
				handin.action_types[street][actionThisStreet] = typename;
				
			}
			
			//get values
			if (typename != "checks" && typename != "folds") {
				value = thisAction.match(/sum=\".*?([\d|,|\.]+)\"/);
				if (value) {handin.action_values[street][actionThisStreet] = value[1];}
			}
			
			//set max bet
			if ((handin.action_types[street][actionThisStreet] == "bets") || (handin.action_types[street][actionThisStreet] == "raises")) {
				maxBet = handin.action_values[street][actionThisStreet];
			}
			
			//calculate value added to pot
			if (handin.action_values[street][actionThisStreet]) {
				
					playerIndex = findIndex(handin.players,handin.action_players[street][actionThisStreet]);
					
					if (handin.action_types[street][actionThisStreet] == 'raises'){
						
						//for raises, we have to subtract amount already bet by the same player
						newval = parseFloat(handin.action_values[street][actionThisStreet]) - parseFloat(handin.action_playersPot[playerIndex]); 
						handin.action_playersPot[playerIndex] = newval;
						handin.action_addedToPot[street] = parseFloat(handin.action_addedToPot[street]) + newval;						
						
					} else if ( handin.action_types[street][actionThisStreet].match(/bets/)  ) {
					
						//for bets and calls just add the amount bet or called
						newval = parseFloat(handin.action_values[street][actionThisStreet]) + parseFloat(handin.action_playersPot[playerIndex]); 
						handin.action_playersPot[playerIndex] = newval;
						
						handin.action_addedToPot[street] = parseFloat(handin.action_addedToPot[street]) + parseFloat(handin.action_values[street][actionThisStreet]);

					} else if (handin.action_types[street][actionThisStreet].match(/calls/)) {
					
						//for calls add the amount called, make sure it equals max bet for all-in control
						newval = parseFloat(handin.action_values[street][actionThisStreet]) + parseFloat(handin.action_playersPot[playerIndex]); 
						
						extramoney = maxBet-newval;
				
						handin.action_playersPot[playerIndex] = newval;		
						//now, we could subtract extramoney, but Titan includes everything bet in what is won, so for now we won't	
						handin.action_addedToPot[street] = parseFloat(handin.action_addedToPot[street]) + parseFloat(handin.action_values[street][actionThisStreet]);

					
					
					}
				
			}
			
			currentAction = currentAction + 1;			
			actionThisStreet = actionThisStreet + 1;
		} else {
		
		 moreToGo = 0;
		}
		
		
	}
	handin.currentAction = currentAction-1;
	
	return handin;
}

function cleanNum(num) {

	if (num) {
		num = '' + num;
		num = num.replace(/\,/g, "");
		num = parseFloat(num);
	}
	return num;

}

function findIndex(theArray, theTarget) {

	targetIndex = -1;

	for (xx = 0; xx < theArray.length; xx++) {
		if (theArray[xx] == theTarget) {
			targetIndex = xx;
		}
	}

	
	return targetIndex;
}

function escapeText(str) {

	return (str + '').replace(/([\\"'\(\)])/g, "\\$1").replace(/\0/g, "\\0");
}

function addCommas(nStr)
{
	nStr += '';
	u = nStr.split('.');
	x1 = u[0];
	x2 = u.length > 1 ? '.' + u[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}

function getPrecision(num) {

	numString = num.toString();
	
	result = numString.match(/\.(.*)/);
	
	if (result) {
		digs = result[1];
		numDigs = digs.length;
	} else {
		numDigs = 0;
	}
	
	return numDigs;
}

function addslashes(str) {
	
	if(str) {
		str=str.replace(/\$/g,'\\$');
		str=str.replace(/\./g,'\\.');
		str=str.replace(/\:/g,'\\:');
		str=str.replace(/\[/g,'\\[');
		str=str.replace(/\]/g,'\\]');
		str=str.replace(/\"/g,'\\"');
		str=str.replace(/\(/g,'\\(');
		str=str.replace(/\)/g,'\\)');
		str=str.replace(/\?/g,'\\?');
		str=str.replace(/\*/g,'\\*');
	}
	return str;
	
}

function reverseCards(cardstring) {

	newstring = cardstring.substr(1,1) + cardstring.substr(0,1);
	return newstring;
}