"use strict"; // Edit one INI value without rewriting comments, unrelated keys, or line endings. const HeroIni = (() => { const split = (raw) => raw.split(/\r\n|\n|\r/); const ending = (raw) => raw.includes("\r\n") ? "\r\n" : raw.includes("\r") ? "\r" : "\n"; function parse(raw) { const lines = split(raw), sections = []; let current = null; for (let i = 0; i < lines.length; i++) { const header = /^\s*\[([^\]]+)\]\s*(?:;.*)?$/.exec(lines[i]); if (header) { if (current) current.end = i; current = { name: header[1].trim(), start: i, end: lines.length, fields: [] }; sections.push(current); continue; } const m = /^\s*([^\s=;#]+)\s*=\s*(.*)$/.exec(lines[i]); if (m && current) current.fields.push({ key: m[1], value: m[2].trim(), line: i }); } return { raw, lines, sections }; } function section(doc, name) { return doc.sections.find((s) => s.name.toLowerCase() === name.toLowerCase()); } function get(doc, name, key) { const s = section(doc, name); return s?.fields.findLast((f) => f.key.toLowerCase() === key.toLowerCase())?.value ?? ""; } function set(raw, name, key, value) { const doc = parse(raw), s = section(doc, name); if (!s) throw new Error(`Section [${name}] is missing`); const field = s.fields.findLast((f) => f.key.toLowerCase() === key.toLowerCase()); const lines = doc.lines; if (field) { const old = lines[field.line], prefix = /^\s*[^\s=;#]+\s*=\s*/.exec(old)?.[0] || `${key} = `; lines[field.line] = prefix + value; } else { lines.splice(s.end, 0, `${key} = ${value}`); } return lines.join(ending(raw)); } return { parse, section, get, set }; })(); if (typeof module !== "undefined") module.exports = HeroIni;