function parseLite(code) {
    const trimmed = code.trim();
    const onMatch = trimmed.match(/^on\s+(\w+)(?:\s+from\s+([^\s]+))?\s+(.+)$/i);
    if (onMatch) {
        return {
            event: onMatch[1],
            filter: onMatch[2],
            commands: parseCommands(onMatch[3]),
        };
    }
    const everyMatch = trimmed.match(/^every\s+(\d+)(ms|s)?\s+(.+)$/i);
    if (everyMatch) {
        const ms = everyMatch[2] === 's' ? parseInt(everyMatch[1]) * 1000 : parseInt(everyMatch[1]);
        return {
            event: `interval:${ms}`,
            commands: parseCommands(everyMatch[3]),
        };
    }
    const initMatch = trimmed.match(/^init\s+(.+)$/i);
    if (initMatch) {
        return {
            event: 'init',
            commands: parseCommands(initMatch[1]),
        };
    }
    return parseCommands(trimmed);
}
function parseCommands(code) {
    const parts = code.split(/\s+(?:then|and)\s+/i);
    return parts.map(parseCommand).filter(Boolean);
}
function parseCommand(code) {
    const trimmed = code.trim();
    if (!trimmed)
        return null;
    let match = trimmed.match(/^toggle\s+(\.\w+|\w+)(?:\s+on\s+(.+))?$/i);
    if (match) {
        return { name: 'toggle', args: [match[1]], target: match[2] };
    }
    match = trimmed.match(/^add\s+(\.\w+|\w+)(?:\s+to\s+(.+))?$/i);
    if (match) {
        return { name: 'add', args: [match[1]], target: match[2] };
    }
    match = trimmed.match(/^remove\s+(\.\w+)(?:\s+from\s+(.+))?$/i);
    if (match) {
        return { name: 'remove', args: [match[1]], target: match[2] };
    }
    match = trimmed.match(/^remove\s+(.+)$/i);
    if (match) {
        return { name: 'remove', args: [], target: match[1] };
    }
    match = trimmed.match(/^put\s+(?:"([^"]+)"|'([^']+)'|(\S+))\s+(into|before|after)\s+(.+)$/i);
    if (match) {
        const content = match[1] || match[2] || match[3];
        return { name: 'put', args: [content], modifier: match[4], target: match[5] };
    }
    match = trimmed.match(/^set\s+(.+?)\s+to\s+(.+)$/i);
    if (match) {
        return { name: 'set', args: [match[1], match[2]] };
    }
    match = trimmed.match(/^log\s+(.+)$/i);
    if (match) {
        return { name: 'log', args: [match[1]] };
    }
    match = trimmed.match(/^send\s+(\w+)(?:\s+to\s+(.+))?$/i);
    if (match) {
        return { name: 'send', args: [match[1]], target: match[2] };
    }
    match = trimmed.match(/^wait\s+(\d+)(ms|s)?$/i);
    if (match) {
        const ms = match[2] === 's' ? parseInt(match[1]) * 1000 : parseInt(match[1]);
        return { name: 'wait', args: [ms.toString()] };
    }
    match = trimmed.match(/^(if|unless)\s+(.+?)\s+(toggle|add|remove|put|set|log|send|wait)\s+(.+)$/i);
    if (match) {
        const innerCmd = parseCommand(`${match[3]} ${match[4]}`);
        if (innerCmd) {
            innerCmd.modifier = match[1].toLowerCase();
            innerCmd.args.unshift(match[2]);
            return innerCmd;
        }
    }
    match = trimmed.match(/^(show|hide)(?:\s+(.+))?$/i);
    if (match) {
        const target = match[2];
        return match[1].toLowerCase() === 'show'
            ? { name: 'remove', args: ['.hidden'], target }
            : { name: 'add', args: ['.hidden'], target };
    }
    const parts = trimmed.split(/\s+/);
    if (parts.length > 0) {
        return { name: parts[0], args: parts.slice(1) };
    }
    return null;
}
function resolveTarget(target, me) {
    if (!target)
        return me;
    const t = target.trim();
    if (t === 'me')
        return me;
    if (t === 'body')
        return document.body;
    if (t.startsWith('#') || t.startsWith('.') || t.startsWith('[')) {
        const elements = document.querySelectorAll(t);
        return elements.length === 1 ? elements[0] : Array.from(elements);
    }
    if (/^\w+$/.test(t) && document.getElementById(t)) {
        return document.getElementById(t);
    }
    return me;
}
function getClassName(arg) {
    return arg.startsWith('.') ? arg.slice(1) : arg;
}
async function executeCommand(cmd, me, locals) {
    const target = resolveTarget(cmd.target, me);
    const elements = Array.isArray(target) ? target : target ? [target] : [me];
    switch (cmd.name) {
        case 'toggle': {
            const className = getClassName(cmd.args[0]);
            for (const el of elements) {
                el.classList.toggle(className);
            }
            return elements.length === 1 ? elements[0] : elements;
        }
        case 'add': {
            const className = getClassName(cmd.args[0]);
            for (const el of elements) {
                el.classList.add(className);
            }
            return elements.length === 1 ? elements[0] : elements;
        }
        case 'remove': {
            if (cmd.args[0]) {
                const className = getClassName(cmd.args[0]);
                for (const el of elements) {
                    el.classList.remove(className);
                }
            }
            else {
                for (const el of elements) {
                    el.remove();
                }
            }
            return null;
        }
        case 'put': {
            const content = evaluateValue(cmd.args[0], me, locals);
            for (const el of elements) {
                switch (cmd.modifier?.toLowerCase()) {
                    case 'into':
                        el.innerHTML = String(content);
                        break;
                    case 'before':
                        el.insertAdjacentHTML('beforebegin', String(content));
                        break;
                    case 'after':
                        el.insertAdjacentHTML('afterend', String(content));
                        break;
                    default:
                        el.innerHTML = String(content);
                }
            }
            return elements.length === 1 ? elements[0] : elements;
        }
        case 'set': {
            const [targetExpr, valueExpr] = cmd.args;
            const value = evaluateValue(valueExpr, me, locals);
            if (targetExpr.startsWith(':')) {
                locals.set(targetExpr.slice(1), value);
                return value;
            }
            const propMatch = targetExpr.match(/^(.+?)(?:'s|\.)\s*(\w+)$/);
            if (propMatch) {
                const obj = resolveTarget(propMatch[1], me);
                if (obj) {
                    obj[propMatch[2]] = value;
                    return obj;
                }
            }
            return value;
        }
        case 'log': {
            const value = evaluateValue(cmd.args.join(' '), me, locals);
            console.log(value);
            return value;
        }
        case 'send': {
            const eventName = cmd.args[0];
            const event = new CustomEvent(eventName, { bubbles: true });
            for (const el of elements) {
                el.dispatchEvent(event);
            }
            return event;
        }
        case 'wait': {
            const ms = parseInt(cmd.args[0]) || 0;
            await new Promise(resolve => setTimeout(resolve, ms));
            return ms;
        }
        default:
            console.warn(`Unknown command: ${cmd.name}`);
            return null;
    }
}
function evaluateValue(expr, me, locals) {
    if (!expr)
        return undefined;
    const e = expr.trim();
    if ((e.startsWith('"') && e.endsWith('"')) || (e.startsWith("'") && e.endsWith("'"))) {
        return e.slice(1, -1);
    }
    if (/^-?\d+(\.\d+)?$/.test(e)) {
        return parseFloat(e);
    }
    if (e === 'true')
        return true;
    if (e === 'false')
        return false;
    if (e === 'null')
        return null;
    if (e.startsWith(':')) {
        return locals.get(e.slice(1));
    }
    if (e === 'me')
        return me;
    if (e === 'my')
        return me;
    if (e === 'body')
        return document.body;
    const propMatch = e.match(/^(me|my)\.(\w+)$/);
    if (propMatch) {
        return me[propMatch[2]];
    }
    return e;
}
async function executeParsed(parsed, me, locals = new Map()) {
    if (Array.isArray(parsed)) {
        let result;
        for (const cmd of parsed) {
            if (cmd.modifier === 'if' || cmd.modifier === 'unless') {
                const condition = evaluateCondition(cmd.args[0], me, locals);
                const shouldRun = cmd.modifier === 'if' ? condition : !condition;
                if (!shouldRun)
                    continue;
                cmd.args.shift();
            }
            result = await executeCommand(cmd, me, locals);
        }
        return result;
    }
    const handler = parsed;
    const targetEl = handler.filter ? document.querySelector(handler.filter) : me;
    const eventName = handler.event;
    if (eventName.startsWith('interval:')) {
        const ms = parseInt(eventName.split(':')[1]);
        setInterval(async () => {
            const handlerLocals = new Map(locals);
            for (const cmd of handler.commands) {
                await executeCommand(cmd, me, handlerLocals);
            }
        }, ms);
        return me;
    }
    if (eventName === 'init') {
        const handlerLocals = new Map(locals);
        for (const cmd of handler.commands) {
            await executeCommand(cmd, me, handlerLocals);
        }
        return me;
    }
    if (targetEl) {
        targetEl.addEventListener(eventName, async (event) => {
            const handlerLocals = new Map(locals);
            handlerLocals.set('event', event);
            for (const cmd of handler.commands) {
                await executeCommand(cmd, me, handlerLocals);
            }
        });
    }
    return me;
}
function evaluateCondition(expr, me, locals) {
    const e = expr.trim();
    const hasMatch = e.match(/^(me|my)\s+has\s+\.(\w+)$/i);
    if (hasMatch) {
        return me.classList.contains(hasMatch[2]);
    }
    const propMatch = e.match(/^(me|my)\.(\w+)$/i);
    if (propMatch) {
        return Boolean(me[propMatch[2]]);
    }
    if (e.startsWith(':')) {
        return Boolean(locals.get(e.slice(1)));
    }
    const value = evaluateValue(e, me, locals);
    return Boolean(value);
}
function processElements(root = document) {
    const elements = root.querySelectorAll('[_]');
    for (const el of elements) {
        const code = el.getAttribute('_');
        if (code) {
            try {
                const parsed = parseLite(code);
                executeParsed(parsed, el);
            }
            catch (err) {
                console.error('HyperFixi Lite error:', err, 'Code:', code);
            }
        }
    }
}
const api = {
    version: '1.0.0-lite',
    parse: parseLite,
    execute: async (code, element) => {
        const me = element || document.body;
        const parsed = parseLite(code);
        return executeParsed(parsed, me);
    },
    init: processElements,
    process: processElements,
    commands: ['add', 'remove', 'toggle', 'put', 'set', 'log', 'send', 'wait'],
};
if (typeof window !== 'undefined') {
    window.hyperfixi = api;
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => processElements());
    }
    else {
        processElements();
    }
}

