+
+ # don't evaluate if it has factoid arguments.
+ if ($message =~ /^CMD:/i) {
+ &status("Reply: not doing substVars (eval dollar vars)");
+ } else {
+ $reply = &substVars($reply,1);
+ }
+
+ $reply;
+}
+
+sub smart_replace {
+ my ($string) = @_;
+ my ($l,$r) = (0,0); # l = left, r = right.
+ my ($s,$t) = (0,0); # s = start, t = marker.
+ my $i = 0;
+ my $old = $string;
+ my @rand;
+
+ foreach (split //, $string) {
+
+ if ($_ eq "(") {
+ if (!$l and !$r) {
+ $s = $i;
+ $t = $i;
+ }
+
+ $l++;
+ $r--;
+ }
+
+ if ($_ eq ")") {
+ $r++;
+ $l--;
+
+ if (!$l and !$r) {
+ my $substr = substr($old,$s,$i-$s+1);
+ push(@rand, substr($old,$t+1,$i-$t-1) );
+
+ my $rand = $rand[rand @rand];
+# &status("SARing '$substr' to '$rand'.");
+ $string =~ s/\Q$substr\E/$rand/;
+ undef @rand;
+ }
+ }
+
+ if ($_ eq "|" and $l+$r== 0 and $l==1) {
+ push(@rand, substr($old,$t+1,$i-$t-1) );
+ $t = $i;
+ }
+
+ $i++;
+ }
+
+ if ($old eq $string) {
+ &WARN("smart_replace: no subst made. (string => $string)");
+ }
+
+ return $string;
+}
+
+sub SARit {
+ my($txt) = @_;
+ my $done = 0;
+
+ # (blah1|blah2)?
+ while ($txt =~ /\((.*?)\)\?/) {
+ my $str = $1;
+ if (rand() > 0.5) { # fix.
+ &status("Factoid transform: keeping '$str'.");
+ $txt =~ s/\(\Q$str\E\)\?/$str/;
+ } else { # remove
+ &status("Factoid transform: removing '$str'.");
+ $txt =~ s/\(\Q$str\E\)\?\s?//;
+ }
+ $done++;
+ last if ($done >= 10); # just in case.
+ }
+ $done = 0;
+
+ # EG: (0-32768) => 6325
+ ### TODO: (1-10,20-30,40) => 24
+ while ($txt =~ /\((\d+)-(\d+)\)/) {
+ my ($lower,$upper) = ($1,$2);
+ my $new = int(rand $upper-$lower) + $lower;
+
+ &status("SARing '$&' to '$new' (2).");
+ $txt =~ s/$&/$new/;
+ $done++;
+ last if ($done >= 10); # just in case.
+ }
+ $done = 0;
+
+ # EG: (blah1|blah2|blah3|) => blah1
+ while ($txt =~ /.*\((.*\|.*?)\).*/) {
+ $txt = &smart_replace($txt);
+
+ $done++;
+ last if ($done >= 10); # just in case.
+ }
+ &status("Reply.pl: $done SARs done.") if ($done);
+
+ return $txt;
+}
+
+sub substVars {
+ my($reply,$flag) = @_;
+