function $(selector, el = document) {
    return el.querySelector(selector);
}

function $$(selector, el = document) {
    return [].slice.call(el.querySelectorAll(selector));
}

function replace(el_old, el_new) {
    el_old.parentNode.replaceChild(el_new, el_old);
    return el_new;
}

function component(name, init, opts = {}) {
    function parse_conf(el) {
        const default_conf = {};

        try {
            const conf = JSON.parse(el.getAttribute("data-component-conf"));
            return conf || default_conf;
        } catch(e) {
            return default_conf;
        }
    }
    
    opts = opts instanceof HTMLElement ? { root: opts } : opts;

    return $$(`[data-component~="${name}"]`, opts.root || document)
        .filter((el) => !el.hasAttribute("data-component-ready"))
        .map((el, index) => {
            const def = el.getAttribute("data-component").split(" ");
            const conf = Object.assign({}, init.DEFAULTS || {}, opts.conf || {}, parse_conf(el));

            const options = {
                index, conf,
                is_type(type) {
                    return def.indexOf(`${name}-${type}`) !== -1;
                }
            };

            const component = init(el, options);
            el.setAttribute("data-component-ready", "");
            return component;
        });
}

export { $, $$, component, replace };

@@ -1,16 +1,85 @@
+function to_array(iterable) %7B%0A    return %5B%5D.slice.call(iterable);%0A%7D%0A%0A
 function $(selec
@@ -92,32 +92,32 @@
 l = document) %7B%0A
-
     return el.qu
@@ -192,29 +192,24 @@
  return 
-%5B%5D.slice.call
+to_array
 (el.quer
@@ -341,24 +341,1019 @@
  el_new;%0A%7D%0A%0A
+function index(el, parent = null) %7B%0A    return to_array((parent %7C%7C el.parentNode).childNodes).indexOf(el);%0A%7D%0A%0Afunction remove(el) %7B%0A    el.parentNode && el.parentNode.removeChild(el);%0A    return el;%0A%7D%0A%0Afunction each(els, action, ...args) %7B%0A    return els.map((el) =%3E %7B%0A        return action.apply(null, %5B%5D.concat(el, args));%0A    %7D);%0A%7D%0A%0Afunction add_class(el, clazz) %7B%0A    el.classList.add(clazz);%0A    return el;%0A%7D%0A%0Afunction toggle_class(el, clazz, force = false) %7B%0A    el.classList.toggle(clazz, force);%0A    return el;%0A%7D%0A%0Afunction remove_class(el, clazz) %7B%0A    el.classList.remove(clazz);%0A    return el;%0A%7D%0A%0Afunction get_attr(el, name, _default = void 0) %7B%0A    return el && el.hasAttribute(name) ? el.getAttribute(name) : _default;%0A%7D%0A%0Afunction set_attr(el, name, value, append = false) %7B%0A    const attr_value = append ? get_attr(el, name, %22%22) + %22 %22 + value : value;%0A    el.setAttribute(name, attr_value);%0A    return el;%0A%7D%0A%0Afunction has_attr(el, name) %7B%0A    return el && el.hasAttribute(name);%0A%7D%0A%0A
 function com
@@ -2407,15 +2407,128 @@
 rt %7B
+%0A   
  $, $$,
+%0A    replace, index, remove,%0A    get_attr, has_attr, set_attr,%0A    add_class, remove_class, toggle_class,%0A   
  com
@@ -2539,15 +2539,13 @@
 nt, 
-replace 
+each,%0A
 %7D;%0A

add new dom utility functions