{"version":3,"file":"index.cjs","names":["emojiPattern","emojiJsonLocal"],"sources":["../../../common/emoji/index.js"],"sourcesContent":["import { emojiPattern } from 'regex-combined-emojis';\nimport emojiJsonLocal from 'emoji-toolkit/emoji_strategy.json' with { type: 'json' };\n\nexport const emojiRegex = new RegExp(emojiPattern, 'g');\nexport const emojiVersion = '9.0';\nexport const defaultEmojiAssetUrl = 'https://cdn.jsdelivr.net/joypixels/assets/' + emojiVersion + '/png/unicode/32/';\nexport let customEmojiAssetUrl = null;\n\n// Used for emoji 16px and smaller\nexport let emojiImageUrlSmall = defaultEmojiAssetUrl;\nexport let emojiFileExtensionSmall = '.png';\n\n// Used for emoji larger than 16px\nexport let emojiImageUrlLarge = defaultEmojiAssetUrl;\nexport let emojiFileExtensionLarge = '.png';\n\nexport const emojiJson = emojiJsonLocal;\n\nexport const emojiShortCodeRegex = /(^| |(?<=:))(:\\w+:)/g;\n\nexport function getEmojiData () {\n  return emojiJson;\n}\n\nexport function setEmojiAssetUrlSmall (url, fileExtension = '.png') {\n  if (!url.endsWith('/')) {\n    url = url + '/';\n  }\n  emojiImageUrlSmall = url;\n  emojiFileExtensionSmall = fileExtension;\n}\n\nexport function setEmojiAssetUrlLarge (url, fileExtension = '.svg') {\n  if (!url.endsWith('/')) {\n    url = url + '/';\n  }\n  emojiImageUrlLarge = url;\n  emojiFileExtensionLarge = fileExtension;\n}\n\nexport function setCustomEmojiUrl (url) {\n  customEmojiAssetUrl = url;\n}\n\nexport function setCustomEmojiJson (json) {\n  validateCustomEmojiJson(json);\n}\n\n/**\n * Validate custom emoji json\n */\nexport function validateCustomEmojiJson (json) {\n    const customEmojiProps = [\n    'custom',\n    'date_added',\n    'image',\n  ];\n  const customEmojiRequiredProps = [\n    'date_added',\n    'image',\n    'unicode_output',\n    'shortname',\n    'shortname_alternates',\n    'custom',\n    'name',\n  ];\n\n  /**\n   * Update single emoji properties.\n   * If the property exists in emojiData, it'll add the values if the property is an array, otherwise will overwrite.\n   * If not exists, will add the property to the emojiData object.\n   */\n  const _updateNativeEmojiData = (emojiData, propName, propValue) => {\n    if (emojiData[propName] === undefined) {\n      if (!customEmojiProps.includes(propName)) {\n        return;\n      }\n\n      // new property to add\n      emojiData[propName] = propValue;\n    } else {\n      if (Array.isArray(emojiData[propName])) {\n        emojiData[propName] = emojiData[propName].concat(propValue);\n      } else {\n        emojiData[propName] = propValue;\n      }\n    }\n  };\n\n  Object.entries(json).forEach((item) => {\n    const [customEmojiKey, customEmojiValue] = item;\n\n    if (customEmojiKey in emojiJson) {\n      // custom emoji exists in emoji json which means to update some data in the native emoji\n      const emojiData = emojiJson[customEmojiKey];\n\n      for (const customEmojiPropertyName in customEmojiValue) {\n        const customEmojiPropertyValue = customEmojiValue[customEmojiPropertyName];\n\n        _updateNativeEmojiData(emojiData, customEmojiPropertyName, customEmojiPropertyValue);\n      }\n    } else {\n      // new custom emoji\n      const _validateRequiredProps = () =>\n        customEmojiRequiredProps.every((val) => {\n          return customEmojiValue[val] !== undefined;\n        });\n\n      if (_validateRequiredProps()) {\n        emojiJson[customEmojiKey] = customEmojiValue;\n      } else {\n        console.error(\n          'The following custom emoji doesn\\'t contain the required properties:',\n          customEmojiValue,\n        );\n      }\n    }\n  });\n}\n\n// recursively searches the emoji data object containing data for all emojis\n// and returns the object with the specified shortcode.\nexport function shortcodeToEmojiData (shortcode) {\n  // eslint-disable-next-line complexity\n  function f (o, key) {\n    if (!o || typeof o !== 'object') {\n      return;\n    }\n    if ('shortname' in o) {\n      if (o.shortname === shortcode || o.shortname_alternates.includes(shortcode)) {\n        o.key = key;\n        reference = o;\n        return true;\n      }\n    }\n    Object.keys(o).some(function (k) {\n      return f(o[k], k);\n    });\n  }\n\n  let reference;\n  f(getEmojiData(), null);\n  return reference;\n}\n\nexport function getEmojiShortCode (emoji) {\n  if (emoji.startsWith(':')) return emoji;\n\n  const unicode = unicodeToString(emoji);\n  return emojiJson[unicode]?.shortname;\n}\n\n// Takes in an emoji unicode character(s) and converts it to an emoji string in the format the emoji data object expects\n// as a key. There can be multiple unicode characters in an emoji to denote the emoji itself, skin tone, gender\n// and such. Note that this function does NOT return variation selectors (fe0f) or zero width joiners (200d), as these\n// are not included as part of the key in the emoji.json.\n//\n// Example:\n// return value for smile emoji (no skin tone): 1f600\n// return value for left facing fist (light skin tone): 1f91b-1f3fb\nexport function unicodeToString (emoji) {\n  let key = '';\n  for (const codePoint of emoji) {\n    const codepoint = codePoint.codePointAt(0).toString(16).padStart(4, '0');\n\n    // skip 200d and fe0f as these are not included in emoji_strategy.json keys\n    if (['200d', 'fe0f'].includes(codepoint)) continue;\n    if (key !== '') { key = key + '-'; }\n    key = key + codepoint;\n  }\n  return key;\n}\n\n// Takes in unicode in string form ex: '1f91b-1f3fb' and converts it to an actual unicode character.\nexport function stringToUnicode (str) {\n  const uChars = str.split('-');\n  let result = '';\n  uChars.forEach((uChar) => {\n    result = result + String.fromCodePoint(parseInt(uChar, 16));\n  });\n  return result;\n}\n\n// Takes in a code (which could be unicode or shortcode) and returns the emoji data for it.\nexport function codeToEmojiData (code) {\n  code = code?.trim();\n  if (code.startsWith(':') && code.endsWith(':')) {\n    return shortcodeToEmojiData(code);\n  } else {\n    const unicodeString = unicodeToString(code);\n    const result = emojiJson[unicodeString];\n    if (result) result.key = unicodeString;\n    return result;\n  }\n}\n\n// Finds every shortcode in slot text\n// filters only the existing codes in emojiJson\n// removes duplicates.\n// @returns {string[]}\nexport function findShortCodes (textContent) {\n  const shortcodes = (\n    textContent.match(emojiShortCodeRegex) || []\n  ).map(code => code.trim());\n  return filterValidShortCodes(shortcodes);\n}\n\nexport function filterValidShortCodes (shortcodes) {\n  const filtered = shortcodes ? shortcodes.filter(code => shortcodeToEmojiData(code)) : [];\n  return new Set(filtered);\n}\n\n// Finds every emoji in slot text\n// removes duplicates\n// @returns {string[]}\nexport function findEmojis (textContent) {\n  const matches = [...textContent.matchAll(emojiRegex)];\n  const emojis = matches.length ? matches.map(match => match[0]) : [];\n  return new Set(emojis);\n}\n"],"mappings":"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"}