0xa85e2099…e34asent to0xd28694b1…4215·#25,412,206·view on Etherscan
ass.index === 0) {
const bandCount = Math.max(1, Math.round(3 + pass.strength * 14));
for (let band = 0; band < bandCount; band += 1) {
const bandSeed = seed + band * 977;
const y = Math.floor(grSmoothRandom(bandSeed, time * 0.82) * rows * cell);
const bandHeight = Math.max(1, Math.floor((grSmoothRandom(bandSeed + 37, time * 0.45) * 10 + 2) * pass.strength));
if (rowY < y || rowY > y + bandHeight) continue;
offset += Math.round((grSmoothRandom(bandSeed + 73, time) - 0.5) * fullWidth * 0.16 * pass.strength);
}
} else {
const slices = pass.index === 1 ? 5 : 10;
const sliceHeight = Math.max(1, Math.ceil(rows / slices));
const slice = Math.floor(row / sliceHeight);
const sliceSeed = seed + slice * 557;
const direction = grSmoothRandom(sliceSeed, time * 0.5) * 2 - 1;
const travel = 0.025 + grSmoothRandom(sliceSeed + 89, time * 0.42) * (slices === 5 ? 0.18 : 0.26);
offset += Math.round(direction * travel * fullWidth * pass.strength);
}
}
const brokenRows = (effects.brokenRows || 0) / 100;
const misregistration = (effects.misregistration || 0) / 100;
if (brokenRows > 0 || misregistration > 0) {
const tears = Math.round(1 + brokenRows * 10 + misregistration * 5);
for (let i = 0; i < tears; i += 1) {
const active = grSmoothRandom(i * 379 + 73, frame * 0.12) < brokenRows * 0.85 + misregistration * 0.35;
if (!active) continue;
const y = Math.floor(grSmoothRandom(i * 701 + 17, frame * 0.1) * rows);
const bandHeight = Math.max(1, Math.round(1 + grSmoothRandom(i * 313 + 29, frame * 0.07) * (2 + brokenRows * 18)));
if (row < y || row > y + bandHeight) continue;
offset += Math.round((grSmoothRandom(i * 997 + 41, frame * 0.16) - 0.5) * fullWidth * (brokenRows * 0.14 + misregistration * 0.08));
}
}
return offset;
}
function svgComputeRowOffsets(frame) {
for (let row = 0; row < rows; row += 1) rowOffsets[row] = svgRowGlitchOffset(row, frame);
}
function svgClearCell(node) {
if (node._grText !== "") {
node.textContent = "";
node._grText = "";
}
node._grTone = 0;
}
function grToneAt(toneLines, column, row) {
const line = toneLines[Math.max(0, Math.min(rows - 1, row))] || "";
return toneValueMap[line[Math.max(0, Math.min(columns - 1, column))] || "0"] ?? 0;
}
function grAdaptiveCellScale(toneLines, column, row) {
const effects = grEffectSettings();
if (!effects.asciiAdaptiveSize) return 1;
const blockColumn = column - (column % 2);
const blockRow = row - (row % 2);
const a = grToneAt(toneLines, blockColumn, blockRow);
const b = grToneAt(toneLines, blockColumn + 1, blockRow);
const c = grToneAt(toneLines, blockColumn, blockRow + 1);
const d = grToneAt(toneLines, blockColumn + 1, blockRow + 1);
const maxTone = Math.max(a, b, c, d);
const minTone = Math.min(a, b, c, d);
if (maxTone > 0.68) return 1;
if (maxTone - minTone > 0.24) return 1;
return Math.max(1, Math.min(1.18, 1 + ((effects.asciiLargeScale || 2) - 1) * 0.12));
}
function grAdaptiveClearedNeighborCount(styleLines, column, row) {
let clearedNeighbors = 0;
for (let y = row - 1; y <= row + 1; y += 1) {
const line = styleLines[Math.max(0, Math.min(rows - 1, y))] || "";
for (let x = column - 1; x <= column + 1; x += 1) {
if (x === column && y === row) continue;
if ((line[Math.max(0, Math.min(columns - 1, x))] || "0") === "1") clearedNeighbors += 1;
}
}
return clearedNeighbors;
}
function grRecoveredAdaptiveDenseAnchor(styleLines, column, row, style) {
return grIsDenseHighlightStyle(style) && grAdaptiveClearedNeighborCount(styleLines, column, row) >= 2;
}
function grStoredAnchorScale(styleLines, column, row, style) {
const canBeAdaptiveAnchor = style === "2" || style === "3" || grIsDenseHighlightStyle(style);
if (!canBeAdaptiveAnchor) return 1;
const clearedNeighbors = grAdaptiveClearedNeighborCount(styleLines, column, row);
if (style !== "2" && clearedNeighbors < 2) return 1;
const tuning = SIGNAL_RITUAL_ENGINE.visualRenderer.rendererTuning || {};
return Math.min(3, Math.max(1.35, (grEffectSettings().asciiLargeScale || 2) * (tuning.largeAnchorScaleMultiplier ?? 0.95)));
}
function grIsAdaptiveAnchorStyle(style) {
return style === "2" || style === "3" || style === "4" || grIsDenseHighlightStyle(style) || grIsEdgeStyle(style);
}
function grAdaptiveBlockSpec(styleLines, column, row, style) {
const effects = grEffectSettings();
if (!effects.asciiAdaptiveSize || !grIsAdaptiveAnchorStyle(style)) return null;
const maxBlockSize = Math.max(2, Math.min(4, Math.round(effects.asciiLargeScale || 2)));
for (let blockSize = maxBlockSize; blockSize >= 2; blockSize -= 1) {
const startColumn = column - Math.floor(blockSize / 2);
const startRow = row - Math.floor(blockSize / 2);
const endColumn = startColumn + blockSize;
const endRow = startRow + blockSize;
if (startColumn < 0 || startRow < 0 || endColumn > columns || endRow > rows) continue;
let helperCells = 0;
let valid = true;
for (let y = startRow; y < endRow && valid; y += 1) {
const line = styleLines[y] || "";
for (let x = startColumn; x < endColumn; x += 1) {
if (x === column && y === row) continue;
if ((line[x] || "0") !== "1") {
valid = false;
break;
}
helperCells += 1;
}
}
if (!valid || helperCells === 0) continue;
const blockCenterX = (startColumn + blockSize / 2) * cell;
const blockCenterY = (startRow + blockSize / 2) * cell;
const anchorCenterX = (column + 0.5) * cell;
const anchorCenterY = (row + 0.5) * cell;
return {
scale: blockSize,
offsetX: blockCenterX - anchorCenterX,
offsetY: blockCenterY - anchorCenterY,
recoveredDenseAnchor: grIsDenseHighlightStyle(style),
};
}
return null;
}
function grAdaptiveAnchorOffset(styleLines, column, row, style) {
const canBeAdaptiveAnchor = style === "2" || style === "3" || grIsDenseHighlightStyle(style);
if (!canBeAdaptiveAnchor) return [0, 0];
let minX = 0;
let maxX = 0;
let minY = 0;
let maxY = 0;
let hasClear = false;
for (let y = row - 1; y <= row + 1; y += 1) {
const line = styleLines[Math.max(0, Math.min(rows - 1, y))] || "";
for (let x = column - 1; x <= column + 1; x += 1) {
if ((line[Math.max(0, Math.min(columns - 1, x))] || "0") !== "1") continue;
const dx = x - column;
const dy = y - row;
minX = Math.min(minX, dx);
maxX = Math.max(maxX, dx);
minY = Math.min(minY, dy);
maxY = Math.max(maxY, dy);
hasClear = true;
}
}
if (!hasClear) return [0, 0];
return [((minX + maxX) / 2) * cell, ((minY + maxY) / 2) * cell];
}
function grShouldGlowCell(tone, style, highlightFill, column, row, frame) {
if (!RENDER_GLOW_ENABLED) return false;
const isLargeAnchor = style === "2";
const isHighlightMark = style === "3";
const isHeavyInk = style === "4" || grIsDenseHighlightStyle(style);
const highlightThreshold = (grEffectSettings().asciiHighlightThreshold || 65) / 100;
const glowToneFloor = Math.max(0.42, highlightThreshold - 0.24);
const eligible = isLargeAnchor
|| isHighlightMark
|| isHeavyInk
|| highlightFill > 0.08
|| tone >= glowToneFloor;
if (!eligible) return false;
const strong = Math.max(tone, highlightFill, isLargeAnchor || isHighlightMark || isHeavyInk ? 0.72 : 0);
const density = Math.max(0.28, Math.min(0.62, 0.24 + strong * 0.38));
return grSeeded(column * 1201 + row * 379 + frame * 97 + 17) < density;
}
function svgSetCell(node, glyph, tone, style, column, row, frame, adaptiveScale = 1, motionFrame = frame, recoveredAdaptiveDenseAnchor = false, adaptiveSpec = null) {
const isLargeAnchor = style === "2";
const isHighlightMark = style === "3";
const isHeavyInk = style === "4";
const isBackgroundStyle = style === "5";
const isEdge = grIsEdgeStyle(style);
const isStoredDenseStyle = grIsDenseHighlightStyle(style);
const isRecoveredLargeHighlight = recoveredAdaptiveDenseAnchor;
const useRecoveredDenseAnchor = isRecoveredLargeHighlight && isStoredDenseStyle;
const glowStyle = isStoredDenseStyle && !useRecoveredDenseAnchor ? "0" : style;
const isAdaptiveClear = style === "1";
if (isAdaptiveClear) {
svgClearCell(node);
return false;
}
const isStoredSpace = glyph === " " || isBackgroundStyle;
if (isStoredSpace) {
const chars = SIGNAL_RITUAL_ENGINE.glyphs;
const backgroundIndex = Math.max(1, Math.min(chars.length - 1, Math.floor(grSeeded(column * 181 + row * 557) * Math.min(4, chars.length - 1))));
glyph = chars[backgroundIndex] || ".";
}
if (!isEdge) glyph = grMotionGlyph(glyph, column, row, frame, tone);
const isDenseHighlight = !isStoredSpace && (
useRecoveredDenseAnchor
|| (!isStoredDenseStyle && grShouldUseDenseHighlightGlyph(tone, style))
);
if (isDenseHighlight) {
glyph = grDenseHighlightGlyph(tone, style, column, row, frame);
}
if (glyph === " " && tone < 0.02) {
svgClearCell(node);
return false;
}
const highlightFill = Math.max(grHighlightFill(tone), isHeavyInk ? 0.35 : 0);
const fill = highlightFill > 0 || isHighlightMark || isHeavyInk || isDenseHighlight
? grRgbString(grHighlightInkColor(tone, highlightFill, isHighlightMark, isHeavyInk, isDenseHighlight))
: svgToneFill(tone);
const usesAdaptiveBlock = Boolean(adaptiveSpec);
const largeScale = usesAdaptiveBlock
? adaptiveSpec.scale
: grHighlightCellScale(tone, style, column, row, frame, isRecoveredLargeHighlight);
const sizeScale = grSizeGlitchScale(column, row, frame) * largeScale;
const tuning = SIGNAL_RITUAL_ENGINE.visualRenderer.rendererTuning || {};
const bgAlpha = Math.max(
tuning.backgroundAlphaMin ?? 0.02,
Math.min(tuning.backgroundAlphaMax ?? 0.12, (tuning.backgroundAlphaBase ?? 0.035) + tone * (tuning.backgroundAlphaTone ?? 0.18)),
);
const alpha = isStoredSpace ? bgAlpha : Math.max(0.82, Math.min(1, 0.86 + tone * 0.32));
const text = isHighlightMark || grShouldHighlightBlock(tone) ? "#" : glyph;
const opacity = alpha.toFixed(3);
const fontWeight = String(isStoredSpace ? 700 : isEdge ? 800 : grHighlightWeight(tone, style));
const glyphScale = tuning.glyphScale ?? 1.25;
const usesFixedHighlightSize = isLargeAnchor || isHighlightMark || isHeavyInk || isDenseHighlight || isRecoveredLargeHighlight || usesAdaptiveBlock;
const rawFontSize = usesFixedHighlightSize
? cell * (glyphScale + highlightFill * (tuning.highlightGlyphBoost ?? 0.38)) * sizeScale
: cell * glyphScale * sizeScale;
const maxFontSize = usesFixedHighlightSize
? rawFontSize
: cell * (adaptiveScale > 1 ? Math.min(1.35, adaptiveScale * 1.12) : 1.2);
const fontSize = String(Math.round(Math.min(rawFontSize, maxFontSize)));
const rowOffset = rowOffsets[row] || 0;
const centeredOffset = adaptiveSpec ? [adaptiveSpec.offsetX, adaptiveSpec.offsetY] : [0, 0];
const proceduralOffset = grProceduralGlyphOffset(column, row, motionFrame, tone);
const tx = rowOffset + centeredOffset[0] + proceduralOffset[0];
const ty = centeredOffset[1] + proceduralOffset[1];
const transform = tx || ty ? "translate(" + tx + " " + ty + ")" : "";
node._grColumn = column;
node._grRow = row;
node._grTone = tone;
node._grBaseRowOffset = rowOffset;
node._grCenteredOffsetX = centeredOffset[0];
node._grCenteredOffsetY = centeredOffset[1];
if (node._grText !== text) {
node.textContent = text;
node._grText = text;
}
if (node._grFill !== fill) {
node.setAttribute("fill", fill);
node._grFill = fill;
}
if (node._grOpacity !== opacity) {
node.setAttribute("opacity", opacity);
node._grOpacity = opacity;
}
if (node._grFontSize !== fontSize) {
node.setAttribute("font-size", fontSize);
node._grFontSize = fontSize;
}
if (node._grFontWeight !== fontWeight) {
node.setAttribute("font-weight", fontWeigh