/************************************************************
  util
*************************************************************/
const Util = (() => {
  const NAME = 'Cosmos.lib.Util';

  class Util {

    // static
    
    static get name() {
      return NAME;
    }

    /**
     * event on selector
     * 
     * @param  {String}   selector   querySelector
     * @param  {String}   type       event type
     * @param  {Function} listener   event listener
     * @param  {Boolean}  useCapture
     * @return {number|null}
     */
    static eventOnSelector(selector, type, listener, useCapture = false) {
      let elements = document.querySelectorAll(selector);
      if (elements.length == 0) {
        return null;
      }
      for (let element of elements) {
        element.addEventListener(type, listener, useCapture);
      }
      return elements.length;
    }

    /**
     * find ancestor by selector
     * 
     * @param  {Element} element
     * @param  {String}  selector
     * @return {Element|null}
     */
    static findAncestor(element, selector) {
      do {
        if(element == document.querySelector('html')) return null;
        element = element.parentElement;
      } while(!element.matches(selector));
      return element;
    }

    /**
     * wrap elements by div.wrapper
     * @param  {String} target  querySelector
     * @param  {String} wrapper wrapper's class name
     * @return {void}
     */
    static wrap(target, wrapper) {
      var elements = document.querySelectorAll(target);
      var div = document.createElement('div');
      div.classList.add(wrapper);
      
      for (let el of elements) {
        let parent = el.parentNode;
        let sibling = el.nextSibling;

        div.appendChild(el);

        if (sibling) {
          parent.insertBefore(div, sibling);
        } else {
          parent.appendChild(div);
        }
      }
    }

    /**
     * wrap all elements inside to div.wrapper
     * @param  {String}  target  querySelector
     * @param  {String}  wrapper wrapper's class name
     * @return {void}
     */
    static wrapAll(target, wrapper) {
      var elements = document.querySelectorAll(target);
      var div = document.createElement('div');
      div.classList.add(wrapper);
      var parent = elements[0].parentNode;
      var sibling = elements[0].nextSibling;

      elements.forEach((elm) => {
        div.appendChild(elm);
      });

      if (sibling) {
        parent.insertBefore(div, sibling);
      } else {
        parent.appendChild(div);
      }
    }

    /**
     * location.search to Object.
     * 
     * @return {Object}
     */
    static locationSearchToObject() {
      let queries = window.location.search.substring(1).split('&');
      let obj = {};

      queries.forEach((value) => {
        let q = value.split('=');
        if (!q[1]) return;
        obj[decodeURIComponent(q[0])] = decodeURIComponent(q[1]);
      });

      return obj;
    }
  }

  return Util;
})();

export default Util;

@@ -2956,16 +2956,739 @@
 j;%0A    %7D
+%0A%0A    /**%0A     * returns true if 'big' contains 'small'.%0A     * %0A     * @param  %7Bmixed%7D  big%0A     * @param  %7Bmixed%7D  small%0A     * @return %7BBoolean%7D%0A     */%0A    static isContains(big, small) %7B%0A      if (typeof big !== typeof small) return false;%0A%0A      if (Array.isArray(big) && Array.isArray(small)) %7B%0A        let correct = 0;%0A        big.forEach((v) =%3E %7B%0A          if (small.includes(v)) correct++;%0A        %7D);%0A        return correct == small.length;%0A      %7D else if (typeof small === 'object' && Object(small) === small) %7B%0A        for (let p in small) %7B%0A          if (!(p in big && this.isContains(big%5Bp%5D, small%5Bp%5D))) return false;%0A        %7D%0A        return true;%0A      %7D else %7B%0A        return big === small;%0A      %7D%0A    %7D
 %0A  %7D%0A%0A  

Add static method "isContains()" in Util.js