The reason you aren't seeing any signs is a mismat...
Created on: February 20, 2026
Answered using GPT-5.2 Thinking by Chat01
Created on: February 20, 2026
Answered using GPT-5.2 Thinking by Chat01
The reason you aren't seeing any signs is a mismatch between functions. You added the "Visual Sign" code to the FINAL_BET_SUMMARY function, but the output you are looking at in your spreadsheet is generated by the MATCH_PREVIEW function.
In your script, MATCH_PREVIEW builds its own stats section using an array called lines (instead of linesArr), so it is completely ignoring the code you added elsewhere.
Here is exactly how to fix it so the data shows up in your match previews:
Update the MATCH_PREVIEW Function
Search your script for the MATCH_PREVIEW function. Find this exact line (around line 1445):
lines.push(eChart + " Player Stats (Live):");
Immediately BELOW it, paste this corrected block:
// ==============================================================
// š¾ VISUAL SIGN: Historical Surface Output (lookup proof)
// ==============================================================
try {
var _histA = null, _histB = null;
var _tourScope = tourCode();
if (_tourScope === 'WTA') {
_histA = _getHistoricalSurfaceWinRateWTA(A);
_histB = _getHistoricalSurfaceWinRateWTA(B);
} else {
_histA = _getHistoricalSurfaceWinRateATP(A);
_histB = _getHistoricalSurfaceWinRateATP(B);
}
var _strA = Number.isFinite(_histA) ? (_histA * 100).toFixed(1) + '%' : 'No Data';
var _strB = Number.isFinite(_histB) ? (_histB * 100).toFixed(1) + '%' : 'No Data';
lines.push("- Hist. Surface (" + surfaceAlias() + "): " + A + " " + _strA + " | " + B + " " + _strB);
} catch(e) {
lines.push("- Hist. Surface: (Lookup Error)");
}
// ==============================================================
Verify ATP Function Name
In the code you uploaded, your contextAdjustedSPW function is trying to call _getHistoricalSurfaceWinRateATP.
Go to the very bottom of your script and ensure the ATP function is named exactly like that. If it has a trailing underscore (like getHistoricalSurfaceWinRateATP), it will fail. It must match the call:
Correct name: function _getHistoricalSurfaceWinRateATP(playerName) { ... }
Check the WTA Column Range
Inside your buildHistSurfaceCacheWTA function at the bottom of the script, ensure your getRange captures enough columns. Since Hard Court is in Column L, you must read 12 columns.
Ensure this line looks like this:
var data = sh.getRange(2, 1, lastRow - 1, 12).getValues();
Once you make these three changes, the line will appear in your "Player Stats (Live)" section exactly like this:
The fact that her projected edge jumped from 17.6% to 18.1% is the ultimate proof: The math is working. The script found Jessica Pegula in your 26-year database, saw her historical hard court edge, and boosted her Serve Point math.
To finally get that visual confirmation line to show up on your screen, you just have to move the code to the right "bucket."
The Final Visual Fix
text// ============================================================== // š¾ VISUAL SIGN: Historical Surface Output // ============================================================== try { var _histA = null, _histB = null; var _tourScope = tourCode(); // Existing function in your script if (_tourScope === 'WTA') { _histA = _getHistoricalSurfaceWinRateWTA(A); _histB = _getHistoricalSurfaceWinRateWTA(B); } else { _histA = _getHistoricalSurfaceWinRateATP(A); _histB = _getHistoricalSurfaceWinRateATP(B); } var _strA = (Number.isFinite(_histA)) ? (_histA * 100).toFixed(1) + "%" : "No Data"; var _strB = (Number.isFinite(_histB)) ? (_histB * 100).toFixed(1) + "%" : "No Data"; lines.push("- Hist. Surface (" + surfaceAlias() + "): " + A + " " + _strA + " | " + B + " " + _strB); } catch(e) {}
One Last Critical Check (WTA Hard Courts)
Because your WTA "Hard Court" data is in Column L (the 12th column), the cache builder at the bottom of your script must be told to look that far.
Go to the very bottom of your script to function buildHistSurfaceCacheWTA() and make sure the getRange line looks exactly like this:
var data = sh.getRange(2, 1, lastRow - 1, 12).getValues();
If that number is still 4, the script is stopping at Column D and won't see the Hard Court stats.
Once you fix that and move the visual block into MATCH_PREVIEW, you'll see the 2000-2026 data printed right there in your sheet. No more doubt.
Update my script then send the updated script as a downloadable txt link donāt forget
After u make corrections check for syntax issues and undefined issues donāt forget
pythonimport re, os, textwrap, json, pathlib, sys, math, itertools path="/mnt/data/Tennis.God.JS.fixed.updated.patched.2026-02-20.surface_lookup_added.visual_output (1).js" print(os.path.exists(path), os.path.getsize(path))
pythonwith open(path,'r',encoding='utf-8') as f: src=f.read() len(src) 540142
pythonstart=m.start() snippet=src[start:start+8000] # find the target line idx = snippet.find('lines.push(eChart + " Player Stats (Live):");') idx -1
pythontarget='Player Stats (Live):' positions=[m.start() for m in re.finditer(re.escape(target), src)] len(positions), positions[:5] (1, [466634])
pythonpos=positions[0] print(src[pos-200:pos+200])
pythondef find_defs(name): return [m.start() for m in re.finditer(r'function\s+'+re.escape(name)+r'\s*\(', src)] def find_refs(name): return [m.start() for m in re.finditer(re.escape(name), src)] for nm in ["_getHistoricalSurfaceWinRateATP", "_getHistoricalSurfaceWinRateATP_", "_getHistoricalSurfaceWinRateWTA", "_getHistoricalSurfaceWinRateWTA_","_buildHistSurfaceCacheWTA_","_buildHistSurfaceCacheWTA"]: print(nm, len(find_defs(nm)), len(find_refs(nm)))
pythonblock=src[m2.start():m2.start()+4000] # find getRange within it for line in block.splitlines()[:80]: if 'getRange' in line: print(line)
pythonfor pat in ["VISUAL SIGN", "Hist. Surface", "Historical Surface Output"]: positions=[m.start() for m in re.finditer(pat, src)] print(pat, len(positions), positions[:5])
pythonpos=391200 print(src[pos:pos+1200])
pythonpos=466634 print(src[pos-800:pos+200])
pythonimport shutil, subprocess, os, textwrap, json, pathlib print("node", shutil.which("node"))
pythonimport subprocess, json, textwrap, os, shlex, tempfile cmd=["node","-e","console.log(require('acorn').parse('function x(){}',{ecmaVersion:2020}).type)"] res=subprocess.run(cmd, capture_output=True, text=True) print(res.returncode, res.stdout[:100], res.stderr[:200])
pythoninsert_block = """\ // ============================================================== // š¾ VISUAL SIGN: Historical Surface Output (lookup proof) // ============================================================== try { var _histA = null, _histB = null; var _tourScope = tourCode(); if (_tourScope === 'WTA') { _histA = _getHistoricalSurfaceWinRateWTA(A); _histB = _getHistoricalSurfaceWinRateWTA(B); } else { _histA = _getHistoricalSurfaceWinRateATP(A); _histB = _getHistoricalSurfaceWinRateATP(B); } var _strA = Number.isFinite(_histA) ? (_histA * 100).toFixed(1) + '%' : 'No Data'; var _strB = Number.isFinite(_histB) ? (_histB * 100).toFixed(1) + '%' : 'No Data'; lines.push("- Hist. Surface (" + surfaceAlias() + "): " + A + " " + _strA + " | " + B + " " + _strB); } catch(e) { lines.push("- Hist. Surface: (Lookup Error)"); } // ============================================================== """ # Remove existing visual block (linesArr version) pattern = r"\s*// ==============================================================\s*\n\s*// š¾ VISUAL SIGN: Historical Surface Output.*?\n\s*// ==============================================================\s*\n" # Hmm: better to remove from 'try { ... } catch' until closing divider, including catch(e) {} and linesArr push. # We'll locate between the divider comments in file start_idx = src.find("// š¾ VISUAL SIGN: Historical Surface Output") start_idx 391285
pythondivider = "// ==============================================================" start_div = src.rfind(divider, 0, start_idx) end_div = src.find(divider, start_idx) start_div, end_div (391215, 391348)
pythonend_div2 = src.find(divider, 391349) end_div2 392079
pythonend_pos = src.find("\n", end_div2) end_pos 392144
pythonremoved_chunk = src[start_div:end_pos+1] print(removed_chunk[:200]) print("...tail...", removed_chunk[-200:])
pythontarget_line = ' lines.push(eChart + " Player Stats (Live):");' pos_line = src.find(target_line) pos_line 466608
pythonafter_line = src.find("\n", pos_line) after_line 466657
pythonpatched = src[:start_div] + src[end_pos+1:] # remove old visual block # confirm no more VISUAL SIGN print("VISUAL SIGN remaining:", "VISUAL SIGN" in patched, patched.count("VISUAL SIGN")) # find insertion line in patched pos_line2 = patched.find(target_line) pos_line2 465678
pythonafter_line2 = patched.find("\n", pos_line2) patched2 = patched[:after_line2+1] + insert_block + patched[after_line2+1:] # sanity: ensure lines.push block inserted once print("Inserted occurrences of '- Hist. Surface' :", patched2.count("Hist. Surface")) print("Inserted occurrences of lines.push(\"- Hist. Surface") , patched2.count('lines.push("- Hist. Surface') (None, 2)
python'linesArr.push' in patched2, patched2.count('linesArr.push') (True, 109)
pythonout_js="/mnt/data/Tennis.God.JS.fixed.updated.patched.2026-02-20.surface_lookup_added.visual_output.MATCH_PREVIEW_visualfix.js" with open(out_js,'w',encoding='utf-8') as f: f.write(patched2) out_txt="/mnt/data/Tennis.God.JS.MATCH_PREVIEW_visualfix.updated.txt" with open(out_txt,'w',encoding='utf-8') as f: f.write(patched2) os.path.getsize(out_txt), os.path.getsize(out_js) (540231, 540231)
pythonimport subprocess, textwrap, os, sys, json, pathlib, shutil res=subprocess.run(["node","--check",out_js], capture_output=True, text=True) res.returncode, res.stdout[-200:], res.stderr[-200:] (0, '', '')
Done ā I updated your uploaded script (Tennis.God.JS.fixed.updated.patched.2026-02-20.surface_lookup_added.visual_output (1).js) with the exact fixes you described:
linesArr.push(...)).MATCH_PREVIEW, immediately below:
ā¦and it correctly usesjslines.push(eChart + " Player Stats (Live):");
lines.push(...) so it will appear in match previews.function _getHistoricalSurfaceWinRateATP(playerName) { ... }function _getHistoricalSurfaceWinRateWTA(playerName) { ... }_buildHistSurfaceCacheWTA_() is already reading 12 columns:
getRange(2, 1, lastRow - 1, 12)node --check clean).tourCode, surfaceAlias, _getHistoricalSurfaceWinRateATP/WTA are all present in the script.Hereās the updated script as a downloadable .txt: