// The webpack loader converts the emoji files in
// http://github.com/buildkite/emojis to an indexed version for use in the
// browser.
//
// The exported hash from this loader looks like this:
//
// {
//   host: "http://assets.buildkite.com/emojis",
//   emoji: [ { name: "smiley", image: "img-apple-64/1f603.png", unicode: "😃" } ],
//   index: {
//     "😃": 0,
//     ":smiley:": 0,
//     ":smiley::skin-tone-4:": 0
//   }
// }
//
// Emoji unicode values, names and aliases are all indexed.

function convertToUnicode(code) {
  if (!code || !code.length) {
    return null;
  }

  var points = code.split("-").map((point) => `0x${point}`);

  return String.fromCodePoint.apply(String, points);
}

module.exports = function(source) {
  // Mark this loader as being cacheable
  this.cacheable && this.cacheable();

  // Get the emoji host and throw and error if it's missing
  var host = process.env.EMOJI_HOST;
  if (!host) {
    this.emitError("ERROR: No EMOJI_HOST set, can't load emoji");
    throw new Error("Failed to load emoji");
  }

  // Parse the JSON source
  source = typeof source === "string" ? JSON.parse(source) : source;

  // Normalize the host (should always end with a "/")
  if (host.slice(-1) !== "/") {
    host = host + "/";
  }

  // Index the emoji
  var emojiList = [];
  var emojiIndex = {};

  source.forEach(function(emoji) {
    var item = { name: emoji["name"], image: emoji["image"] };

    emojiList.push(item);
    var itemIndex = emojiList.indexOf(item);

    var emojiUnicode = convertToUnicode(emoji["unicode"]);

    if (emojiUnicode) {
      item.unicode = emojiUnicode;
      emojiIndex[emojiUnicode] = itemIndex;
    }

    emojiIndex[`:${emoji["name"]}:`] = itemIndex;

    emoji["aliases"].forEach(function(alias) {
      emojiIndex[`:${alias}:`] = itemIndex;
    });

    var modifiers = emoji["modifiers"];
    if (modifiers && modifiers.length > 0) {
      modifiers.forEach(function(modifier) {
        var modified = { name: emoji["name"], image: modifier["image"] };

        emojiList.push(modified);
        var modifiedIndex = emojiList.indexOf(modified);

        var modifierUnicode = convertToUnicode(modifier["unicode"]);

        if (modifierUnicode) {
          modified.unicode = modifierUnicode;
          emojiIndex[modifierUnicode] = modifiedIndex;
        }

        emojiIndex[`:${emoji["name"]}::${modifier["name"]}:`] = modifiedIndex;

        emoji["aliases"].forEach(function(alias) {
          emojiIndex[`:${alias}::${modifier["name"]}:`] = modifiedIndex;
        });
      });
    }
  });

  var emojiData = { emoji: emojiList, index: emojiIndex, host: host };

  // Store the newly sorted emoji
  this.value = [emojiData];

  // Re-export the emoji as native code
  return "module.exports = " + JSON.stringify(emojiData, undefined, "\t") + ";";
};

@@ -1364,24 +1364,30 @@
 var item = %7B
+%0A     
  name: emoji
@@ -1398,31 +1398,12 @@
 me%22%5D
-, image: emoji%5B%22image%22%5D
+%0A   
  %7D;%0A
@@ -1602,46 +1602,50 @@
     
-  emojiIndex%5BemojiUnicode%5D = itemIndex
+%7D else %7B%0A      item.image = emoji%5B%22image%22%5D
 ;%0A  
@@ -1954,16 +1954,26 @@
 fied = %7B
+%0A         
  name: e
@@ -1988,34 +1988,16 @@
 me%22%5D
-, image: modifier%5B%22image%22%5D
+%0A       
  %7D;%0A
@@ -2248,53 +2248,61 @@
     
-  emojiIndex%5BmodifierUnicode%5D = modifiedIndex
+%7D else %7B%0A          modified.image = modifier%5B%22image%22%5D
 ;%0A  

Optimise emoji data webpack loader