class RegexParserImpl {
    constructor() {
        this.name = 'regex';
        this.supportedCommands = [
            'add',
            'remove',
            'toggle',
            'put',
            'set',
            'log',
            'send',
            'wait',
        ];
    }
    parse(code) {
        const result = api.parse(code);
        if ('event' in result) {
            return {
                type: 'eventHandler',
                event: result.event,
                filter: result.filter,
                commands: result.commands.map(cmd => this.convertCommand(cmd)),
            };
        }
        if (Array.isArray(result)) {
            if (result.length === 1) {
                return this.convertCommand(result[0]);
            }
            return {
                type: 'sequence',
                commands: result.map(cmd => this.convertCommand(cmd)),
            };
        }
        return this.convertCommand(result);
    }
    convertCommand(cmd) {
        return {
            type: 'command',
            name: cmd.name,
            args: cmd.args.map(arg => ({
                type: 'literal',
                value: arg,
            })),
            ...(cmd.target && {
                target: {
                    type: 'selector',
                    value: cmd.target,
                },
            }),
        };
    }
    parseCommands(code) {
        const result = this.parse(code);
        if (result.type === 'sequence' && 'commands' in result) {
            return result.commands;
        }
        return [result];
    }
    supports(syntax) {
        const firstWord = syntax.trim().split(/\s+/)[0]?.toLowerCase();
        if (firstWord === 'on' || firstWord === 'every' || firstWord === 'init') {
            return true;
        }
        return this.supportedCommands.includes(firstWord);
    }
}
const regexParser = new RegexParserImpl();
function createRegexParser() {
    return new RegexParserImpl();
}

export { createRegexParser, regexParser };
//# sourceMappingURL=regex-parser.mjs.map
