From 2ea8297dd5e83bcfce5e54040a70125c18a04c65 Mon Sep 17 00:00:00 2001 From: "Jocelyn Badgley (Twipped)" Date: Wed, 25 Aug 2021 08:53:42 -0700 Subject: [PATCH] eslint corrections --- analytics/fs.js | 49 +- build/cache.js | 2 +- build/lib/util.js | 2397 ++++++++++---------- js/.eslintrc.js | 24 +- package.json | 3 +- terraform/files/decorate/index.js | 4 +- terraform/files/decorate/package-lock.json | 94 + terraform/files/decorate/package.json | 1 + terraform/files/index_redirect.js | 2 +- terraform/lambda/src/cloudfront.js | 2 + terraform/lambda/src/cloudwatch-logs.js | 2 +- 11 files changed, 1338 insertions(+), 1242 deletions(-) diff --git a/analytics/fs.js b/analytics/fs.js index 7c8d3a5..07f031e 100644 --- a/analytics/fs.js +++ b/analytics/fs.js @@ -1,9 +1,9 @@ /** - * + * * @twipped/utils - * + * * Copyright (c) 2020, Jocelyn Badgley - * + * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -11,10 +11,10 @@ * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -22,9 +22,8 @@ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * */ - 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); @@ -36,16 +35,16 @@ var util = require('util'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } -var stream__default = /*#__PURE__*/_interopDefaultLegacy(stream); +var stream__default = /* #__PURE__*/_interopDefaultLegacy(stream); -const pipeline = util.promisify(stream__default['default'].pipeline); +const pipeline = util.promisify(stream__default.default.pipeline); const mkdir = (f, recursive = true) => fs.promises.mkdir(f, { - recursive + recursive, }); -const exists = f => fs.promises.access(f).then(() => true, () => false); -const stat = f => fs.promises.stat(f).catch(() => null); -const linkStat = f => fs.promises.lstat(f).catch(() => null); -async function isWritable(file) { +const exists = (f) => fs.promises.access(f).then(() => true, () => false); +const stat = (f) => fs.promises.stat(f).catch(() => null); +const linkStat = (f) => fs.promises.lstat(f).catch(() => null); +async function isWritable (file) { try { await fs.promises.access(file, fs.constants.F_OK | fs.constants.W_OK); return true; @@ -57,7 +56,7 @@ async function isWritable(file) { return false; } } -async function touch(file) { +async function touch (file) { const stats = await linkStat(file); if (stats) { @@ -69,34 +68,36 @@ async function touch(file) { if (!(await exists(path.dirname(file)))) await mkdir(path.dirname(file)); await fs.promises.writeFile(file, ''); } -async function remove(file) { +async function remove (file) { const stats = await linkStat(file); if (!stats) return; - if (stats.isDirectory()) return fs.promises.rmdir(file, { - recursive: true - }); + if (stats.isDirectory()) { + return fs.promises.rmdir(file, { + recursive: true, + }); + } return fs.promises.unlink(file); } -async function writeJson(file, object, options) { +async function writeJson (file, object, options) { const { replacer, spaces, ...ops } = { encoding: 'utf8', - ...options + ...options, }; await fs.promises.writeFile(file, `${JSON.stringify(object, replacer, spaces)}\n`, ops); } const writeJSON = writeJson; -async function readJson(file, options) { +async function readJson (file, options) { const { reviver, quiet, ...ops } = { encoding: 'utf8', - ...options + ...options, }; const content = await fs.promises.readFile(file, ops); @@ -109,7 +110,7 @@ async function readJson(file, options) { } const readJSON = readJson; -function stripBom(content) { +function stripBom (content) { if (Buffer.isBuffer(content)) { content = content.toString('utf8'); } diff --git a/build/cache.js b/build/cache.js index c1af1a2..6382b15 100644 --- a/build/cache.js +++ b/build/cache.js @@ -48,7 +48,7 @@ module.exports = exports = class Manifest { hash ({ action, input, output, ...task }) { if (!isFunction(action)) { - console.error({ action, input, output }); + console.error({ action, input, output }); // eslint-disable-line throw new Error('Task action is not a task action (function).'); } diff --git a/build/lib/util.js b/build/lib/util.js index dd8a4d2..4a74930 100644 --- a/build/lib/util.js +++ b/build/lib/util.js @@ -1,9 +1,9 @@ /** - * + * * handlebar-kit - * + * * Copyright (c) 2020, Jocelyn Badgley - * + * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -11,10 +11,10 @@ * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -22,42 +22,41 @@ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * Portions of the MIT licensed date-fns library are bundled with this * software. https://github.com/date-fns/date-fns#readme */ - 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function equals (value) { - value = uc(value); - return (tok) => uc(tok) === value; + value = uc(value); + return (tok) => uc(tok) === value; } function re (pattern) { - if (isString(pattern)) pattern = new RegExp(pattern); - return (tok) => !!String(tok).match(pattern); + if (isString(pattern)) pattern = new RegExp(pattern); + return (tok) => !!String(tok).match(pattern); } function anyOf (...args) { - args = args.flat().map(uc); - if (!anyBy(args, isFunction)) { - // arguments do not contain a function, so we can optimize - if (args.length === 1) return (tok) => uc(tok) === args[0]; - return (tok) => args.includes(uc(tok)); - } + args = args.flat().map(uc); + if (!anyBy(args, isFunction)) { + // arguments do not contain a function, so we can optimize + if (args.length === 1) return (tok) => uc(tok) === args[0]; + return (tok) => args.includes(uc(tok)); + } - args = args.map((a) => isFunction(a) && a || equals(a)); - if (args.length === 1) return (tok) => args[0](tok); - return (tok) => anyBy(args, (check) => check(tok)); + args = args.map((a) => isFunction(a) && a || equals(a)); + if (args.length === 1) return (tok) => args[0](tok); + return (tok) => anyBy(args, (check) => check(tok)); } function allOf (...args) { - args = args.flat().map((a) => isFunction(a) && a || equals(a)); - if (args.length === 1) return (tok) => args[0](tok); - return (tok) => allBy(args, (check) => check(tok)); + args = args.flat().map((a) => isFunction(a) && a || equals(a)); + if (args.length === 1) return (tok) => args[0](tok); + return (tok) => allBy(args, (check) => check(tok)); } function isNumber (input) { return typeof input === 'number' && !isNaN(input); } @@ -75,65 +74,65 @@ function isNull (input) { return input === null; } const isArray = Array.isArray; function isPrimitive (input) { - switch (typeof input) { - case 'string': - case 'number': - case 'boolean': - return true; - default: - return false; - } + switch (typeof input) { + case 'string': + case 'number': + case 'boolean': + return true; + default: + return false; + } } function isObject (input) { - if (!input) return false; - if (typeof input !== 'object') return false; - if (isArray(input)) return false; - if (!(input instanceof Object)) return false; - if (input.constructor !== Object.prototype.constructor) return false; - return true; + if (!input) return false; + if (typeof input !== 'object') return false; + if (isArray(input)) return false; + if (!(input instanceof Object)) return false; + if (input.constructor !== Object.prototype.constructor) return false; + return true; } const IS_LOOKUP = new Map([ - [ Array, isArray ], - [ Number, isNumber ], - [ String, isString ], - [ Boolean, isBoolean ], - [ Map, isMap ], - [ Set, isSet ], - [ Function, isFunction ], - [ Date, isDate ], - [ undefined, isUndefined ], - [ true, isTruthy ], - [ false, isFalsey ], + [ Array, isArray ], + [ Number, isNumber ], + [ String, isString ], + [ Boolean, isBoolean ], + [ Map, isMap ], + [ Set, isSet ], + [ Function, isFunction ], + [ Date, isDate ], + [ undefined, isUndefined ], + [ true, isTruthy ], + [ false, isFalsey ], ]); function is (...args) { - args = args.flat().map((a) => - IS_LOOKUP.get(a) + args = args.flat().map((a) => + IS_LOOKUP.get(a) || (isFunction(a) && a) || (isRegExp(a) && re(a)) || equals(a), - ); - if (args.length === 1) return (tok) => args[0](tok); - return (tok) => anyBy(args, (check) => check(tok)); + ); + if (args.length === 1) return (tok) => args[0](tok); + return (tok) => anyBy(args, (check) => check(tok)); } function isAll (...args) { - args = args.flat().map((a) => - IS_LOOKUP.get(a) + args = args.flat().map((a) => + IS_LOOKUP.get(a) || (isFunction(a) && a) || (isRegExp(a) && re(a)) || equals(a), - ); - if (args.length === 1) return (tok) => args[0](tok); - return (tok) => allBy(args, (check) => check(tok)); + ); + if (args.length === 1) return (tok) => args[0](tok); + return (tok) => allBy(args, (check) => check(tok)); } function isArrayOf (...args) { - const predicate = is(...args); - return (tok) => (isArray(tok) ? allBy(tok, predicate) : predicate(tok)); + const predicate = is(...args); + return (tok) => (isArray(tok) ? allBy(tok, predicate) : predicate(tok)); } function isArrayOfStrings (input) { return allBy(input, isString); } function isArrayOfNumbers (input) { return allBy(input, isNumber); } @@ -147,8 +146,8 @@ function isArrayOfTruthy (input) { return allBy(input, isTruthy); } function isArrayOfFalsey (input) { return allBy(input, isFalsey); } function contains (...args) { - const predicate = is(...args); - return (tok) => (isArray(tok) ? anyBy(tok, predicate) : predicate(tok)); + const predicate = is(...args); + return (tok) => (isArray(tok) ? anyBy(tok, predicate) : predicate(tok)); } function containsStrings (input) { return anyBy(input, isString); } function containsNumbers (input) { return anyBy(input, isNumber); } @@ -162,644 +161,644 @@ function containsTruthy (input) { return anyBy(input, isTruthy); } function containsFalsey (input) { return anyBy(input, isFalsey); } function truthy (value) { - if (isMappable(value)) return !!sizeOf(value); - return !!value; + if (isMappable(value)) return !!sizeOf(value); + return !!value; } function hasOwn (obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); + return Object.prototype.hasOwnProperty.call(obj, key); } function lc (str) { - return isString(uc) ? str.toLowerCase() : str; + return isString(uc) ? str.toLowerCase() : str; } function uc (str) { - return isString(str) ? str.toUpperCase() : str; + return isString(str) ? str.toUpperCase() : str; } function ucfirst (input) { - input = String(input); - return input.charAt(0).toUpperCase() + input.slice(1); + input = String(input); + return input.charAt(0).toUpperCase() + input.slice(1); } function ucsentence (input) { - return input.replace(/((?:\S[^.?!]*)[.?!]*)/g, (txt) => - txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(), - ); + return input.replace(/((?:\S[^.?!]*)[.?!]*)/g, (txt) => + txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(), + ); } function ucwords (input) { - return input.replace(/\w\S*/g, (word) => word.charAt(0).toUpperCase() + word.substr(1)); + return input.replace(/\w\S*/g, (word) => word.charAt(0).toUpperCase() + word.substr(1)); } function merge (...sources) { - const result = {}; - for (const source of sources) { - if (!source) continue; - for (const [ key, value ] of Object.entries(source)) { - if (isObject(value)) { - if (isObject(result[key])) { - result[key] = merge(result[key], value); - } else { - result[key] = merge(value); - } - } else { - result[key] = value; - } - } - } - return result; + const result = {}; + for (const source of sources) { + if (!source) continue; + for (const [ key, value ] of Object.entries(source)) { + if (isObject(value)) { + if (isObject(result[key])) { + result[key] = merge(result[key], value); + } else { + result[key] = merge(value); + } + } else { + result[key] = value; + } + } + } + return result; } function set (obj, path, value) { - if (path === null && path === undefined && path === '') return false; - if (isNumber(path)) path = [ String(path) ]; - else if (isString(path)) { - if (hasOwn(obj, path)) { - obj[path] = value; - return obj; - } - path = path.split(/[,[\].]+?/); - } + if (path === null && path === undefined && path === '') return false; + if (isNumber(path)) path = [ String(path) ]; + else if (isString(path)) { + if (hasOwn(obj, path)) { + obj[path] = value; + return obj; + } + path = path.split(/[,[\].]+?/); + } - const c = path.length - 1; - path - .filter((s) => s || s === 0) - .reduce((res, key, i) => { - if (i === c) { - res[key] = value; - return true; - } - if (isObject(res[key]) || isFunction(res[key])) return res[key]; - return (res[key] = {}); - }, obj); + const c = path.length - 1; + path + .filter((s) => s || s === 0) + .reduce((res, key, i) => { + if (i === c) { + res[key] = value; + return true; + } + if (isObject(res[key]) || isFunction(res[key])) return res[key]; + return (res[key] = {}); + }, obj); - return obj; + return obj; } function get (obj, path, defaultValue) { - if (path === null && path === undefined && path === '') return defaultValue; - if (isNumber(path)) path = [ String(path) ]; - else if (isString(path)) { - if (hasOwn(obj, path)) return obj[path]; - path = path.split(/[,[\].]+?/); - } + if (path === null && path === undefined && path === '') return defaultValue; + if (isNumber(path)) path = [ String(path) ]; + else if (isString(path)) { + if (hasOwn(obj, path)) return obj[path]; + path = path.split(/[,[\].]+?/); + } - const result = path - .filter((s) => s !== null && s !== undefined && s !== '') - .reduce((res, key) => - ((res !== null && res !== undefined) ? res[key] : res) - , obj); - return (result === undefined || result === obj) ? defaultValue : result; + const result = path + .filter((s) => s !== null && s !== undefined && s !== '') + .reduce((res, key) => + ((res !== null && res !== undefined) ? res[key] : res) + , obj); + return (result === undefined || result === obj) ? defaultValue : result; } function has (obj, path) { - if (isNumber(path)) path = [ String(path) ]; - else if (isString(path)) path = String.prototype.split.call(path, /[,[\].]+?/); - let res = obj; - for (const key of path) { - if (res === null || res === undefined) return false; - if (typeof res !== 'object' && typeof res !== 'function') return false; - if (!hasOwn(res, key)) return false; - res = res[key]; - } - return true; + if (isNumber(path)) path = [ String(path) ]; + else if (isString(path)) path = String.prototype.split.call(path, /[,[\].]+?/); + let res = obj; + for (const key of path) { + if (res === null || res === undefined) return false; + if (typeof res !== 'object' && typeof res !== 'function') return false; + if (!hasOwn(res, key)) return false; + res = res[key]; + } + return true; } function isMappable (collection, arrays = true) { - return ( - (arrays && isArray(collection)) || + return ( + (arrays && isArray(collection)) || (arrays && isSet(collection)) || isMap(collection) || collection && (typeof collection === 'object' || typeof collection === 'function') - ); + ); } function sizeOf (collection) { - if (isArray(collection) || isString(collection)) return collection.length; - if (isSet(collection) || isMap(collection)) return collection.size; - if (isObject(collection)) return Object.keys(collection).length; - return !!collection; + if (isArray(collection) || isString(collection)) return collection.length; + if (isSet(collection) || isMap(collection)) return collection.size; + if (isObject(collection)) return Object.keys(collection).length; + return !!collection; } function keys (input) { - if (isArray(input)) return [ ...input.keys() ]; + if (isArray(input)) return [ ...input.keys() ]; - if (isSet(input)) return Array.from(input.entries(), ([ k ]) => k); + if (isSet(input)) return Array.from(input.entries(), ([ k ]) => k); - if (isMap(input)) return Array.from(input.keys()); + if (isMap(input)) return Array.from(input.keys()); - if (isObject(input)) return Object.keys(input); + if (isObject(input)) return Object.keys(input); - return []; + return []; } function values (input) { - if (isArray(input)) return [ ...input ]; + if (isArray(input)) return [ ...input ]; - if (isSet(input) || isMap(input)) return Array.from(input.values()); + if (isSet(input) || isMap(input)) return Array.from(input.values()); - if (isObject(input)) return Object.values(input); + if (isObject(input)) return Object.values(input); - return []; + return []; } function arrayify (input) { - if (isArray(input)) return input; + if (isArray(input)) return input; - if (isSet(input) || isMap(input)) return Array.from(input.values()); + if (isSet(input) || isMap(input)) return Array.from(input.values()); - if (isObject(input)) return Object.values(input); + if (isObject(input)) return Object.values(input); - return [ input ]; + return [ input ]; } function first (input, count = 1) { - if (count === 1) { - if (isArray(input) || isString(input)) return input[0]; - if (isSet(input) || isObject(input)) for (const v of input) return v; - if (isMap(input)) for (const [ , v ] of input) return v; - return; - } + if (count === 1) { + if (isArray(input) || isString(input)) return input[0]; + if (isSet(input) || isObject(input)) for (const v of input) return v; + if (isMap(input)) for (const [ , v ] of input) return v; + return; + } - if (isArray(input) || isString(input)) return input.slice(0, count); - if (isSet(input)) return Array.from(input).slice(0, count); - if (isObject(input)) return Object.values(input).slice(0, count); - if (isMap(input)) return Array.from(input.values()).slice(0, count); + if (isArray(input) || isString(input)) return input.slice(0, count); + if (isSet(input)) return Array.from(input).slice(0, count); + if (isObject(input)) return Object.values(input).slice(0, count); + if (isMap(input)) return Array.from(input.values()).slice(0, count); } function last (input, count = 1) { - if (count === 1) { - if (isArray(input) || isString(input)) return input[input.length - 1]; - } + if (count === 1) { + if (isArray(input) || isString(input)) return input[input.length - 1]; + } - if (isArray(input) || isString(input)) return input.slice(-count); - if (isSet(input)) return Array.from(input).slice(-count); - if (isObject(input)) return Object.values(input).slice(-count); - if (isMap(input)) return Array.from(input.values()).slice(-count); + if (isArray(input) || isString(input)) return input.slice(-count); + if (isSet(input)) return Array.from(input).slice(-count); + if (isObject(input)) return Object.values(input).slice(-count); + if (isMap(input)) return Array.from(input.values()).slice(-count); } function all (...args) { - let input; - if (args.length > 1) { - input = args; - } else { - input = arrayify(args[0]); - } + let input; + if (args.length > 1) { + input = args; + } else { + input = arrayify(args[0]); + } - let result = input.shift(); - for (const value of input) { - if (!truthy(result)) { - return false; - } - result = value; - } + let result = input.shift(); + for (const value of input) { + if (!truthy(result)) { + return false; + } + result = value; + } - return result; + return result; } function allBy (collection, predicate = null) { - if (!collection) return false; - if (predicate === null) { - predicate = (v) => v; - } else if (!isFunction(predicate)) { - predicate = iteratee(predicate); - } + if (!collection) return false; + if (predicate === null) { + predicate = (v) => v; + } else if (!isFunction(predicate)) { + predicate = iteratee(predicate); + } - if (isArray(collection)) { - let i = 0; - for (const value of collection) { - if (!predicate(value, i, i++)) return false; - } - return true; - } + if (isArray(collection)) { + let i = 0; + for (const value of collection) { + if (!predicate(value, i, i++)) return false; + } + return true; + } - if (isSet(collection)) { - let i = 0; - for (const item of collection) { - if (!predicate(item, i, i++)) return false; - } - return true; - } + if (isSet(collection)) { + let i = 0; + for (const item of collection) { + if (!predicate(item, i, i++)) return false; + } + return true; + } - // received a Map - if (isMap(collection)) { - let i = 0; - for (const [ key, value ] of collection.entries()) { - if (!predicate(value, key, i++)) return false; - } - return true; - } + // received a Map + if (isMap(collection)) { + let i = 0; + for (const [ key, value ] of collection.entries()) { + if (!predicate(value, key, i++)) return false; + } + return true; + } - // received an object hash - if (isObject(collection)) { - let i = 0; - for (const [ key, value ] of Object.entries(collection)) { - if (!predicate(value, key, i++)) return false; - } - return true; - } + // received an object hash + if (isObject(collection)) { + let i = 0; + for (const [ key, value ] of Object.entries(collection)) { + if (!predicate(value, key, i++)) return false; + } + return true; + } - return !!collection; + return !!collection; } function any (...args) { - let input; - if (args.length > 1) { - input = args; - } else { - input = arrayify(args[0]); - } + let input; + if (args.length > 1) { + input = args; + } else { + input = arrayify(args[0]); + } - for (const value of input) { - if (truthy(value)) { - return value; - } - } + for (const value of input) { + if (truthy(value)) { + return value; + } + } - return input[input.length - 1]; + return input[input.length - 1]; } function anyBy (collection, predicate = null) { - if (!collection) return false; - if (predicate === null) { - predicate = (v) => v; - } else if (!isFunction(iteratee)) { - predicate = iteratee(predicate); - } + if (!collection) return false; + if (predicate === null) { + predicate = (v) => v; + } else if (!isFunction(iteratee)) { + predicate = iteratee(predicate); + } - if (isArray(collection)) { - let i = 0; - for (const value of collection) { - if (predicate(value, i, i++)) return true; - } - return false; - } + if (isArray(collection)) { + let i = 0; + for (const value of collection) { + if (predicate(value, i, i++)) return true; + } + return false; + } - if (isSet(collection)) { - let i = 0; - for (const item of collection) { - if (predicate(item, i, i++)) return true; - } - return false; - } + if (isSet(collection)) { + let i = 0; + for (const item of collection) { + if (predicate(item, i, i++)) return true; + } + return false; + } - // received a Map - if (isMap(collection)) { - let i = 0; - for (const [ key, value ] of collection.entries()) { - if (predicate(value, key, i++)) return true; - } - return false; - } + // received a Map + if (isMap(collection)) { + let i = 0; + for (const [ key, value ] of collection.entries()) { + if (predicate(value, key, i++)) return true; + } + return false; + } - // received an object hash - if (isObject(collection)) { - let i = 0; - for (const [ key, value ] of Object.entries(collection)) { - if (predicate(value, key, i++)) return true; - } - return false; - } + // received an object hash + if (isObject(collection)) { + let i = 0; + for (const [ key, value ] of Object.entries(collection)) { + if (predicate(value, key, i++)) return true; + } + return false; + } - return !!collection; + return !!collection; } function iteratee (match) { - if (isUndefined(match) || match === null) return Boolean; + if (isUndefined(match) || match === null) return Boolean; - if (isFunction(match)) return match; + if (isFunction(match)) return match; - if (isString(match)) { - return (o) => { - if (isArray(o)) return o.includes(match); - if (isObject(o)) return o[match]; - if (isMap(o)) return o.get(match); - if (isSet(o)) return o.has(match); - if (isPrimitive(o)) return o[match]; - return o === match; - }; - } + if (isString(match)) { + return (o) => { + if (isArray(o)) return o.includes(match); + if (isObject(o)) return o[match]; + if (isMap(o)) return o.get(match); + if (isSet(o)) return o.has(match); + if (isPrimitive(o)) return o[match]; + return o === match; + }; + } - if (isNumber(match)) { - return (o) => { - if (isObject(o) || isArray(o)) return o[match]; - if (isMap(o)) return o.get(match); - if (isSet(o)) return o.has(match); - if (isNumber(o)) return o === match; - if (isString(o)) return Number(o) === match; - return o === match; - }; - } + if (isNumber(match)) { + return (o) => { + if (isObject(o) || isArray(o)) return o[match]; + if (isMap(o)) return o.get(match); + if (isSet(o)) return o.has(match); + if (isNumber(o)) return o === match; + if (isString(o)) return Number(o) === match; + return o === match; + }; + } - if (isArray(match)) { - const [ key, value ] = match; - return (o) => o[key] === value; - } + if (isArray(match)) { + const [ key, value ] = match; + return (o) => o[key] === value; + } - if (isObject(match)) { - // create an array of key/value iteratees - const tests = Object.entries(match).map(iteratee); - // evaluate the object against the array - return (o) => { - for (const t of tests) { - if (!t(o)) return false; - } - return true; - }; - } + if (isObject(match)) { + // create an array of key/value iteratees + const tests = Object.entries(match).map(iteratee); + // evaluate the object against the array + return (o) => { + for (const t of tests) { + if (!t(o)) return false; + } + return true; + }; + } } function sorter (match) { - if (isFunction(match)) return match; + if (isFunction(match)) return match; - function qs (a, b) { - if (a > b) return 1; - else if (b > a) return -1; - return 0; - } + function qs (a, b) { + if (a > b) return 1; + else if (b > a) return -1; + return 0; + } - if (isString(match)) { - return (a, b) => { - if (!isObject(a) && !isObject(b)) return qs(a, b); - if (!isObject(a)) return -1; - if (!isObject(b)) return 1; - return qs(a[match], b[match]); - }; - } + if (isString(match)) { + return (a, b) => { + if (!isObject(a) && !isObject(b)) return qs(a, b); + if (!isObject(a)) return -1; + if (!isObject(b)) return 1; + return qs(a[match], b[match]); + }; + } - if (isArray(match)) { - return (a, b) => { - if (!isObject(a) && !isObject(b)) return qs(a, b); - if (!isObject(a)) return -1; - if (!isObject(b)) return 1; - for (const k of match) { - const v = qs(a[k], b[k]); - if (v) return v; - } - return 0; - }; - } + if (isArray(match)) { + return (a, b) => { + if (!isObject(a) && !isObject(b)) return qs(a, b); + if (!isObject(a)) return -1; + if (!isObject(b)) return 1; + for (const k of match) { + const v = qs(a[k], b[k]); + if (v) return v; + } + return 0; + }; + } - if (isObject(match)) { - return (a, b) => { - if (!isObject(a) && !isObject(b)) return qs(a, b); - if (!isObject(a)) return -1; - if (!isObject(b)) return 1; - for (const [ k, d ] of Object.entries(match)) { - const v = qs(a[k], b[k]) * (d < 0 ? -1 : 1); - if (v) return v; - } - return 0; - }; - } + if (isObject(match)) { + return (a, b) => { + if (!isObject(a) && !isObject(b)) return qs(a, b); + if (!isObject(a)) return -1; + if (!isObject(b)) return 1; + for (const [ k, d ] of Object.entries(match)) { + const v = qs(a[k], b[k]) * (d < 0 ? -1 : 1); + if (v) return v; + } + return 0; + }; + } - return (a, b) => { - if (!isObject(a) && !isObject(b)) return qs(a, b); - if (!isObject(a)) return -1; - if (!isObject(b)) return 1; - return 0; - }; + return (a, b) => { + if (!isObject(a) && !isObject(b)) return qs(a, b); + if (!isObject(a)) return -1; + if (!isObject(b)) return 1; + return 0; + }; } function toPairs (object) { - return Object.entries(object); + return Object.entries(object); } function fromPairs (entries) { - return mapReduce(entries, ([ v, k ]) => [ v, k ]); + return mapReduce(entries, ([ v, k ]) => [ v, k ]); } function slice (collection, begin, end) { - if (isString(collection) || isArray(collection)) return collection.slice(begin, end); + if (isString(collection) || isArray(collection)) return collection.slice(begin, end); - if (isSet(collection)) { - return new Set(Array.from(collection.values()).slice(begin, end)); - } + if (isSet(collection)) { + return new Set(Array.from(collection.values()).slice(begin, end)); + } - if (isMap(collection)) { - return new Map(Array.from(collection.entries()).slice(begin, end)); - } + if (isMap(collection)) { + return new Map(Array.from(collection.entries()).slice(begin, end)); + } - if (isObject(collection)) { - return fromPairs(toPairs(collection).slice(begin, end)); - } + if (isObject(collection)) { + return fromPairs(toPairs(collection).slice(begin, end)); + } - return collection; + return collection; } function sort (collection, predicate) { - predicate = sorter(predicate); + predicate = sorter(predicate); - if (isArray(collection)) return [ ...collection ].sort(predicate); + if (isArray(collection)) return [ ...collection ].sort(predicate); - if (isSet(collection)) { - return new Set(Array.from(collection.values()).sort(predicate)); - } + if (isSet(collection)) { + return new Set(Array.from(collection.values()).sort(predicate)); + } - // sort by key for maps and objects - const hashpredicate = (a, b) => predicate(a[0], b[0]); + // sort by key for maps and objects + const hashpredicate = (a, b) => predicate(a[0], b[0]); - if (isMap(collection)) { - return new Map(Array.from(collection.entries()).sort(hashpredicate)); - } + if (isMap(collection)) { + return new Map(Array.from(collection.entries()).sort(hashpredicate)); + } - if (isObject(collection)) { - return fromPairs(toPairs(collection).sort(hashpredicate)); - } + if (isObject(collection)) { + return fromPairs(toPairs(collection).sort(hashpredicate)); + } - return collection; + return collection; } function map (collection, predicate) { - predicate = iteratee(predicate); + predicate = iteratee(predicate); - if (isArray(collection)) { - return collection.map((value, i) => predicate(value, i, i)); - } + if (isArray(collection)) { + return collection.map((value, i) => predicate(value, i, i)); + } - if (isSet(collection)) { - return Array.from(collection, (value, i) => predicate(value, i, i)); - } + if (isSet(collection)) { + return Array.from(collection, (value, i) => predicate(value, i, i)); + } - return mapReduce(collection, (value, key, index) => [ key, predicate(value, key, index) ]); + return mapReduce(collection, (value, key, index) => [ key, predicate(value, key, index) ]); } function uniq (collection, predicate = null) { - if (predicate === null) { - predicate = (v) => v; - } else { - predicate = iteratee(predicate); - } + if (predicate === null) { + predicate = (v) => v; + } else { + predicate = iteratee(predicate); + } - const exists = new Set(); + const exists = new Set(); - if (isArray(collection)) { - const result = []; - collection.forEach((v) => { - const match = predicate(v); - if (exists.has(match)) return; - exists.add(match); - result.push(v); - }); + if (isArray(collection)) { + const result = []; + collection.forEach((v) => { + const match = predicate(v); + if (exists.has(match)) return; + exists.add(match); + result.push(v); + }); - return result; - } + return result; + } - if (isSet(collection)) return new Set(collection); // really? + if (isSet(collection)) return new Set(collection); // really? - if (isMap(collection)) { - return new Map(Array.from(collection.entries(), ([ k, v ]) => { - const match = predicate(v); - if (exists.has(match)) return false; - exists.add(match); - return [ k, v ]; - }).filter(Boolean)); - } + if (isMap(collection)) { + return new Map(Array.from(collection.entries(), ([ k, v ]) => { + const match = predicate(v); + if (exists.has(match)) return false; + exists.add(match); + return [ k, v ]; + }).filter(Boolean)); + } - if (isObject(collection)) { - return mapReduce(collection, ([ v, k ]) => { - const match = predicate(v); - if (exists.has(match)) return null; - exists.add(match); - return [ k, v ]; - }); - } + if (isObject(collection)) { + return mapReduce(collection, ([ v, k ]) => { + const match = predicate(v); + if (exists.has(match)) return null; + exists.add(match); + return [ k, v ]; + }); + } - return collection; + return collection; } function keyBy (collection, predicate) { - predicate = iteratee(predicate); - return mapReduce(collection, (value, key, index) => - [ predicate(value, key, index), value ], - ); + predicate = iteratee(predicate); + return mapReduce(collection, (value, key, index) => + [ predicate(value, key, index), value ], + ); } function groupBy (collection, predicate) { - predicate = iteratee(predicate); - return reduce(collection, (result, value, key, index) => { - const k = predicate(value, key, index); - (result[k] || (result[k] = [])).push(value); - return result; - }, {}); + predicate = iteratee(predicate); + return reduce(collection, (result, value, key, index) => { + const k = predicate(value, key, index); + (result[k] || (result[k] = [])).push(value); + return result; + }, {}); } function filter (collection, predicate) { - predicate = iteratee(predicate); + predicate = iteratee(predicate); - if (isArray(collection)) { - return collection.filter((value, i) => predicate(value, i, i)); - } + if (isArray(collection)) { + return collection.filter((value, i) => predicate(value, i, i)); + } - if (isSet(collection)) { - return Array.from(collection).filter((value, i) => predicate(value, i, i)); - } + if (isSet(collection)) { + return Array.from(collection).filter((value, i) => predicate(value, i, i)); + } - throw new Error('filter can not be applied to objects or maps, perhaps you meant to use omit?'); + throw new Error('filter can not be applied to objects or maps, perhaps you meant to use omit?'); } function omit (collection, predicate) { - if (isFunction(predicate)) { - return mapReduce(collection, (value, key, index) => - (predicate(value, key, index) - ? [ undefined, undefined ] - : [ key, value ]), - ); - } + if (isFunction(predicate)) { + return mapReduce(collection, (value, key, index) => + (predicate(value, key, index) + ? [ undefined, undefined ] + : [ key, value ]), + ); + } - if (isString(predicate)) { - predicate = [ predicate ]; - } + if (isString(predicate)) { + predicate = [ predicate ]; + } - if (!isArray(predicate)) throw new Error('omit requires a string or array of strings'); - return mapReduce(collection, (value, key) => - (predicate.includes(key) - ? [ undefined, undefined ] - : [ key, value ]), - ); + if (!isArray(predicate)) throw new Error('omit requires a string or array of strings'); + return mapReduce(collection, (value, key) => + (predicate.includes(key) + ? [ undefined, undefined ] + : [ key, value ]), + ); } function pick (collection, predicate) { - if (!collection) return {}; + if (!collection) return {}; - if (isFunction(predicate)) { - return mapReduce(collection, (value, key, index) => - (predicate(value, key, index) - ? [ key, value ] - : [ undefined, undefined ]), - ); - } + if (isFunction(predicate)) { + return mapReduce(collection, (value, key, index) => + (predicate(value, key, index) + ? [ key, value ] + : [ undefined, undefined ]), + ); + } - if (isString(predicate)) { - predicate = [ predicate ]; - } + if (isString(predicate)) { + predicate = [ predicate ]; + } - if (!isArray(predicate)) throw new Error('pick requires a string or array of strings'); - return predicate.reduce((obj, key) => { - const value = get(collection, key); - if (isUndefined(value)) return obj; - return set(obj, key, value); - }, {}); + if (!isArray(predicate)) throw new Error('pick requires a string or array of strings'); + return predicate.reduce((obj, key) => { + const value = get(collection, key); + if (isUndefined(value)) return obj; + return set(obj, key, value); + }, {}); } function deepPick (collection, schema) { - if (isPrimitive(schema) && isPrimitive(collection)) return collection; + if (isPrimitive(schema) && isPrimitive(collection)) return collection; - if (isArray(schema) && schema.length > 0) { - // collection does not match this schema tier, abort - if (!isArray(collection)) return; + if (isArray(schema) && schema.length > 0) { + // collection does not match this schema tier, abort + if (!isArray(collection)) return; - schema = schema[0]; - return collection.map((branch) => deepPick(branch, schema)); - } + schema = schema[0]; + return collection.map((branch) => deepPick(branch, schema)); + } - // if the schema at this tier is not an object, - // return the value at this tier only if schema is truthy - if (!isObject(schema)) return schema ? collection : undefined; - if (isPrimitive(collection)) return; + // if the schema at this tier is not an object, + // return the value at this tier only if schema is truthy + if (!isObject(schema)) return schema ? collection : undefined; + if (isPrimitive(collection)) return; - // if the collection isn't something we can pull data from, skip it - if (!isObject(collection) && !isFunction(collection)) return; + // if the collection isn't something we can pull data from, skip it + if (!isObject(collection) && !isFunction(collection)) return; - const result = {}; - for (const [ key, subschema ] of Object.entries(schema)) { + const result = {}; + for (const [ key, subschema ] of Object.entries(schema)) { - const target = collection[key]; - if (isUndefined(target)) continue; + const target = collection[key]; + if (isUndefined(target)) continue; - const child = deepPick(target, subschema); - if (isUndefined(child)) continue; + const child = deepPick(target, subschema); + if (isUndefined(child)) continue; - result[key] = child; - } + result[key] = child; + } - return result; + return result; } function pathinate (object, delimiter = '.') { - const paths = []; + const paths = []; - function descend (branch, ancest) { - if (!isObject(branch)) { - paths.push(ancest.join(delimiter)); - return; - } - for (const [ k, v ] of Object.entries(branch)) { - descend(v, ancest.concat([ k ])); - } - return; - } + function descend (branch, ancest) { + if (!isObject(branch)) { + paths.push(ancest.join(delimiter)); + return; + } + for (const [ k, v ] of Object.entries(branch)) { + descend(v, ancest.concat([ k ])); + } + return; + } - descend(object, []); + descend(object, []); - return uniq(paths); + return uniq(paths); } @@ -811,761 +810,761 @@ function pathinate (object, delimiter = '.') { * @return {Object} */ function mapReduce (collection, cb) { - if (!collection) return {}; + if (!collection) return {}; - const result = {}; - function iterate (v, k, i) { - // return true to continue looping - const res = cb(v, k, i) || []; - if (res === false) return false; - if (!res || !isArray(res)) return true; - const [ key, value ] = res; - if (key === undefined || key === null || value === undefined) return true; - result[key] = value; - return true; - } + const result = {}; + function iterate (v, k, i) { + // return true to continue looping + const res = cb(v, k, i) || []; + if (res === false) return false; + if (!res || !isArray(res)) return true; + const [ key, value ] = res; + if (key === undefined || key === null || value === undefined) return true; + result[key] = value; + return true; + } - if (isArray(collection)) { - let i = 0; - for (const value of collection) { - if (!iterate(value, i, i++)) break; - } - return result; - } + if (isArray(collection)) { + let i = 0; + for (const value of collection) { + if (!iterate(value, i, i++)) break; + } + return result; + } - if (isSet(collection)) { - let i = 0; - for (const item of collection) { - if (!iterate(item, i, i++)) break; - } - return result; - } + if (isSet(collection)) { + let i = 0; + for (const item of collection) { + if (!iterate(item, i, i++)) break; + } + return result; + } - // received a Map - if (isMap(collection)) { - let i = 0; - for (const [ key, value ] of collection.entries()) { - if (!iterate(value, key, i++)) break; - } - return result; - } + // received a Map + if (isMap(collection)) { + let i = 0; + for (const [ key, value ] of collection.entries()) { + if (!iterate(value, key, i++)) break; + } + return result; + } - // received an object hash - if (isObject(collection)) { - let i = 0; - for (const [ key, value ] of Object.entries(collection)) { - if (!iterate(value, key, i++)) break; - } - return result; - } + // received an object hash + if (isObject(collection)) { + let i = 0; + for (const [ key, value ] of Object.entries(collection)) { + if (!iterate(value, key, i++)) break; + } + return result; + } - return result; + return result; } function reduce (collection, predicate, init) { - if (!isFunction(predicate)) throw new TypeError('Predicate must be a function'); + if (!isFunction(predicate)) throw new TypeError('Predicate must be a function'); - if (isArray(collection)) return collection.reduce((r, v, i) => predicate(r, v, i, i), init); + if (isArray(collection)) return collection.reduce((r, v, i) => predicate(r, v, i, i), init); - if (isSet(collection)) { - return Array.from(collection).reduce((r, v, i) => predicate(r, v, i, i), init); - } + if (isSet(collection)) { + return Array.from(collection).reduce((r, v, i) => predicate(r, v, i, i), init); + } - if (isMap(collection)) { - return Array.from(collection.entries()).reduce((prev, [ key, value ], i) => predicate(prev, value, key, i), init); - } + if (isMap(collection)) { + return Array.from(collection.entries()).reduce((prev, [ key, value ], i) => predicate(prev, value, key, i), init); + } - if (isObject(collection)) { - return Object.entries(collection).reduce((prev, [ key, value ], i) => predicate(prev, value, key, i), init); - } + if (isObject(collection)) { + return Object.entries(collection).reduce((prev, [ key, value ], i) => predicate(prev, value, key, i), init); + } } function flatten (collection, depth = Infinity) { - if (depth <= 0) return slice(collection); - return reduce(collection, - (acc, val) => acc.concat(...( - isMappable(val) - ? flatten(val, depth - 1) - : [ val ] - )), - [], - ); + if (depth <= 0) return slice(collection); + return reduce(collection, + (acc, val) => acc.concat(...( + isMappable(val) + ? flatten(val, depth - 1) + : [ val ] + )), + [], + ); } function slugify (input, delimiter = '-', separators = false) { - var i = separators && separators.length; - var slug = input; - var regexEscape = new RegExp(/[[/\\^$*+?.()|{}\]]/g); - var regexDelimiter = delimiter.replace(regexEscape, '\\$&'); - var prohibited = new RegExp('([^a-z0-9' + regexDelimiter + '])', 'g'); - var consecutive = new RegExp('(' + regexDelimiter + '+)', 'g'); - var trim = new RegExp('^' + regexDelimiter + '*(.*?)' + regexDelimiter + '*$'); - var sanitizer = { - // common latin - 'á': 'a', - 'à': 'a', - 'â': 'a', - 'ä': 'a', - 'ã': 'a', - 'æ': 'ae', - 'ç': 'c', - 'é': 'e', - 'è': 'e', - 'ê': 'e', - 'ë': 'e', - 'ẽ': 'e', - 'í': 'i', - 'ì': 'i', - 'î': 'i', - 'ï': 'i', - 'ĩ': 'i', - 'ó': 'o', - 'ò': 'o', - 'ô': 'o', - 'ö': 'o', - 'õ': 'o', - 'œ': 'oe', - 'ß': 'ss', - 'ú': 'u', - 'ù': 'u', - 'û': 'u', - 'ü': 'u', - 'ũ': 'u', + var i = separators && separators.length; + var slug = input; + var regexEscape = new RegExp(/[[/\\^$*+?.()|{}\]]/g); + var regexDelimiter = delimiter.replace(regexEscape, '\\$&'); + var prohibited = new RegExp('([^a-z0-9' + regexDelimiter + '])', 'g'); + var consecutive = new RegExp('(' + regexDelimiter + '+)', 'g'); + var trim = new RegExp('^' + regexDelimiter + '*(.*?)' + regexDelimiter + '*$'); + var sanitizer = { + // common latin + 'á': 'a', + 'à': 'a', + 'â': 'a', + 'ä': 'a', + 'ã': 'a', + 'æ': 'ae', + 'ç': 'c', + 'é': 'e', + 'è': 'e', + 'ê': 'e', + 'ë': 'e', + 'ẽ': 'e', + 'í': 'i', + 'ì': 'i', + 'î': 'i', + 'ï': 'i', + 'ĩ': 'i', + 'ó': 'o', + 'ò': 'o', + 'ô': 'o', + 'ö': 'o', + 'õ': 'o', + 'œ': 'oe', + 'ß': 'ss', + 'ú': 'u', + 'ù': 'u', + 'û': 'u', + 'ü': 'u', + 'ũ': 'u', - // other diacritics - 'ă': 'a', - 'ắ': 'a', - 'ằ': 'a', - 'ẵ': 'a', - 'ẳ': 'a', - 'ấ': 'a', - 'ầ': 'a', - 'ẫ': 'a', - 'ẩ': 'a', - 'ǎ': 'a', - 'å': 'a', - 'ǻ': 'a', - 'ǟ': 'a', - 'ȧ': 'a', - 'ǡ': 'a', - 'ą': 'a', - 'ā': 'a', - 'ả': 'a', - 'ȁ': 'a', - 'ȃ': 'a', - 'ạ': 'a', - 'ặ': 'a', - 'ậ': 'a', - 'ḁ': 'a', - 'ⱥ': 'a', - 'ᶏ': 'a', - 'ɐ': 'a', - 'ɑ': 'a', + // other diacritics + 'ă': 'a', + 'ắ': 'a', + 'ằ': 'a', + 'ẵ': 'a', + 'ẳ': 'a', + 'ấ': 'a', + 'ầ': 'a', + 'ẫ': 'a', + 'ẩ': 'a', + 'ǎ': 'a', + 'å': 'a', + 'ǻ': 'a', + 'ǟ': 'a', + 'ȧ': 'a', + 'ǡ': 'a', + 'ą': 'a', + 'ā': 'a', + 'ả': 'a', + 'ȁ': 'a', + 'ȃ': 'a', + 'ạ': 'a', + 'ặ': 'a', + 'ậ': 'a', + 'ḁ': 'a', + 'ⱥ': 'a', + 'ᶏ': 'a', + 'ɐ': 'a', + 'ɑ': 'a', - 'ḃ': 'b', - 'ḅ': 'b', - 'ḇ': 'b', - 'ƀ': 'b', - 'ɓ': 'b', - 'ƃ': 'b', - 'ᵬ': 'b', - 'ᶀ': 'b', - 'þ': 'b', + 'ḃ': 'b', + 'ḅ': 'b', + 'ḇ': 'b', + 'ƀ': 'b', + 'ɓ': 'b', + 'ƃ': 'b', + 'ᵬ': 'b', + 'ᶀ': 'b', + 'þ': 'b', - 'ć': 'c', - 'ĉ': 'c', - 'č': 'c', - 'ċ': 'c', - 'ḉ': 'c', - 'ȼ': 'c', - 'ƈ': 'c', - 'ɕ': 'c', + 'ć': 'c', + 'ĉ': 'c', + 'č': 'c', + 'ċ': 'c', + 'ḉ': 'c', + 'ȼ': 'c', + 'ƈ': 'c', + 'ɕ': 'c', - 'ď': 'd', - 'ḋ': 'd', - 'ḑ': 'd', - 'ḍ': 'd', - 'ḓ': 'd', - 'ḏ': 'd', - 'đ': 'd', - 'ɖ': 'd', - 'ɗ': 'd', - 'ƌ': 'd', - 'ᵭ': 'd', - 'ᶁ': 'd', - 'ᶑ': 'd', - 'ȡ': 'd', - '∂': 'd', + 'ď': 'd', + 'ḋ': 'd', + 'ḑ': 'd', + 'ḍ': 'd', + 'ḓ': 'd', + 'ḏ': 'd', + 'đ': 'd', + 'ɖ': 'd', + 'ɗ': 'd', + 'ƌ': 'd', + 'ᵭ': 'd', + 'ᶁ': 'd', + 'ᶑ': 'd', + 'ȡ': 'd', + '∂': 'd', - 'ĕ': 'e', - 'ế': 'e', - 'ề': 'e', - 'ễ': 'e', - 'ể': 'e', - 'ě': 'e', - 'ė': 'e', - 'ȩ': 'e', - 'ḝ': 'e', - 'ę': 'e', - 'ē': 'e', - 'ḗ': 'e', - 'ḕ': 'e', - 'ẻ': 'e', - 'ȅ': 'e', - 'ȇ': 'e', - 'ẹ': 'e', - 'ệ': 'e', - 'ḙ': 'e', - 'ḛ': 'e', - 'ɇ': 'e', - 'ᶒ': 'e', + 'ĕ': 'e', + 'ế': 'e', + 'ề': 'e', + 'ễ': 'e', + 'ể': 'e', + 'ě': 'e', + 'ė': 'e', + 'ȩ': 'e', + 'ḝ': 'e', + 'ę': 'e', + 'ē': 'e', + 'ḗ': 'e', + 'ḕ': 'e', + 'ẻ': 'e', + 'ȅ': 'e', + 'ȇ': 'e', + 'ẹ': 'e', + 'ệ': 'e', + 'ḙ': 'e', + 'ḛ': 'e', + 'ɇ': 'e', + 'ᶒ': 'e', - 'ḟ': 'f', - 'ƒ': 'f', - 'ᵮ': 'f', - 'ᶂ': 'f', + 'ḟ': 'f', + 'ƒ': 'f', + 'ᵮ': 'f', + 'ᶂ': 'f', - 'ǵ': 'g', - 'ğ': 'g', - 'ĝ': 'g', - 'ǧ': 'g', - 'ġ': 'g', - 'ģ': 'g', - 'ḡ': 'g', - 'ǥ': 'g', - 'ɠ': 'g', - 'ᶃ': 'g', + 'ǵ': 'g', + 'ğ': 'g', + 'ĝ': 'g', + 'ǧ': 'g', + 'ġ': 'g', + 'ģ': 'g', + 'ḡ': 'g', + 'ǥ': 'g', + 'ɠ': 'g', + 'ᶃ': 'g', - 'ĥ': 'h', - 'ȟ': 'h', - 'ḧ': 'h', - 'ḣ': 'h', - 'ḩ': 'h', - 'ḥ': 'h', - 'ḫ': 'h', - 'ẖ': 'h', - 'ħ': 'h', - 'ⱨ': 'h', + 'ĥ': 'h', + 'ȟ': 'h', + 'ḧ': 'h', + 'ḣ': 'h', + 'ḩ': 'h', + 'ḥ': 'h', + 'ḫ': 'h', + 'ẖ': 'h', + 'ħ': 'h', + 'ⱨ': 'h', - 'ĭ': 'i', - 'ǐ': 'i', - 'ḯ': 'i', - 'į': 'i', - 'ī': 'i', - 'ỉ': 'i', - 'ȉ': 'i', - 'ȋ': 'i', - 'ị': 'i', - 'ḭ': 'i', - 'ɨ': 'i', - 'ᵻ': 'i', - 'ᶖ': 'i', - 'i': 'i', - 'ı': 'i', + 'ĭ': 'i', + 'ǐ': 'i', + 'ḯ': 'i', + 'į': 'i', + 'ī': 'i', + 'ỉ': 'i', + 'ȉ': 'i', + 'ȋ': 'i', + 'ị': 'i', + 'ḭ': 'i', + 'ɨ': 'i', + 'ᵻ': 'i', + 'ᶖ': 'i', + 'i': 'i', + 'ı': 'i', - 'ĵ': 'j', - 'ɉ': 'j', - 'ǰ': 'j', - 'ȷ': 'j', - 'ʝ': 'j', - 'ɟ': 'j', - 'ʄ': 'j', + 'ĵ': 'j', + 'ɉ': 'j', + 'ǰ': 'j', + 'ȷ': 'j', + 'ʝ': 'j', + 'ɟ': 'j', + 'ʄ': 'j', - 'ḱ': 'k', - 'ǩ': 'k', - 'ķ': 'k', - 'ḳ': 'k', - 'ḵ': 'k', - 'ƙ': 'k', - 'ⱪ': 'k', - 'ᶄ': 'k', + 'ḱ': 'k', + 'ǩ': 'k', + 'ķ': 'k', + 'ḳ': 'k', + 'ḵ': 'k', + 'ƙ': 'k', + 'ⱪ': 'k', + 'ᶄ': 'k', - 'ĺ': 'l', - 'ľ': 'l', - 'ļ': 'l', - 'ḷ': 'l', - 'ḹ': 'l', - 'ḽ': 'l', - 'ḻ': 'l', - 'ł': 'l', - 'ŀ': 'l', - 'ƚ': 'l', - 'ⱡ': 'l', - 'ɫ': 'l', - 'ɬ': 'l', - 'ᶅ': 'l', - 'ɭ': 'l', - 'ȴ': 'l', + 'ĺ': 'l', + 'ľ': 'l', + 'ļ': 'l', + 'ḷ': 'l', + 'ḹ': 'l', + 'ḽ': 'l', + 'ḻ': 'l', + 'ł': 'l', + 'ŀ': 'l', + 'ƚ': 'l', + 'ⱡ': 'l', + 'ɫ': 'l', + 'ɬ': 'l', + 'ᶅ': 'l', + 'ɭ': 'l', + 'ȴ': 'l', - 'ḿ': 'm', - 'ṁ': 'm', - 'ṃ': 'm', - 'ᵯ': 'm', - 'ᶆ': 'm', - 'ɱ': 'm', + 'ḿ': 'm', + 'ṁ': 'm', + 'ṃ': 'm', + 'ᵯ': 'm', + 'ᶆ': 'm', + 'ɱ': 'm', - 'ń': 'n', - 'ǹ': 'n', - 'ň': 'n', - 'ñ': 'n', - 'ṅ': 'n', - 'ņ': 'n', - 'ṇ': 'n', - 'ṋ': 'n', - 'ṉ': 'n', - 'n̈': 'n', - 'ɲ': 'n', - 'ƞ': 'n', - 'ŋ': 'n', - 'ᵰ': 'n', - 'ᶇ': 'n', - 'ɳ': 'n', - 'ȵ': 'n', + 'ń': 'n', + 'ǹ': 'n', + 'ň': 'n', + 'ñ': 'n', + 'ṅ': 'n', + 'ņ': 'n', + 'ṇ': 'n', + 'ṋ': 'n', + 'ṉ': 'n', + 'n̈': 'n', + 'ɲ': 'n', + 'ƞ': 'n', + 'ŋ': 'n', + 'ᵰ': 'n', + 'ᶇ': 'n', + 'ɳ': 'n', + 'ȵ': 'n', - 'ŏ': 'o', - 'ố': 'o', - 'ồ': 'o', - 'ỗ': 'o', - 'ổ': 'o', - 'ǒ': 'o', - 'ȫ': 'o', - 'ő': 'o', - 'ṍ': 'o', - 'ṏ': 'o', - 'ȭ': 'o', - 'ȯ': 'o', - '͘o͘': 'o', - 'ȱ': 'o', - 'ø': 'o', - 'ǿ': 'o', - 'ǫ': 'o', - 'ǭ': 'o', - 'ō': 'o', - 'ṓ': 'o', - 'ṑ': 'o', - 'ỏ': 'o', - 'ȍ': 'o', - 'ȏ': 'o', - 'ơ': 'o', - 'ớ': 'o', - 'ờ': 'o', - 'ỡ': 'o', - 'ở': 'o', - 'ợ': 'o', - 'ọ': 'o', - 'ộ': 'o', - 'ɵ': 'o', - 'ɔ': 'o', + 'ŏ': 'o', + 'ố': 'o', + 'ồ': 'o', + 'ỗ': 'o', + 'ổ': 'o', + 'ǒ': 'o', + 'ȫ': 'o', + 'ő': 'o', + 'ṍ': 'o', + 'ṏ': 'o', + 'ȭ': 'o', + 'ȯ': 'o', + '͘o͘': 'o', + 'ȱ': 'o', + 'ø': 'o', + 'ǿ': 'o', + 'ǫ': 'o', + 'ǭ': 'o', + 'ō': 'o', + 'ṓ': 'o', + 'ṑ': 'o', + 'ỏ': 'o', + 'ȍ': 'o', + 'ȏ': 'o', + 'ơ': 'o', + 'ớ': 'o', + 'ờ': 'o', + 'ỡ': 'o', + 'ở': 'o', + 'ợ': 'o', + 'ọ': 'o', + 'ộ': 'o', + 'ɵ': 'o', + 'ɔ': 'o', - 'ṕ': 'p', - 'ṗ': 'p', - 'ᵽ': 'p', - 'ƥ': 'p', - 'p̃': 'p', - 'ᵱ': 'p', - 'ᶈ': 'p', + 'ṕ': 'p', + 'ṗ': 'p', + 'ᵽ': 'p', + 'ƥ': 'p', + 'p̃': 'p', + 'ᵱ': 'p', + 'ᶈ': 'p', - 'ɋ': 'q', - 'ƣ': 'q', - 'ʠ': 'q', + 'ɋ': 'q', + 'ƣ': 'q', + 'ʠ': 'q', - 'ŕ': 'r', - 'ř': 'r', - 'ṙ': 'r', - 'ŗ': 'r', - 'ȑ': 'r', - 'ȓ': 'r', - 'ṛ': 'r', - 'ṝ': 'r', - 'ṟ': 'r', - 'ɍ': 'r', - 'ɽ': 'r', - 'ᵲ': 'r', - 'ᶉ': 'r', - 'ɼ': 'r', - 'ɾ': 'r', - 'ᵳ': 'r', + 'ŕ': 'r', + 'ř': 'r', + 'ṙ': 'r', + 'ŗ': 'r', + 'ȑ': 'r', + 'ȓ': 'r', + 'ṛ': 'r', + 'ṝ': 'r', + 'ṟ': 'r', + 'ɍ': 'r', + 'ɽ': 'r', + 'ᵲ': 'r', + 'ᶉ': 'r', + 'ɼ': 'r', + 'ɾ': 'r', + 'ᵳ': 'r', - 'ś': 's', - 'ṥ': 's', - 'ŝ': 's', - 'š': 's', - 'ṧ': 's', - 'ṡẛ': 's', - 'ş': 's', - 'ṣ': 's', - 'ṩ': 's', - 'ș': 's', - 's̩': 's', - 'ᵴ': 's', - 'ᶊ': 's', - 'ʂ': 's', - 'ȿ': 's', + 'ś': 's', + 'ṥ': 's', + 'ŝ': 's', + 'š': 's', + 'ṧ': 's', + 'ṡẛ': 's', + 'ş': 's', + 'ṣ': 's', + 'ṩ': 's', + 'ș': 's', + 's̩': 's', + 'ᵴ': 's', + 'ᶊ': 's', + 'ʂ': 's', + 'ȿ': 's', - 'ť': 't', - 'ṫ': 't', - 'ţ': 't', - 'ṭ': 't', - 'ț': 't', - 'ṱ': 't', - 'ṯ': 't', - 'ŧ': 't', - 'ⱦ': 't', - 'ƭ': 't', - 'ʈ': 't', - '̈ẗ': 't', - 'ᵵ': 't', - 'ƫ': 't', - 'ȶ': 't', + 'ť': 't', + 'ṫ': 't', + 'ţ': 't', + 'ṭ': 't', + 'ț': 't', + 'ṱ': 't', + 'ṯ': 't', + 'ŧ': 't', + 'ⱦ': 't', + 'ƭ': 't', + 'ʈ': 't', + '̈ẗ': 't', + 'ᵵ': 't', + 'ƫ': 't', + 'ȶ': 't', - 'ŭ': 'u', - 'ǔ': 'u', - 'ů': 'u', - 'ǘ': 'u', - 'ǜ': 'u', - 'ǚ': 'u', - 'ǖ': 'u', - 'ű': 'u', - 'ṹ': 'u', - 'ų': 'u', - 'ū': 'u', - 'ṻ': 'u', - 'ủ': 'u', - 'ȕ': 'u', - 'ȗ': 'u', - 'ư': 'u', - 'ứ': 'u', - 'ừ': 'u', - 'ữ': 'u', - 'ử': 'u', - 'ự': 'u', - 'ụ': 'u', - 'ṳ': 'u', - 'ṷ': 'u', - 'ṵ': 'u', - 'ʉ': 'u', - 'ᵾ': 'u', - 'ᶙ': 'u', + 'ŭ': 'u', + 'ǔ': 'u', + 'ů': 'u', + 'ǘ': 'u', + 'ǜ': 'u', + 'ǚ': 'u', + 'ǖ': 'u', + 'ű': 'u', + 'ṹ': 'u', + 'ų': 'u', + 'ū': 'u', + 'ṻ': 'u', + 'ủ': 'u', + 'ȕ': 'u', + 'ȗ': 'u', + 'ư': 'u', + 'ứ': 'u', + 'ừ': 'u', + 'ữ': 'u', + 'ử': 'u', + 'ự': 'u', + 'ụ': 'u', + 'ṳ': 'u', + 'ṷ': 'u', + 'ṵ': 'u', + 'ʉ': 'u', + 'ᵾ': 'u', + 'ᶙ': 'u', - 'ṽ': 'v', - 'ṿ': 'v', - 'ʋ': 'v', - 'ᶌ': 'v', - 'ⱴ': 'v', + 'ṽ': 'v', + 'ṿ': 'v', + 'ʋ': 'v', + 'ᶌ': 'v', + 'ⱴ': 'v', - 'ẃ': 'w', - 'ẁ': 'w', - 'ŵ': 'w', - 'ẅ': 'w', - 'ẇ': 'w', - 'ẉ': 'w', - 'ẘ': 'w', + 'ẃ': 'w', + 'ẁ': 'w', + 'ŵ': 'w', + 'ẅ': 'w', + 'ẇ': 'w', + 'ẉ': 'w', + 'ẘ': 'w', - 'ẍ': 'x', - 'ẋ': 'x', - 'ᶍ': 'x', + 'ẍ': 'x', + 'ẋ': 'x', + 'ᶍ': 'x', - 'ý': 'y', - 'ỳ': 'y', - 'ŷ': 'y', - 'ẙ': 'y', - 'ÿ': 'y', - 'ỹ': 'y', - 'ẏ': 'y', - 'ȳ': 'y', - 'ỷ': 'y', - 'ỵ': 'y', - 'ɏ': 'y', - 'ƴ': 'y', - 'ʏ': 'y', + 'ý': 'y', + 'ỳ': 'y', + 'ŷ': 'y', + 'ẙ': 'y', + 'ÿ': 'y', + 'ỹ': 'y', + 'ẏ': 'y', + 'ȳ': 'y', + 'ỷ': 'y', + 'ỵ': 'y', + 'ɏ': 'y', + 'ƴ': 'y', + 'ʏ': 'y', - 'ź': 'z', - 'ẑ': 'z', - 'ž': 'z', - 'ż': 'z', - 'ẓ': 'z', - 'ẕ': 'z', - 'ƶ': 'z', - 'ȥ': 'z', - 'ⱬ': 'z', - 'ᵶ': 'z', - 'ᶎ': 'z', - 'ʐ': 'z', - 'ʑ': 'z', - 'ɀ': 'z', + 'ź': 'z', + 'ẑ': 'z', + 'ž': 'z', + 'ż': 'z', + 'ẓ': 'z', + 'ẕ': 'z', + 'ƶ': 'z', + 'ȥ': 'z', + 'ⱬ': 'z', + 'ᵶ': 'z', + 'ᶎ': 'z', + 'ʐ': 'z', + 'ʑ': 'z', + 'ɀ': 'z', - // greek - 'α': 'a', - 'β': 'b', - 'γ': 'g', - 'ɣ': 'g', - 'δ': 'd', - 'ð': 'd', - 'ε': 'e', - 'ζ': 'z', - 'η': 'i', - 'θ': 'th', - 'ι': 'i', - 'κ': 'k', - 'λ': 'l', - 'μ': 'm', - 'µ': 'm', - 'ν': 'n', - 'ξ': 'x', - 'ο': 'o', - 'π': 'p', - 'ρ': 'r', - 'σ': 's', - 'ς': 's', - 'τ': 't', - 'υ': 'u', // official rule: if preceeded by 'α' OR 'ε' => 'v', by 'ο' => 'u', else => 'i' - 'φ': 'f', - 'χ': 'ch', - 'ψ': 'ps', - 'ω': 'o', + // greek + 'α': 'a', + 'β': 'b', + 'γ': 'g', + 'ɣ': 'g', + 'δ': 'd', + 'ð': 'd', + 'ε': 'e', + 'ζ': 'z', + 'η': 'i', + 'θ': 'th', + 'ι': 'i', + 'κ': 'k', + 'λ': 'l', + 'μ': 'm', + 'µ': 'm', + 'ν': 'n', + 'ξ': 'x', + 'ο': 'o', + 'π': 'p', + 'ρ': 'r', + 'σ': 's', + 'ς': 's', + 'τ': 't', + 'υ': 'u', // official rule: if preceeded by 'α' OR 'ε' => 'v', by 'ο' => 'u', else => 'i' + 'φ': 'f', + 'χ': 'ch', + 'ψ': 'ps', + 'ω': 'o', - // greek diacritics - 'ᾳ': 'a', - 'ά': 'a', - 'ὰ': 'a', - 'ᾴ': 'a', - 'ᾲ': 'a', - 'ᾶ': 'a', - 'ᾷ': 'a', - 'ἀ': 'a', - 'ᾀ': 'a', - 'ἄ': 'a', - 'ᾄ': 'a', - 'ἂ': 'a', - 'ᾂ': 'a', - 'ἆ': 'a', - 'ᾆ': 'a', - 'ἁ': 'a', - 'ᾁ': 'a', - 'ἅ': 'a', - 'ᾅ': 'a', - 'ἃ': 'a', - 'ᾃ': 'a', - 'ἇ': 'a', - 'ᾇ': 'a', - 'ᾱ': 'a', - 'ᾰ': 'a', + // greek diacritics + 'ᾳ': 'a', + 'ά': 'a', + 'ὰ': 'a', + 'ᾴ': 'a', + 'ᾲ': 'a', + 'ᾶ': 'a', + 'ᾷ': 'a', + 'ἀ': 'a', + 'ᾀ': 'a', + 'ἄ': 'a', + 'ᾄ': 'a', + 'ἂ': 'a', + 'ᾂ': 'a', + 'ἆ': 'a', + 'ᾆ': 'a', + 'ἁ': 'a', + 'ᾁ': 'a', + 'ἅ': 'a', + 'ᾅ': 'a', + 'ἃ': 'a', + 'ᾃ': 'a', + 'ἇ': 'a', + 'ᾇ': 'a', + 'ᾱ': 'a', + 'ᾰ': 'a', - 'έ': 'e', - 'ὲ': 'e', - 'ἐ': 'e', - 'ἔ': 'e', - 'ἒ': 'e', - 'ἑ': 'e', - 'ἕ': 'e', - 'ἓ': 'e', + 'έ': 'e', + 'ὲ': 'e', + 'ἐ': 'e', + 'ἔ': 'e', + 'ἒ': 'e', + 'ἑ': 'e', + 'ἕ': 'e', + 'ἓ': 'e', - 'ῃ': 'i', - 'ή': 'i', - 'ὴ': 'i', - 'ῄ': 'i', - 'ῂ': 'i', - 'ῆ': 'i', - 'ῇ': 'i', - 'ἠ': 'i', - 'ᾐ': 'i', - 'ἤ': 'i', - 'ᾔ': 'i', - 'ἢ': 'i', - 'ᾒ': 'i', - 'ἦ': 'i', - 'ᾖ': 'i', - 'ἡ': 'i', - 'ᾑ': 'i', - 'ἥ': 'i', - 'ᾕ': 'i', - 'ἣ': 'i', - 'ᾓ': 'i', - 'ἧ': 'i', - 'ᾗ': 'i', + 'ῃ': 'i', + 'ή': 'i', + 'ὴ': 'i', + 'ῄ': 'i', + 'ῂ': 'i', + 'ῆ': 'i', + 'ῇ': 'i', + 'ἠ': 'i', + 'ᾐ': 'i', + 'ἤ': 'i', + 'ᾔ': 'i', + 'ἢ': 'i', + 'ᾒ': 'i', + 'ἦ': 'i', + 'ᾖ': 'i', + 'ἡ': 'i', + 'ᾑ': 'i', + 'ἥ': 'i', + 'ᾕ': 'i', + 'ἣ': 'i', + 'ᾓ': 'i', + 'ἧ': 'i', + 'ᾗ': 'i', - 'ί': 'i', - 'ὶ': 'i', - 'ῖ': 'i', - 'ἰ': 'i', - 'ἴ': 'i', - 'ἲ': 'i', - 'ἶ': 'i', - 'ἱ': 'i', - 'ἵ': 'i', - 'ἳ': 'i', - 'ἷ': 'i', - 'ϊ': 'i', - 'ΐ': 'i', - 'ῒ': 'i', - 'ῗ': 'i', - 'ῑ': 'i', - 'ῐ': 'i', + 'ί': 'i', + 'ὶ': 'i', + 'ῖ': 'i', + 'ἰ': 'i', + 'ἴ': 'i', + 'ἲ': 'i', + 'ἶ': 'i', + 'ἱ': 'i', + 'ἵ': 'i', + 'ἳ': 'i', + 'ἷ': 'i', + 'ϊ': 'i', + 'ΐ': 'i', + 'ῒ': 'i', + 'ῗ': 'i', + 'ῑ': 'i', + 'ῐ': 'i', - 'ό': 'o', - 'ὸ': 'o', - 'ὀ': 'o', - 'ὄ': 'o', - 'ὂ': 'o', - 'ὁ': 'o', - 'ὅ': 'o', - 'ὃ': 'o', + 'ό': 'o', + 'ὸ': 'o', + 'ὀ': 'o', + 'ὄ': 'o', + 'ὂ': 'o', + 'ὁ': 'o', + 'ὅ': 'o', + 'ὃ': 'o', - 'ύ': 'u', - 'ὺ': 'u', - 'ῦ': 'u', - 'ὐ': 'u', - 'ὔ': 'u', - 'ὒ': 'u', - 'ὖ': 'u', - 'ὑ': 'u', - 'ὕ': 'u', - 'ὓ': 'u', - 'ὗ': 'u', - 'ϋ': 'u', - 'ΰ': 'u', - 'ῢ': 'u', - 'ῧ': 'u', - 'ῡ': 'u', - 'ῠ': 'u', + 'ύ': 'u', + 'ὺ': 'u', + 'ῦ': 'u', + 'ὐ': 'u', + 'ὔ': 'u', + 'ὒ': 'u', + 'ὖ': 'u', + 'ὑ': 'u', + 'ὕ': 'u', + 'ὓ': 'u', + 'ὗ': 'u', + 'ϋ': 'u', + 'ΰ': 'u', + 'ῢ': 'u', + 'ῧ': 'u', + 'ῡ': 'u', + 'ῠ': 'u', - 'ῳ': 'o', - 'ώ': 'o', - 'ῴ': 'o', - 'ὼ': 'o', - 'ῲ': 'o', - 'ῶ': 'o', - 'ῷ': 'o', - 'ὠ': 'o', - 'ᾠ': 'o', - 'ὤ': 'o', - 'ᾤ': 'o', - 'ὢ': 'o', - 'ᾢ': 'o', - 'ὦ': 'o', - 'ᾦ': 'o', - 'ὡ': 'o', - 'ᾡ': 'o', - 'ὥ': 'o', - 'ᾥ': 'o', - 'ὣ': 'o', - 'ᾣ': 'o', - 'ὧ': 'o', - 'ᾧ': 'o', + 'ῳ': 'o', + 'ώ': 'o', + 'ῴ': 'o', + 'ὼ': 'o', + 'ῲ': 'o', + 'ῶ': 'o', + 'ῷ': 'o', + 'ὠ': 'o', + 'ᾠ': 'o', + 'ὤ': 'o', + 'ᾤ': 'o', + 'ὢ': 'o', + 'ᾢ': 'o', + 'ὦ': 'o', + 'ᾦ': 'o', + 'ὡ': 'o', + 'ᾡ': 'o', + 'ὥ': 'o', + 'ᾥ': 'o', + 'ὣ': 'o', + 'ᾣ': 'o', + 'ὧ': 'o', + 'ᾧ': 'o', - 'ῤ': 'r', - 'ῥ': 'r', + 'ῤ': 'r', + 'ῥ': 'r', - // cyrillic (russian) - 'а': 'a', - 'б': 'b', - 'в': 'v', - 'г': 'g', - 'д': 'd', - 'е': 'e', - 'ё': 'e', - 'ж': 'zh', - 'з': 'z', - 'и': 'i', - 'й': 'j', - 'к': 'k', - 'л': 'l', - 'м': 'm', - 'н': 'n', - 'о': 'o', - 'п': 'p', - 'р': 'r', - 'с': 's', - 'т': 't', - 'у': 'u', - 'ф': 'f', - 'х': 'h', - 'ц': 'ts', - 'ч': 'ch', - 'ш': 'sh', - 'щ': 'sh', - 'ъ': '', - 'ы': 'i', - 'ь': '', - 'э': 'e', - 'ю': 'yu', - 'я': 'ya', - // --- - 'і': 'j', - 'ѳ': 'f', - 'ѣ': 'e', - 'ѵ': 'i', - 'ѕ': 'z', - 'ѯ': 'ks', - 'ѱ': 'ps', - 'ѡ': 'o', - 'ѫ': 'yu', - 'ѧ': 'ya', - 'ѭ': 'yu', - 'ѩ': 'ya', + // cyrillic (russian) + 'а': 'a', + 'б': 'b', + 'в': 'v', + 'г': 'g', + 'д': 'd', + 'е': 'e', + 'ё': 'e', + 'ж': 'zh', + 'з': 'z', + 'и': 'i', + 'й': 'j', + 'к': 'k', + 'л': 'l', + 'м': 'm', + 'н': 'n', + 'о': 'o', + 'п': 'p', + 'р': 'r', + 'с': 's', + 'т': 't', + 'у': 'u', + 'ф': 'f', + 'х': 'h', + 'ц': 'ts', + 'ч': 'ch', + 'ш': 'sh', + 'щ': 'sh', + 'ъ': '', + 'ы': 'i', + 'ь': '', + 'э': 'e', + 'ю': 'yu', + 'я': 'ya', + // --- + 'і': 'j', + 'ѳ': 'f', + 'ѣ': 'e', + 'ѵ': 'i', + 'ѕ': 'z', + 'ѯ': 'ks', + 'ѱ': 'ps', + 'ѡ': 'o', + 'ѫ': 'yu', + 'ѧ': 'ya', + 'ѭ': 'yu', + 'ѩ': 'ya', - // currency - '₳': 'ARA', - '฿': 'THB', - '₵': 'GHS', - '¢': 'c', - '₡': 'CRC', - '₢': 'Cr', - '₠': 'XEU', - '$': 'USD', - '₫': 'VND', - '৳': 'BDT', - '₯': 'GRD', - '€': 'EUR', - '₣': 'FRF', - '₲': 'PYG', - '₴': 'HRN', - '₭': 'LAK', - '₦': 'NGN', - '₧': 'ESP', - '₱': 'PhP', - '£': 'GBP', - '₤': 'GBP', - '₨': 'Rs', - '₪': 'NS', - '₮': 'MNT', - '₩': 'WON', - '¥': 'YEN', - '៛': 'KHR', + // currency + '₳': 'ARA', + '฿': 'THB', + '₵': 'GHS', + '¢': 'c', + '₡': 'CRC', + '₢': 'Cr', + '₠': 'XEU', + '$': 'USD', + '₫': 'VND', + '৳': 'BDT', + '₯': 'GRD', + '€': 'EUR', + '₣': 'FRF', + '₲': 'PYG', + '₴': 'HRN', + '₭': 'LAK', + '₦': 'NGN', + '₧': 'ESP', + '₱': 'PhP', + '£': 'GBP', + '₤': 'GBP', + '₨': 'Rs', + '₪': 'NS', + '₮': 'MNT', + '₩': 'WON', + '¥': 'YEN', + '៛': 'KHR', - // separators - '–': delimiter, - '—': delimiter, - '―': delimiter, - '~': delimiter, - '/': delimiter, - '\\': delimiter, - '|': delimiter, - '+': delimiter, - '‘': delimiter, - '’': delimiter, - '\'': delimiter, - ' ': delimiter, + // separators + '–': delimiter, + '—': delimiter, + '―': delimiter, + '~': delimiter, + '/': delimiter, + '\\': delimiter, + '|': delimiter, + '+': delimiter, + '‘': delimiter, + '’': delimiter, + '\'': delimiter, + ' ': delimiter, - // permitted by default but can be overridden - '-': '-', - '_': '_', - }; + // permitted by default but can be overridden + '-': '-', + '_': '_', + }; - // add any user-defined separator elements - if (separators) { - for (i; i >= 0; --i) { - sanitizer[separators[i]] = delimiter; - } - } + // add any user-defined separator elements + if (separators) { + for (i; i >= 0; --i) { + sanitizer[separators[i]] = delimiter; + } + } - // do all the replacements - slug = slug.toLowerCase(); // if we don't do this, add the uppercase versions to the sanitizer plus inlcude A-Z in the prohibited filter - slug = slug.replace(prohibited, (match) => sanitizer[match] || ''); - slug = slug.replace(consecutive, delimiter); - slug = slug.replace(trim, '$1'); + // do all the replacements + slug = slug.toLowerCase(); // if we don't do this, add the uppercase versions to the sanitizer plus inlcude A-Z in the prohibited filter + slug = slug.replace(prohibited, (match) => sanitizer[match] || ''); + slug = slug.replace(consecutive, delimiter); + slug = slug.replace(trim, '$1'); - return slug; + return slug; } exports.all = all; diff --git a/js/.eslintrc.js b/js/.eslintrc.js index 8caa274..459f7c7 100644 --- a/js/.eslintrc.js +++ b/js/.eslintrc.js @@ -1,27 +1,27 @@ module.exports = exports = { - extends: "twipped/browser", - env: {es6: true, jquery: true}, + extends: 'twipped/browser', + env: { es6: true, jquery: true }, rules: { 'indent': [ 2, 2, { 'MemberExpression': 1, } ], 'prefer-arrow-callback': 0, 'object-shorthand': 0, - 'node/no-unsupported-features/node-builtins': 0 + 'node/no-unsupported-features/node-builtins': 0, }, overrides: [ { files: '$*.jsx', - extends: "twipped/react", + extends: 'twipped/react', rules: { - 'react/jsx-indent': [2, 2, {checkAttributes: true}], - "react/no-unknown-property": [2, { ignore: ['class'] }], + 'react/jsx-indent': [ 2, 2, { checkAttributes: true } ], + 'react/no-unknown-property': [ 2, { ignore: [ 'class' ] } ], 'node/no-unpublished-import': 0, - "node/no-missing-import": ["error", { - "allowModules": ["svg", 'react'] - }] - } - } - ] + 'node/no-missing-import': [ 'error', { + 'allowModules': [ 'svg', 'react' ], + } ], + }, + }, + ], }; diff --git a/package.json b/package.json index 6e0fe03..77dbd53 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "description": "Code for construction of the GenderDysphoria.fyi website", "scripts": { - "test": "eslint ./ --fix" + "test": "eslint 'build/**/*.js' 'js/**/*.{js,jsx}' 'terraform/**/*.js' --fix", + "build": "gulp prod" }, "engines": { "node": ">=12.14.0" diff --git a/terraform/files/decorate/index.js b/terraform/files/decorate/index.js index d4b23ee..0e57003 100644 --- a/terraform/files/decorate/index.js +++ b/terraform/files/decorate/index.js @@ -1,11 +1,10 @@ /* eslint no-console:0 */ -/* global URLSearchParams */ const AWS = require('aws-sdk'); const zlib = require('zlib'); const util = require('util'); const path = require('path'); -const {URL} = require('url'); +const { URL } = require('url'); const s3 = new AWS.S3(); const { parse: parseLog } = require('cloudfront-log-parser'); const parseUA = require('ua-parser-js'); @@ -56,7 +55,6 @@ exports.handler = async (event) => { if (!query.start) return null; const useragent = parseUA(row.cs_user_agent); - const { referer } = query; const sessionStart = Number(query.start); const sessionEnd = query.end === 'null' ? 0 : Number(query.end); diff --git a/terraform/files/decorate/package-lock.json b/terraform/files/decorate/package-lock.json index 748c795..262d3da 100644 --- a/terraform/files/decorate/package-lock.json +++ b/terraform/files/decorate/package-lock.json @@ -4,6 +4,37 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "aws-sdk": { + "version": "2.975.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.975.0.tgz", + "integrity": "sha512-cmRcM+gU+rfW1RZjca3bdbRTQV6WHuCI6NuqnDgd5HoqufylCrNI/wtysPK1IMJLsAhrcsY0U0YRx+Y/hxQNoQ==", + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, "cloudfront-log-parser": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/cloudfront-log-parser/-/cloudfront-log-parser-1.1.0.tgz", @@ -14,10 +45,73 @@ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.9.0.tgz", "integrity": "sha512-khbFLu/MlzLjEzy9Gh8oY1hNt/Dvxw3J6Rbc28cVoYWQaC1S3YI4xwkF9ZWcjDLscbZlY9hISMr66RFzZagLsA==" }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + }, "ua-parser-js": { "version": "0.7.21", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==" + }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" } } } diff --git a/terraform/files/decorate/package.json b/terraform/files/decorate/package.json index 7f6a5ec..d0f5a0d 100644 --- a/terraform/files/decorate/package.json +++ b/terraform/files/decorate/package.json @@ -9,6 +9,7 @@ "author": "Jocelyn Badgley (http://twipped.com/)", "license": "MIT", "dependencies": { + "aws-sdk": "~2.975.0", "cloudfront-log-parser": "~1.1.0", "date-fns": "~2.9.0", "ua-parser-js": "~0.7.21" diff --git a/terraform/files/index_redirect.js b/terraform/files/index_redirect.js index c0805ce..7341aba 100644 --- a/terraform/files/index_redirect.js +++ b/terraform/files/index_redirect.js @@ -3,7 +3,7 @@ // This should be deployed as a Lambda@Edge connected to the CloudFront Distribution // Only Node.js 10.x Runtime supports Lambda@Edge for right now, we have to wait for AWS to support 12x and beyond -exports.handler = async (event, context) => { +exports.handler = async (event) => { /* * Expand S3 request to have index.html if it ends in / */ diff --git a/terraform/lambda/src/cloudfront.js b/terraform/lambda/src/cloudfront.js index de4cf6b..be2ceb6 100644 --- a/terraform/lambda/src/cloudfront.js +++ b/terraform/lambda/src/cloudfront.js @@ -1,3 +1,5 @@ +/* eslint no-console: 0 */ + const { gunzip } = require('zlib'); const { promisify } = require('util'); const { S3 } = require('aws-sdk'); diff --git a/terraform/lambda/src/cloudwatch-logs.js b/terraform/lambda/src/cloudwatch-logs.js index dca5e73..c745b8e 100644 --- a/terraform/lambda/src/cloudwatch-logs.js +++ b/terraform/lambda/src/cloudwatch-logs.js @@ -1,7 +1,7 @@ const { CloudWatchLogs } = require('aws-sdk'); // Split up ARN like "arn:aws:logs:eu-west-1:123456789012:log-group:example-group:*" -const [,,, region,,, logGroupName] = process.env.CLOUDWATCH_LOGS_GROUP_ARN.split(':'); +const [ ,,, region,,, logGroupName ] = process.env.CLOUDWATCH_LOGS_GROUP_ARN.split(':'); const cloudwatchlogs = new CloudWatchLogs({ region });