UNPKG

cerebro-converter

Version:

Cerebro plugin for converting units and currencies

770 lines (657 loc) 19.6 kB
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 14); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { module.exports = { getRates: __webpack_require__(8), buildExtract: __webpack_require__(7), parseUnitName: __webpack_require__(10), linearConverter: __webpack_require__(9) }; /***/ }), /* 1 */ /***/ (function(module, exports) { /* eslint quote-props: 0 */ /** * List of all supported currencies * @type {Array} */ module.exports.CURRENCIES = ['aud', 'bgn', 'brl', 'cad', 'chf', 'cny', 'czk', 'dkk', 'eur', 'gbp', 'hkd', 'hrk', 'huf', 'idr', 'ils', 'inr', 'jpy', 'krw', 'mxn', 'myr', 'nok', 'nzd', 'php', 'pln', 'ron', 'rub', 'sek', 'sgd', 'thb', 'try', 'uah', 'usd', 'zar', 'btc', 'clp']; /** * Array of prioritized currencies * @type {Array} */ module.exports.PRIORITY_CURRENCIES = ['rub', 'usd', 'eur']; /** * Hash of currencies by locale countries * @type {Object} */ module.exports.CURRENCY_BY_COUNTRY = { 'AU': 'aud', 'BR': 'brl', 'US': 'usd', 'CA': 'cad', 'CH': 'chf', 'CL': 'clp', 'CN': 'cny', 'GB': 'gbp', 'HK': 'hkd', 'KR': 'krw', 'NZ': 'nzd', 'PH': 'php', 'RU': 'rub', 'SG': 'sgd', 'UA': 'uah', 'ZA': 'zar', 'AD': 'eur', 'AT': 'eur', 'AX': 'eur', 'BE': 'eur', 'BL': 'eur', 'CY': 'eur', 'DE': 'eur', 'EE': 'eur', 'ES': 'eur', 'FI': 'eur', 'FR': 'eur', 'GF': 'eur', 'GP': 'eur', 'GR': 'eur', 'IE': 'eur', 'IT': 'eur', 'LU': 'eur', 'MC': 'eur', 'ME': 'eur', 'MF': 'eur', 'MQ': 'eur', 'MT': 'eur', 'NL': 'eur', 'PM': 'eur', 'PT': 'eur', 'RE': 'eur', 'SI': 'eur', 'SK': 'eur', 'SM': 'eur', 'TF': 'eur', 'VA': 'eur', 'YT': 'eur', 'IL': 'ils', 'IN': 'inr' /** * Hash of currencies by locale language * @type {Object} */ };module.exports.CURRENCY_BY_LANG = { 'bg': 'bgn', 'cs': 'czk', 'da': 'dkk', 'hr': 'hrk', 'hu': 'huf', 'id': 'idr', 'he': 'ils', 'hi': 'inr', 'ja': 'jpy', 'ms': 'myr', 'nb': 'nok', 'nn': 'nok', 'no': 'nok', 'ru': 'rub' /** * Object of synonims of currencies for better matching them in search queries * @type {Object} */ };module.exports.SYNONIMS = { 'франк*': 'chf', 'franc*': 'chf', '₣': 'chf', 'real*': 'brl', 'реал*': 'brl', 'kun*': 'hrk', 'кун*': 'hrk', 'форинт*': 'huf', 'forint*': 'huf', '₹': 'inr', 'rs': 'inr', 'rupee*': 'inr', 'ringgit*': 'myr', 'ринггит*': 'myr', '฿': 'thb', 'baht': 'thb', 'бат*': 'thb', 'bat*': 'thb', 'lir*': 'try', 'лир*': 'try', 'rand*': 'zar', 'рэнд*': 'zar', 'ренд*': 'zar', 'zlot*': 'pln', 'злот*': 'pln', '₴': 'uah', 'грн': 'uah', 'грив*': 'uah', 'bucks': 'usd', '$': 'usd', 'dollar*': 'usd', 'долл*': 'usd', '€': 'eur', 'eur*': 'eur', 'евро': 'eur', '£': 'gbp', 'фунт*': 'gbp', 'pound*': 'gbp', '₽': 'rub', 'руб': 'rub', 'рубл*': 'rub', '₪': 'ils', 'шекел*': 'ils', 'йен*': 'jpy', 'юан*': 'cny', 'yuan': 'cny', 'bitc*': 'btc', 'битко*': 'btc' /** * Hash of special display names for some currencies. Default name of currency displayed * @type {Object} */ };module.exports.DISPLAY_NAMES = { 'usd': '$', 'eur': '€', 'gbp': '£', 'rub': '₽', 'uah': '₴', 'ils': '₪', 'chf': '₣', 'thb': '฿', 'inr': '₹' }; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { const getUrl = __webpack_require__(12); const getBaseCurrency = __webpack_require__(11); const { SYNONIMS, DISPLAY_NAMES, PRIORITY_CURRENCIES } = __webpack_require__(1); const { parseUnitName, buildExtract, linearConverter } = __webpack_require__(0); // Hash of exchange rates const rates = {}; // Date of fetching exchange rates let ratesDate = null; let baseCurrency = null; /** * Get cache expiration date * @return {Date} */ function cacheExpirationDate() { return new Date(Date.now() - 2 * 3600 * 1000); } /** * Check that saved exchange rates are still valid * @return {Boolean} */ function cacheValid() { return ratesDate && ratesDate >= cacheExpirationDate(); } /** * Fetch & save rates from yahoo API * @return {Promise} promise that resolves with rates JSON */ function getRates(config) { baseCurrency = getBaseCurrency(config); const url = getUrl(); if (cacheValid()) return Promise.resolve(rates); return fetch(url).then(resp => resp.json()).then(response => { // Save exchange rates date ratesDate = new Date(); // mycurrency.net doesn't provide last refresh timestamp // Convert response array with exchange rates to hash Object.keys(response.rates).forEach(key => { rates[key.toLowerCase()] = parseFloat(response.rates[key]); }); }); } /** * Convert string to real currency * @param {String} unit * @return {String} */ function toUnit(unit) { return parseUnitName(SYNONIMS, rates, unit); } /** * Get target currency when it is not defined * @param {string} currency * @return {string} */ function defaultTarget(currency) { if (baseCurrency !== currency) { return baseCurrency; } return PRIORITY_CURRENCIES.find(cur => cur !== currency); } /** * Prettified name of currency. It is currency sign if it is supported * @param {String} currency * @return {String} */ function displayName(currency) { return DISPLAY_NAMES[currency] || currency; } function toUnitStruct(unit) { return { unit, displayName: displayName(unit) }; } module.exports = { getRates, extract: buildExtract(toUnit, toUnitStruct, defaultTarget), convert: linearConverter(rates) }; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { const { SYNONIMS, UNITS } = __webpack_require__(13); const { buildExtract, getRates, parseUnitName, linearConverter } = __webpack_require__(0); const toUnit = parseUnitName.bind(null, SYNONIMS, UNITS); function defaultTarget(unit) { return unit === 'm' ? 'ft' : 'm'; } function toUnitStruct(unit) { return { unit, displayName: unit }; } module.exports = { getRates, extract: buildExtract(toUnit, toUnitStruct, defaultTarget), convert: linearConverter(UNITS) }; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { const { SYNONIMS, UNITS } = __webpack_require__(15); const { buildExtract, getRates, parseUnitName, linearConverter } = __webpack_require__(0); const toUnit = parseUnitName.bind(null, SYNONIMS, UNITS); function defaultTarget(unit) { return unit === 'kg' ? 'lb' : 'kg'; } function toUnitStruct(unit) { return { unit, displayName: unit }; } module.exports = { getRates, extract: buildExtract(toUnit, toUnitStruct, defaultTarget), convert: linearConverter(UNITS) }; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { const { SYNONIMS, UNITS, KELVIN } = __webpack_require__(16); const { buildExtract, getRates, parseUnitName } = __webpack_require__(0); const toUnit = parseUnitName.bind(null, SYNONIMS, UNITS); function defaultTarget(unit) { return unit === '°c' ? '°f' : '°c'; } function toUnitStruct(unit) { return { unit, displayName: unit.toUpperCase() }; } function convert(amount, from, to) { let result = amount; if (from.unit === '°f') { result = 5 / 9 * (result - 32); if (to.unit === 'k') { result = result - KELVIN; } } else if (from.unit === '°c') { if (to.unit === 'k') { result = KELVIN + result; } if (to.unit === '°f') { result = 9 / 5 * result + 32; } } else if (from.unit === 'k') { if (to.unit === '°c') { result = result + KELVIN; } if (to.unit === '°f') { result = 9 / 5 * (result + KELVIN) + 32; } } return Math.round(result * 100) / 100; } module.exports = { getRates, convert, extract: buildExtract(toUnit, toUnitStruct, defaultTarget) }; /***/ }), /* 6 */ /***/ (function(module, exports) { module.exports = "data:image/png;base64,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" /***/ }), /* 7 */ /***/ (function(module, exports) { /** * Build function, that extracts from and to units from regexp match * @param {Function} toUnit convert string to real unit name * @param {Function} toUnitStruct Function that converts unit name to structure: * @param {Function} defaultTarget Function that returns default target unit * ** unit * ** displayName * ** rate * @return {Function} extract function that takes regexp match and return from and to structures */ module.exports = function (toUnit, toUnitStruct, defaultTarget) { return function extract(match) { const from = toUnit(match[2]); const to = match[3] ? toUnit(match[3]) : defaultTarget(from); if (!from || !to) { return false; } return [toUnitStruct(from), toUnitStruct(to)]; }; }; /***/ }), /* 8 */ /***/ (function(module, exports) { /** * Default getRates function just resolves Promise * because we know convertion rates * * @return {Promise} */ module.exports = () => Promise.resolve(); /***/ }), /* 9 */ /***/ (function(module, exports) { /** * Generate base linear converter from rates hash * @param {Object} rates * @return {Function} converter function */ module.exports = rates => (amount, from, to) => Math.round(amount / rates[from.unit] * rates[to.unit] * 100) / 100; /***/ }), /* 10 */ /***/ (function(module, exports) { /** * Convert user-provided string to real unit name * * @param {Object} synonims Hash with synonims * @param {Object} units Hash with conversion rates * @param {String} unit provided unit * @return {String} real unit name */ module.exports = function parseUnitName(synonims, units, unit) { let result = unit; if (synonims[result]) { result = synonims[result]; } else { const synonim = Object.keys(synonims).filter(key => key.indexOf('*') !== -1).find(key => { const regexp = new RegExp(key.replace(/\*/g, '.*')); return result.match(regexp); }); result = synonims[synonim] || result; } return units[result] ? result : null; }; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { const { CURRENCY_BY_LANG, CURRENCY_BY_COUNTRY } = __webpack_require__(1); /** * Get base currency based on country and language * @return {String} */ module.exports = config => CURRENCY_BY_COUNTRY[config.get('country')] || CURRENCY_BY_LANG[config.get('lang')] || 'usd'; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { // List of available currencies const { CURRENCIES } = __webpack_require__(1); // TODO: move API key to plugin settings const API_KEY = '5d35ac86e868977c24bbae30b5f9d018'; /** * Build url to get exchange rates * @return {String} url */ module.exports = () => { return `http://data.fixer.io/api/latest?access_key=${API_KEY}&format=1`; }; /***/ }), /* 13 */ /***/ (function(module, exports) { /* eslint quote-props: 0 */ module.exports.SYNONIMS = { 'см': 'cm', 'centimeter*': 'cm', 'сантиметр*': 'cm', 'км': 'km', 'kilometer*': 'km', 'километр*': 'km', 'м': 'm', 'meter*': 'm', 'метр*': 'm', 'mile*': 'mile', 'миля*': 'mile', 'мили': 'mile', 'миль': 'mile', 'in*': 'in', '"': 'in', 'дюйм*': 'in', "'": 'ft', 'foot': 'ft', 'feet': 'ft', 'фут*': 'ft', 'yard*': 'yard', 'ярд*': 'yard' }; module.exports.UNITS = { 'm': 1, 'cm': 100, 'in': 39.37, 'ft': 3.28, 'yard': 1.09, 'km': 0.001, 'mile': 0.00062 }; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { /* eslint no-eval: 0 */ const distance = __webpack_require__(3); const mass = __webpack_require__(4); const currency = __webpack_require__(2); const temperature = __webpack_require__(5); const icon = __webpack_require__(6); // Array of all available converters const CONVERTERS = [distance, mass, currency, temperature]; const numberRegexp = /[-+/*\d\s,\.\( )]+/; const unitRegexp = /[\wa-я\$€£₣₹฿₴₽₪'"°℃]+/; const mainRegexpString = [ // Start of line '^', // Number that we want to convert `(${numberRegexp.source})`, // Maybe space before source unit '\\s?', // Source unit name `(${unitRegexp.source})`, // Maybe spaces and any of word, like 'to' or 'in' '\\s*(?:to|in|at|в)?\\s*', // Maybe target unit (we can try to get default target unit by source unit) `(${unitRegexp.source})?`, // End of line '$'].join(''); // Main regexp to match conversation strings const REGEXP = new RegExp(mainRegexpString, 'i'); /** * Get rates for all units * @return {Promise} promise that resolves when all units are ready */ function eachConverter(config, fn) { CONVERTERS.forEach(converter => { converter.getRates(config).then(() => fn(converter)); }); } /** * Convert currency * * @param {String} options.term * @param {Function} options.display */ const converterPlugin = ({ term, display, config }) => { const match = term.toLowerCase().match(REGEXP); if (match) { let amount; try { amount = parseFloat(eval(match[1].toString().replace(/,/g, '.'))); } catch (err) { // do nothing when amount parse failed return; } eachConverter(config, converter => { const pair = converter.extract(match); if (!pair) { return; } const [from, to] = pair; const result = converter.convert(amount, from, to).toLocaleString(); display({ icon, title: `${amount.toLocaleString()}${from.displayName} = ${result}${to.displayName}`, term: `${term} = ${result}${to.displayName}`, clipboard: result.toString() }); }); } }; module.exports = { name: 'Convert', fn: converterPlugin }; /***/ }), /* 15 */ /***/ (function(module, exports) { /* eslint quote-props: 0 */ module.exports.SYNONIMS = { 'pound*': 'lb', 'фунт*': 'lb', 'ounce': 'oz', 'унци*': 'oz', 'kilogram*': 'kg', 'килогра*': 'kg', 'gram*': 'g', 'грам*': 'g', 'г': 'g', 'gr': 'g', 'гр': 'g', 'milligram*': 'mg', 'миллигр*': 'mg', 'карат*': 'ct', 'carat*': 'ct' }; module.exports.UNITS = { 'kg': 1, 'g': 1000, 'mg': 1000000, 'lb': 2.2, 'oz': 35.27, 'ct': 5000 }; /***/ }), /* 16 */ /***/ (function(module, exports) { /* eslint quote-props: 0 */ module.exports.SYNONIMS = { '°': '°c', '℃': '°c', 'c': '°c', 'celsi*': '°c', 'цельси*': '°c', 'кельви*': 'k', 'kelvi*': 'k', 'fahrenheit*': '°f', 'фаренгейт*': '°f', 'f': '°f' }; module.exports.UNITS = { '°f': true, '°c': true, 'k': true }; module.exports.KELVIN = 273.15; /***/ }) /******/ ]);