<commit_before>import { getDirection } from '../intl/locale';

import { keysFromContext, valueFromContext, entityFromContext }
  from '../lib/format';

import { initMutationObserver, translateRoots, observe, disconnect }
  from './observer';
import { setAttributes, getAttributes, translateFragment }
  from './dom';

const properties = new WeakMap();
export const contexts = new WeakMap();

export class Localization {
  constructor(doc, requestBundles, createContext) {
    this.interactive = requestBundles();
    this.createContext = createContext;
    this.ready = this.interactive
      .then(bundles => fetchFirstBundle(bundles, createContext))
      .then(bundles => translateDocument(this, bundles));

    properties.set(this, { doc, requestBundles, ready: false });
    initMutationObserver(this);
    this.observeRoot(doc.documentElement);
  }

  requestLanguages(requestedLangs) {
    return this.ready = this.interactive.then(
      bundles => changeLanguages(this, bundles, requestedLangs)
    );
  }

  handleEvent() {
    return this.requestLanguages();
  }

  formatEntities(...keys) {
    // XXX add async fallback
    return this.interactive.then(
      ([bundle]) => keysFromContext(
        contexts.get(bundle), keys, entityFromContext
      )
    );
  }

  formatValues(...keys) {
    return this.interactive.then(
      ([bundle]) => keysFromContext(
        contexts.get(bundle), keys, valueFromContext
      )
    );
  }

  formatValue(id, args) {
    return this.formatValues([id, args]).then(
      ([val]) => val
    );
  }

  translateFragment(frag) {
    return translateFragment(this, frag);
  }

  observeRoot(root) {
    observe(this, root);
  }

  disconnectRoot(root) {
    disconnect(this, root);
  }
}

Localization.prototype.setAttributes = setAttributes;
Localization.prototype.getAttributes = getAttributes;

function createContextFromBundle(bundle, createContext) {
  return bundle.fetch().then(resources => {
    const ctx = createContext(bundle.lang);
    resources.forEach(res => ctx.addMessages(res));
    contexts.set(bundle, ctx);
    return ctx;
  });
}

function fetchFirstBundle(bundles, createContext) {
  const [bundle] = bundles;
  return createContextFromBundle(bundle, createContext).then(
    () => bundles
  );
}<commit_msg>Don't try to parse messages from missing resources<commit_after>import { getDirection } from '../intl/locale';

import { keysFromContext, valueFromContext, entityFromContext }
  from '../lib/format';

import { initMutationObserver, translateRoots, observe, disconnect }
  from './observer';
import { setAttributes, getAttributes, translateFragment }
  from './dom';

const properties = new WeakMap();
export const contexts = new WeakMap();

export class Localization {
  constructor(doc, requestBundles, createContext) {
    this.interactive = requestBundles();
    this.createContext = createContext;
    this.ready = this.interactive
      .then(bundles => fetchFirstBundle(bundles, createContext))
      .then(bundles => translateDocument(this, bundles));

    properties.set(this, { doc, requestBundles, ready: false });
    initMutationObserver(this);
    this.observeRoot(doc.documentElement);
  }

  requestLanguages(requestedLangs) {
    return this.ready = this.interactive.then(
      bundles => changeLanguages(this, bundles, requestedLangs)
    );
  }

  handleEvent() {
    return this.requestLanguages();
  }

  formatEntities(...keys) {
    // XXX add async fallback
    return this.interactive.then(
      ([bundle]) => keysFromContext(
        contexts.get(bundle), keys, entityFromContext
      )
    );
  }

  formatValues(...keys) {
    return this.interactive.then(
      ([bundle]) => keysFromContext(
        contexts.get(bundle), keys, valueFromContext
      )
    );
  }

  formatValue(id, args) {
    return this.formatValues([id, args]).then(
      ([val]) => val
    );
  }

  translateFragment(frag) {
    return translateFragment(this, frag);
  }

  observeRoot(root) {
    observe(this, root);
  }

  disconnectRoot(root) {
    disconnect(this, root);
  }
}

Localization.prototype.setAttributes = setAttributes;
Localization.prototype.getAttributes = getAttributes;

function createContextFromBundle(bundle, createContext) {
  return bundle.fetch().then(resources => {
    const ctx = createContext(bundle.lang);
    resources
      .filter(res => !(res instanceof Error))
      .forEach(res => ctx.addMessages(res));
    contexts.set(bundle, ctx);
    return ctx;
  });
}

function fetchFirstBundle(bundles, createContext) {
  const [bundle] = bundles;
  return createContextFromBundle(bundle, createContext).then(
    () => bundles
  );
}
{'fraction_non_alphanumeric': 0.12655779974215728, 'fraction_numerical': 0.0, 'mean_word_length': 3.7548518896833505, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5483847', 'n_tokens_mistral': 1388, 'n_tokens_neox': 1350, 'n_words': 278}