/* * Copyright (C) 2026 Mateusz GruszczyƄski @linuxiarz.pl * Source-Available Code / Dual-Licensed. * * Free for non-commercial and evaluation use under terms of BSL/GPLv3. * Commercial or production use requires a valid paid license. * See LICENSE file in repository root for details. */ const LINE_HASH = /^#L([1-9]\d*)$/i; export function lineFromHash(hash, lineCount = Number.POSITIVE_INFINITY) { const match = LINE_HASH.exec(String(hash || "")); if (!match) return null; const line = Number(match[1]); if (!Number.isSafeInteger(line) || line > lineCount) return null; return line; } export function lineStartOffset(text, line) { const target = Number(line); if (!Number.isSafeInteger(target) || target < 1) return null; if (target === 1) return 0; let currentLine = 1; for (let index = 0; index < text.length; index += 1) { if (text.charCodeAt(index) !== 10) continue; currentLine += 1; if (currentLine === target) return index + 1; } return null; } export function lineLink(href, line) { const target = Number(line); if (!Number.isSafeInteger(target) || target < 1) throw new TypeError("Invalid line number"); const url = new URL(href); url.hash = `L${target}`; return url.href; }