const defaults = {
  tName: 't',
  i18nName: 'i18n',
  handleName: 'localize',
  selectorAttr: 'data-i18n',
  targetAttr: 'data-i18n-target',
  optionsAttr: 'data-i18n-options',
  useOptionsAttr: false,
  parseDefaultValueFromContent: true
};

function init(i18next, $, options = {}) {

  options = { ...options, ...defaults };

  function parse(ele, key, opts) {
    if (key.length === 0) return;

    let attr = 'text';

    if (key.indexOf('[') === 0) {
      let parts = key.split(']');
      key = parts[1];
      attr = parts[0].substr(1, parts[0].length-1);
    }

    if (key.indexOf(';') === key.length-1) {
      key = key.substr(0, key.length-2);
    }

    function extendDefault(o, val) {
      if (!options.parseDefaultValueFromContent) return o;
      return { ...o, ...{ defaultValue: val } };
    }

    if (attr === 'html') {
      ele.html(i18next.t(key, extendDefault(opts, ele.html())));
    } else if (attr === 'text') {
      ele.text(i18next.t(key, extendDefault(opts, ele.text())));
    } else if (attr === 'prepend') {
      ele.prepend(i18next.t(key, extendDefault(opts, ele.html())));
    } else if (attr === 'append') {
      ele.append(i18next.t(key, extendDefault(opts, ele.html())));
    } else if (attr.indexOf('data-') === 0) {
      let dataAttr = attr.substr(('data-').length);
      let translated = i18next.t(key, extendDefault(opts, ele.data(dataAttr)));

      // we change into the data cache
      ele.data(dataAttr, translated);
      // we change into the dom
      ele.attr(attr, translated);
    } else {
      ele.attr(attr, i18next.t(key, extendDefault(opts, ele.attr(attr))));
    }
  }

  function localize(ele, opts) {
    let key = ele.attr(options.selectorAttr);
    if (!key && typeof key !== 'undefined' && key !== false) key = ele.text() || ele.val();
    if (!key) return;

    let target = ele,
      targetSelector = ele.data(options.targetAttr);

    if (targetSelector) target = ele.find(targetSelector) || ele;

    if (!opts && options.useOptionsAttr === true) options = ele.data(options.optionsAttr);

    opts = opts || {};

    if (key.indexOf(';') >= 0) {
      var keys = key.split(';');

      $.each(keys, function(m, k) {
        if (k !== '') parse(target, k, opts);
      });
    } else {
      parse(target, key, opts);
    }

    if (options.useOptionsAttr === true) {
      let clone = {};
      clone = { clone, ...options };

      delete clone.lng;
      ele.data(options.optionsAttr, clone);
    }
  }

  function handle(opts) {
    return this.each(function() {
      // localize element itself
      localize($(this), opts);

      // localize children
      var elements =  $(this).find('[' + options.selectorAttr + ']');
      elements.each(function() {
        localize($(this), opts);
      });
    });
  };

  // $.t $.i18n shortcut
  $[options.tName] = i18next.t;
  $[options.i18nName] = i18next;

  // selector function $(mySelector).localize(opts);
  $.fn[options.handleName] = handle;
}

export default {
  init: init
};

@@ -301,27 +301,27 @@
  ...
-options, ...default
+defaults, ...option
 s %7D;

Fix default options overriding