strapi-plugin-logz
Version:
Automatically capture and record the API calls made to your Strapi application
1,371 lines • 751 kB
JavaScript
import dayjs from "dayjs";
import defu from "defu";
import { json2csv } from "json-2-csv";
import require$$1 from "crypto";
import require$$0$1 from "child_process";
import * as yup$1 from "yup";
import require$$0$2 from "os";
import require$$0$4 from "path";
import require$$0$3 from "fs";
import require$$0$5 from "assert";
import require$$2 from "events";
import require$$0$7 from "buffer";
import require$$0$6 from "stream";
import require$$2$1 from "util";
import require$$0$8 from "constants";
import "node:stream";
const config = {
default: () => ({
// The default configuration for the plugin
skipList: [],
skipEndpoints: []
}),
validator(config2) {
if (config2.skipList && !Array.isArray(config2.skipList)) {
throw new Error("skipList must be an array");
}
if (config2.skipEndpoints && !Array.isArray(config2.skipEndpoints)) {
throw new Error("skipEndpoints must be an array");
}
},
/** The name of the plugin @default "logz" */
pluginName: "logz"
};
const bootstrap = async ({ strapi: strapi2 }) => {
const actions = [
{
section: "plugins",
displayName: "Allow Logz dashboard access",
uid: "menu-link",
pluginName: config.pluginName
}
];
await strapi2.admin.services.permission.actionProvider.registerMany(actions);
};
const contentTypes = {
logz: {
// Configuration for the table that will store the logs
schema: {
kind: "collectionType",
collectionName: "logz",
info: {
displayName: "Logz",
singularName: "logz",
pluralName: "logz",
description: "The logz collection"
},
options: { draftAndPublish: false, timestamps: true },
pluginOptions: {
"content-manager": { visible: true },
"content-type-builder": { visible: false }
},
attributes: {
action: {
configurable: false,
type: "text",
required: false
},
method: {
type: "string",
required: true,
configurable: false
},
url: {
type: "text",
configurable: false
},
statusCode: {
configurable: false,
type: "integer"
},
user: {
configurable: false,
type: "relation",
relation: "oneToOne",
target: "plugin::users-permissions.user"
},
data: {
configurable: false,
type: "json"
}
}
}
}
};
const pluginUID$1 = `plugin::${config.pluginName}.${config.pluginName}`;
const sanitizeOutput = async (data, ctx) => {
const schema2 = strapi.getModel(`plugin::${config.pluginName}.${config.pluginName}`);
const { auth } = ctx.state;
return strapi.contentAPI.sanitize.output(data, schema2, { auth });
};
const validateQuery = async (query, ctx) => {
const schema2 = strapi.getModel(`plugin::${config.pluginName}.${config.pluginName}`);
const { auth } = ctx.state;
return strapi.contentAPI.validate.query(query, schema2, { auth });
};
const sanitizeQuery = async (query, ctx) => {
const schema2 = strapi.getModel(`plugin::${config.pluginName}.${config.pluginName}`);
const { auth } = ctx.state;
return strapi.contentAPI.sanitize.query(query, schema2, { auth });
};
const controller = ({ strapi: strapi2 }) => ({
/**
* Download the logs as a CSV file
*
* Accepts a `start` and `end` query parameter to filter the logs by date
*/
async download(ctx) {
let { start, end } = ctx.query;
if (start) start = dayjs(start).startOf("day").toISOString();
if (end) end = dayjs(end).endOf("day").toISOString();
let data = await strapi2.documents(pluginUID$1).findMany({
populate: ["user"],
orderBy: { createdAt: "desc" },
where: start && end && {
createdAt: {
$gte: start,
$lt: end
}
}
});
data = await Promise.all(data.map((d) => sanitizeOutput(d, ctx)));
const csv = json2csv(data, {
keys: [
{ field: "id", title: "ID" },
{ field: "documentId", title: "Document ID" },
{ field: "action", title: "Action" },
{ field: "method", title: "Method" },
{ field: "url", title: "URL" },
{ field: "statusCode", title: "Status Code" },
{ field: "user.email", title: "User" },
{ field: "data", title: "Data" },
{ field: "createdAt", title: "Created At" },
{ field: "updatedAt", title: "Updated At" }
],
trimHeaderFields: true,
excelBOM: true,
emptyFieldValue: "N/A"
});
const fileName = `logs-${dayjs().format("YYYY-MM-DD")}.csv`;
ctx.set("Content-Type", "text/csv");
ctx.set("Content-Disposition", `attachment;filename="${fileName}"`);
ctx.body = csv;
},
/**
* Find all logs
*/
async find(ctx) {
await validateQuery(ctx.query, ctx);
const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);
const query = defu({}, sanitizedQuery, { orderBy: { createdAt: "desc" } });
let { results, pagination: pagination2 } = await strapi2.plugin(config.pluginName).service("logz").find(query);
results = await Promise.all(results.map((d) => sanitizeOutput(d, ctx)));
ctx.body = { data: results, pagination: pagination2 };
},
/**
* Find one log
*/
async findOne(ctx) {
await validateQuery(ctx.query, ctx);
const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);
let data = await strapi2.plugin(config.pluginName).service("logz").findOne(ctx.request.params.id, sanitizedQuery);
if (data) {
data = await sanitizeOutput(data, ctx);
}
return { data };
},
/**
* Get the total number of requests, login requests, register requests, and error requests for the dashboard
*/
async dashboardTotals(ctx) {
const totalRequests = await strapi2.plugin(config.pluginName).service("logz").count();
const totalLoginRequests = await strapi2.plugin(config.pluginName).service("logz").count({ where: { action: { $containsi: "Logged" } } });
const totalRegisterRequests = await strapi2.plugin(config.pluginName).service("logz").count({ where: { action: { $containsi: "Account created" } } });
const totalErrorRequests = await strapi2.plugin(config.pluginName).service("logz").count({ where: { statusCode: { $gte: 400 } } });
ctx.body = {
data: {
totalRequests,
totalLoginRequests,
totalRegisterRequests,
totalErrorRequests
}
};
},
/**
* Get the total number of requests over time based on the filterBy query parameter
*
* filterBy: `week` | `month`
*/
async requestOverTime(ctx) {
const { filterBy = "week" } = ctx.query;
const now = dayjs();
const data = [];
if (filterBy === "week") {
for (let i = 0; i < 7; i++) {
const startOfDay = now.subtract(i, "day").startOf("day").toISOString();
const endOfDay = now.subtract(i, "day").endOf("day").toISOString();
const day = now.subtract(i, "day").format("dddd");
let total = await strapi2.db.query(pluginUID$1).count({
where: {
createdAt: {
$gte: startOfDay,
$lt: endOfDay
}
}
});
data.push({ name: day, total });
}
} else if (filterBy === "month") {
for (let i = 0; i < 7; i++) {
const startOfMonth = now.subtract(i, "month").startOf("month").toISOString();
const endOfMonth = now.subtract(i, "month").endOf("month").toISOString();
const month = now.subtract(i, "month").format("MMMM");
let total = await strapi2.db.query(pluginUID$1).count({
where: {
createdAt: {
$gte: startOfMonth,
$lt: endOfMonth
}
}
});
data.push({ name: month, total });
}
}
ctx.body = { data };
},
/**
* Get the total number of logins vs register requests over time based on the filterBy query parameter
*
* filterBy: `week` | `month`
*/
async loginVsRegister(ctx) {
const { filterBy = "week" } = ctx.query;
const now = dayjs();
const data = [];
if (filterBy === "week") {
for (let i = 0; i < 7; i++) {
const startOfDay = now.subtract(i, "day").startOf("day").toISOString();
const endOfDay = now.subtract(i, "day").endOf("day").toISOString();
const day = now.subtract(i, "day").format("dddd");
let login = await strapi2.db.query(pluginUID$1).count({
where: {
createdAt: {
$gte: startOfDay,
$lt: endOfDay
},
action: { $containsi: "Logged" }
}
});
let register2 = await strapi2.db.query(pluginUID$1).count({
where: {
createdAt: {
$gte: startOfDay,
$lt: endOfDay
},
action: { $containsi: "Account created" }
}
});
data.push({ name: day, login, register: register2 });
}
} else if (filterBy === "month") {
for (let i = 0; i < 7; i++) {
const startOfMonth = now.subtract(i, "month").startOf("month").toISOString();
const endOfMonth = now.subtract(i, "month").endOf("month").toISOString();
const month = now.subtract(i, "month").format("MMMM");
let login = await strapi2.db.query(pluginUID$1).count({
where: {
createdAt: {
$gte: startOfMonth,
$lt: endOfMonth
},
action: { $containsi: "Logged" }
}
});
let register2 = await strapi2.db.query(pluginUID$1).count({
where: {
createdAt: {
$gte: startOfMonth,
$lt: endOfMonth
},
action: { $containsi: "Account created" }
}
});
data.push({ name: month, login, register: register2 });
}
}
ctx.body = { data };
},
/**
* Get the total number of GET, POST, PUT, DELETE, PATCH, "Logged in" & "Account created" requests over time based on the filterBy query parameter
*
* filterBy: `week` | `month`
*/
async mostAccessed(ctx) {
const { filterBy = "week" } = ctx.query;
const now = dayjs();
const data = [];
if (filterBy === "week") {
const start = now.endOf("day").toISOString();
const end = now.subtract(7, "day").startOf("day").toISOString();
const createdFilter = { createdAt: { $gte: end, $lt: start } };
let get = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, method: "GET" }
});
let post = await strapi2.db.query(pluginUID$1).count({
where: {
...createdFilter,
method: "POST",
$and: [{ action: { $notContains: "Logged" } }, { action: { $notContains: "Account created" } }]
}
});
let put = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, method: "PUT" }
});
let patch2 = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, method: "PATCH" }
});
let del = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, method: "DELETE" }
});
let login = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, action: { $containsi: "Logged" } }
});
let register2 = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, action: { $containsi: "Account created" } }
});
data.push(
{ name: "GET", total: get },
{ name: "POST", total: post },
{ name: "PUT", total: put },
{ name: "PATCH", total: patch2 },
{ name: "DELETE", total: del },
{ name: "Logged in", total: login },
{ name: "Account created", total: register2 }
);
} else if (filterBy === "month") {
const start = now.endOf("month").toISOString();
const end = now.subtract(7, "month").startOf("month").toISOString();
const createdFilter = { createdAt: { $gte: end, $lt: start } };
let get = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, method: "GET" }
});
let post = await strapi2.db.query(pluginUID$1).count({
where: {
...createdFilter,
method: "POST",
$and: [{ action: { $notContains: "Logged" } }, { action: { $notContains: "Account created" } }]
}
});
let put = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, method: "PUT" }
});
let patch2 = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, method: "PATCH" }
});
let del = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, method: "DELETE" }
});
let login = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, action: { $containsi: "Logged" } }
});
let register2 = await strapi2.db.query(pluginUID$1).count({
where: { ...createdFilter, action: { $containsi: "Account created" } }
});
data.push(
{ name: "GET", total: get },
{ name: "POST", total: post },
{ name: "PUT", total: put },
{ name: "PATCH", total: patch2 },
{ name: "DELETE", total: del },
{ name: "Logged in", total: login },
{ name: "Account created", total: register2 }
);
}
ctx.body = { data };
}
});
const controllers = {
logz: controller
};
const destroy = ({ strapi: strapi2 }) => {
};
const middleware = async (ctx, next) => {
await next();
const apiPrefix = strapi.config.get("api.rest.prefix", "/api");
if (ctx.request.url.startsWith(apiPrefix)) {
await strapi.plugin(config.pluginName).service(config.pluginName).create();
}
};
const middlewares = {
requestLogged: middleware
};
const policies = {};
const register = ({ strapi: strapi2 }) => {
strapi2.server.use(middlewares.requestLogged);
};
const routes = {
// The admin only routes
admin: {
type: "admin",
routes: [
{
method: "GET",
path: "/download",
handler: "logz.download",
config: { auth: false }
},
{
method: "GET",
path: "/dashboard-totals",
handler: "logz.dashboardTotals",
config: { auth: false }
},
{
method: "GET",
path: "/requests-over-time",
handler: "logz.requestOverTime",
config: { auth: false }
},
{
method: "GET",
path: "/login-vs-register",
handler: "logz.loginVsRegister",
config: { auth: false }
},
{
method: "GET",
path: "/most-accessed",
handler: "logz.mostAccessed",
config: { auth: false }
}
]
},
// The content api routes
"content-api": {
type: "content-api",
routes: [
{
method: "GET",
path: "/download",
handler: "logz.download"
},
{
method: "GET",
path: "/",
handler: "logz.find"
},
{
method: "GET",
path: "/dashboard-totals",
handler: "logz.dashboardTotals"
},
{
method: "GET",
path: "/requests-over-time",
handler: "logz.requestOverTime"
},
{
method: "GET",
path: "/login-vs-register",
handler: "logz.loginVsRegister"
},
{
method: "GET",
path: "/most-accessed",
handler: "logz.mostAccessed"
},
{
method: "GET",
path: "/:id",
handler: "logz.findOne"
}
]
}
};
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
function getDefaultExportFromCjs(x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
}
var lodash = { exports: {} };
/**
* @license
* Lodash <https://lodash.com/>
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
lodash.exports;
(function(module, exports) {
(function() {
var undefined$1;
var VERSION = "4.17.21";
var LARGE_ARRAY_SIZE = 200;
var CORE_ERROR_TEXT = "Unsupported core-js use. Try https://npms.io/search?q=ponyfill.", FUNC_ERROR_TEXT = "Expected a function", INVALID_TEMPL_VAR_ERROR_TEXT = "Invalid `variable` option passed into `_.template`";
var HASH_UNDEFINED = "__lodash_hash_undefined__";
var MAX_MEMOIZE_SIZE = 500;
var PLACEHOLDER = "__lodash_placeholder__";
var CLONE_DEEP_FLAG = 1, CLONE_FLAT_FLAG = 2, CLONE_SYMBOLS_FLAG = 4;
var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2;
var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_BOUND_FLAG = 4, WRAP_CURRY_FLAG = 8, WRAP_CURRY_RIGHT_FLAG = 16, WRAP_PARTIAL_FLAG = 32, WRAP_PARTIAL_RIGHT_FLAG = 64, WRAP_ARY_FLAG = 128, WRAP_REARG_FLAG = 256, WRAP_FLIP_FLAG = 512;
var DEFAULT_TRUNC_LENGTH = 30, DEFAULT_TRUNC_OMISSION = "...";
var HOT_COUNT = 800, HOT_SPAN = 16;
var LAZY_FILTER_FLAG = 1, LAZY_MAP_FLAG = 2, LAZY_WHILE_FLAG = 3;
var INFINITY2 = 1 / 0, MAX_SAFE_INTEGER = 9007199254740991, MAX_INTEGER = 17976931348623157e292, NAN = 0 / 0;
var MAX_ARRAY_LENGTH = 4294967295, MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
var wrapFlags = [
["ary", WRAP_ARY_FLAG],
["bind", WRAP_BIND_FLAG],
["bindKey", WRAP_BIND_KEY_FLAG],
["curry", WRAP_CURRY_FLAG],
["curryRight", WRAP_CURRY_RIGHT_FLAG],
["flip", WRAP_FLIP_FLAG],
["partial", WRAP_PARTIAL_FLAG],
["partialRight", WRAP_PARTIAL_RIGHT_FLAG],
["rearg", WRAP_REARG_FLAG]
];
var argsTag = "[object Arguments]", arrayTag = "[object Array]", asyncTag = "[object AsyncFunction]", boolTag = "[object Boolean]", dateTag = "[object Date]", domExcTag = "[object DOMException]", errorTag = "[object Error]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", mapTag = "[object Map]", numberTag = "[object Number]", nullTag = "[object Null]", objectTag = "[object Object]", promiseTag = "[object Promise]", proxyTag = "[object Proxy]", regexpTag = "[object RegExp]", setTag = "[object Set]", stringTag = "[object String]", symbolTag2 = "[object Symbol]", undefinedTag = "[object Undefined]", weakMapTag = "[object WeakMap]", weakSetTag = "[object WeakSet]";
var arrayBufferTag = "[object ArrayBuffer]", dataViewTag = "[object DataView]", float32Tag = "[object Float32Array]", float64Tag = "[object Float64Array]", int8Tag = "[object Int8Array]", int16Tag = "[object Int16Array]", int32Tag = "[object Int32Array]", uint8Tag = "[object Uint8Array]", uint8ClampedTag = "[object Uint8ClampedArray]", uint16Tag = "[object Uint16Array]", uint32Tag = "[object Uint32Array]";
var reEmptyStringLeading = /\b__p \+= '';/g, reEmptyStringMiddle = /\b(__p \+=) '' \+/g, reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, reUnescapedHtml = /[&<>"']/g, reHasEscapedHtml = RegExp(reEscapedHtml.source), reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
var reEscape = /<%-([\s\S]+?)%>/g, reEvaluate = /<%([\s\S]+?)%>/g, reInterpolate = /<%=([\s\S]+?)%>/g;
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp = /^\w*$/, rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, reHasRegExpChar = RegExp(reRegExpChar.source);
var reTrimStart = /^\s+/;
var reWhitespace = /\s/;
var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, reSplitDetails = /,? & /;
var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
var reEscapeChar = /\\(\\)?/g;
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
var reFlags = /\w*$/;
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
var reIsBinary = /^0b[01]+$/i;
var reIsHostCtor = /^\[object .+?Constructor\]$/;
var reIsOctal = /^0o[0-7]+$/i;
var reIsUint = /^(?:0|[1-9]\d*)$/;
var reLatin2 = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
var reNoMatch = /($^)/;
var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
var rsAstralRange = "\\ud800-\\udfff", rsComboMarksRange2 = "\\u0300-\\u036f", reComboHalfMarksRange = "\\ufe20-\\ufe2f", rsComboSymbolsRange2 = "\\u20d0-\\u20ff", rsComboRange = rsComboMarksRange2 + reComboHalfMarksRange + rsComboSymbolsRange2, rsDingbatRange = "\\u2700-\\u27bf", rsLowerRange = "a-z\\xdf-\\xf6\\xf8-\\xff", rsMathOpRange = "\\xac\\xb1\\xd7\\xf7", rsNonCharRange = "\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf", rsPunctuationRange = "\\u2000-\\u206f", rsSpaceRange = " \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000", rsUpperRange = "A-Z\\xc0-\\xd6\\xd8-\\xde", rsVarRange = "\\ufe0e\\ufe0f", rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
var rsApos = "['’]", rsAstral = "[" + rsAstralRange + "]", rsBreak = "[" + rsBreakRange + "]", rsCombo2 = "[" + rsComboRange + "]", rsDigits = "\\d+", rsDingbat = "[" + rsDingbatRange + "]", rsLower = "[" + rsLowerRange + "]", rsMisc = "[^" + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + "]", rsFitz = "\\ud83c[\\udffb-\\udfff]", rsModifier = "(?:" + rsCombo2 + "|" + rsFitz + ")", rsNonAstral = "[^" + rsAstralRange + "]", rsRegional = "(?:\\ud83c[\\udde6-\\uddff]){2}", rsSurrPair = "[\\ud800-\\udbff][\\udc00-\\udfff]", rsUpper = "[" + rsUpperRange + "]", rsZWJ = "\\u200d";
var rsMiscLower = "(?:" + rsLower + "|" + rsMisc + ")", rsMiscUpper = "(?:" + rsUpper + "|" + rsMisc + ")", rsOptContrLower = "(?:" + rsApos + "(?:d|ll|m|re|s|t|ve))?", rsOptContrUpper = "(?:" + rsApos + "(?:D|LL|M|RE|S|T|VE))?", reOptMod = rsModifier + "?", rsOptVar = "[" + rsVarRange + "]?", rsOptJoin = "(?:" + rsZWJ + "(?:" + [rsNonAstral, rsRegional, rsSurrPair].join("|") + ")" + rsOptVar + reOptMod + ")*", rsOrdLower = "\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])", rsOrdUpper = "\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])", rsSeq = rsOptVar + reOptMod + rsOptJoin, rsEmoji = "(?:" + [rsDingbat, rsRegional, rsSurrPair].join("|") + ")" + rsSeq, rsSymbol = "(?:" + [rsNonAstral + rsCombo2 + "?", rsCombo2, rsRegional, rsSurrPair, rsAstral].join("|") + ")";
var reApos = RegExp(rsApos, "g");
var reComboMark2 = RegExp(rsCombo2, "g");
var reUnicode = RegExp(rsFitz + "(?=" + rsFitz + ")|" + rsSymbol + rsSeq, "g");
var reUnicodeWord = RegExp([
rsUpper + "?" + rsLower + "+" + rsOptContrLower + "(?=" + [rsBreak, rsUpper, "$"].join("|") + ")",
rsMiscUpper + "+" + rsOptContrUpper + "(?=" + [rsBreak, rsUpper + rsMiscLower, "$"].join("|") + ")",
rsUpper + "?" + rsMiscLower + "+" + rsOptContrLower,
rsUpper + "+" + rsOptContrUpper,
rsOrdUpper,
rsOrdLower,
rsDigits,
rsEmoji
].join("|"), "g");
var reHasUnicode = RegExp("[" + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + "]");
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
var contextProps = [
"Array",
"Buffer",
"DataView",
"Date",
"Error",
"Float32Array",
"Float64Array",
"Function",
"Int8Array",
"Int16Array",
"Int32Array",
"Map",
"Math",
"Object",
"Promise",
"RegExp",
"Set",
"String",
"Symbol",
"TypeError",
"Uint8Array",
"Uint8ClampedArray",
"Uint16Array",
"Uint32Array",
"WeakMap",
"_",
"clearTimeout",
"isFinite",
"parseInt",
"setTimeout"
];
var templateCounter = -1;
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var cloneableTags = {};
cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = cloneableTags[boolTag] = cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[mapTag] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[regexpTag] = cloneableTags[setTag] = cloneableTags[stringTag] = cloneableTags[symbolTag2] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false;
var deburredLetters2 = {
// Latin-1 Supplement block.
"À": "A",
"Á": "A",
"Â": "A",
"Ã": "A",
"Ä": "A",
"Å": "A",
"à": "a",
"á": "a",
"â": "a",
"ã": "a",
"ä": "a",
"å": "a",
"Ç": "C",
"ç": "c",
"Ð": "D",
"ð": "d",
"È": "E",
"É": "E",
"Ê": "E",
"Ë": "E",
"è": "e",
"é": "e",
"ê": "e",
"ë": "e",
"Ì": "I",
"Í": "I",
"Î": "I",
"Ï": "I",
"ì": "i",
"í": "i",
"î": "i",
"ï": "i",
"Ñ": "N",
"ñ": "n",
"Ò": "O",
"Ó": "O",
"Ô": "O",
"Õ": "O",
"Ö": "O",
"Ø": "O",
"ò": "o",
"ó": "o",
"ô": "o",
"õ": "o",
"ö": "o",
"ø": "o",
"Ù": "U",
"Ú": "U",
"Û": "U",
"Ü": "U",
"ù": "u",
"ú": "u",
"û": "u",
"ü": "u",
"Ý": "Y",
"ý": "y",
"ÿ": "y",
"Æ": "Ae",
"æ": "ae",
"Þ": "Th",
"þ": "th",
"ß": "ss",
// Latin Extended-A block.
"Ā": "A",
"Ă": "A",
"Ą": "A",
"ā": "a",
"ă": "a",
"ą": "a",
"Ć": "C",
"Ĉ": "C",
"Ċ": "C",
"Č": "C",
"ć": "c",
"ĉ": "c",
"ċ": "c",
"č": "c",
"Ď": "D",
"Đ": "D",
"ď": "d",
"đ": "d",
"Ē": "E",
"Ĕ": "E",
"Ė": "E",
"Ę": "E",
"Ě": "E",
"ē": "e",
"ĕ": "e",
"ė": "e",
"ę": "e",
"ě": "e",
"Ĝ": "G",
"Ğ": "G",
"Ġ": "G",
"Ģ": "G",
"ĝ": "g",
"ğ": "g",
"ġ": "g",
"ģ": "g",
"Ĥ": "H",
"Ħ": "H",
"ĥ": "h",
"ħ": "h",
"Ĩ": "I",
"Ī": "I",
"Ĭ": "I",
"Į": "I",
"İ": "I",
"ĩ": "i",
"ī": "i",
"ĭ": "i",
"į": "i",
"ı": "i",
"Ĵ": "J",
"ĵ": "j",
"Ķ": "K",
"ķ": "k",
"ĸ": "k",
"Ĺ": "L",
"Ļ": "L",
"Ľ": "L",
"Ŀ": "L",
"Ł": "L",
"ĺ": "l",
"ļ": "l",
"ľ": "l",
"ŀ": "l",
"ł": "l",
"Ń": "N",
"Ņ": "N",
"Ň": "N",
"Ŋ": "N",
"ń": "n",
"ņ": "n",
"ň": "n",
"ŋ": "n",
"Ō": "O",
"Ŏ": "O",
"Ő": "O",
"ō": "o",
"ŏ": "o",
"ő": "o",
"Ŕ": "R",
"Ŗ": "R",
"Ř": "R",
"ŕ": "r",
"ŗ": "r",
"ř": "r",
"Ś": "S",
"Ŝ": "S",
"Ş": "S",
"Š": "S",
"ś": "s",
"ŝ": "s",
"ş": "s",
"š": "s",
"Ţ": "T",
"Ť": "T",
"Ŧ": "T",
"ţ": "t",
"ť": "t",
"ŧ": "t",
"Ũ": "U",
"Ū": "U",
"Ŭ": "U",
"Ů": "U",
"Ű": "U",
"Ų": "U",
"ũ": "u",
"ū": "u",
"ŭ": "u",
"ů": "u",
"ű": "u",
"ų": "u",
"Ŵ": "W",
"ŵ": "w",
"Ŷ": "Y",
"ŷ": "y",
"Ÿ": "Y",
"Ź": "Z",
"Ż": "Z",
"Ž": "Z",
"ź": "z",
"ż": "z",
"ž": "z",
"IJ": "IJ",
"ij": "ij",
"Œ": "Oe",
"œ": "oe",
"ʼn": "'n",
"ſ": "s"
};
var htmlEscapes = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'"
};
var htmlUnescapes = {
"&": "&",
"<": "<",
">": ">",
""": '"',
"'": "'"
};
var stringEscapes = {
"\\": "\\",
"'": "'",
"\n": "n",
"\r": "r",
"\u2028": "u2028",
"\u2029": "u2029"
};
var freeParseFloat = parseFloat, freeParseInt = parseInt;
var freeGlobal2 = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
var freeSelf2 = typeof self == "object" && self && self.Object === Object && self;
var root2 = freeGlobal2 || freeSelf2 || Function("return this")();
var freeExports = exports && !exports.nodeType && exports;
var freeModule = freeExports && true && module && !module.nodeType && module;
var moduleExports = freeModule && freeModule.exports === freeExports;
var freeProcess = moduleExports && freeGlobal2.process;
var nodeUtil = function() {
try {
var types = freeModule && freeModule.require && freeModule.require("util").types;
if (types) {
return types;
}
return freeProcess && freeProcess.binding && freeProcess.binding("util");
} catch (e) {
}
}();
var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, nodeIsDate = nodeUtil && nodeUtil.isDate, nodeIsMap = nodeUtil && nodeUtil.isMap, nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, nodeIsSet = nodeUtil && nodeUtil.isSet, nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
function apply(func, thisArg, args) {
switch (args.length) {
case 0:
return func.call(thisArg);
case 1:
return func.call(thisArg, args[0]);
case 2:
return func.call(thisArg, args[0], args[1]);
case 3:
return func.call(thisArg, args[0], args[1], args[2]);
}
return func.apply(thisArg, args);
}
function arrayAggregator(array, setter, iteratee, accumulator) {
var index2 = -1, length = array == null ? 0 : array.length;
while (++index2 < length) {
var value = array[index2];
setter(accumulator, value, iteratee(value), array);
}
return accumulator;
}
function arrayEach(array, iteratee) {
var index2 = -1, length = array == null ? 0 : array.length;
while (++index2 < length) {
if (iteratee(array[index2], index2, array) === false) {
break;
}
}
return array;
}
function arrayEachRight(array, iteratee) {
var length = array == null ? 0 : array.length;
while (length--) {
if (iteratee(array[length], length, array) === false) {
break;
}
}
return array;
}
function arrayEvery(array, predicate) {
var index2 = -1, length = array == null ? 0 : array.length;
while (++index2 < length) {
if (!predicate(array[index2], index2, array)) {
return false;
}
}
return true;
}
function arrayFilter(array, predicate) {
var index2 = -1, length = array == null ? 0 : array.length, resIndex = 0, result = [];
while (++index2 < length) {
var value = array[index2];
if (predicate(value, index2, array)) {
result[resIndex++] = value;
}
}
return result;
}
function arrayIncludes(array, value) {
var length = array == null ? 0 : array.length;
return !!length && baseIndexOf(array, value, 0) > -1;
}
function arrayIncludesWith(array, value, comparator) {
var index2 = -1, length = array == null ? 0 : array.length;
while (++index2 < length) {
if (comparator(value, array[index2])) {
return true;
}
}
return false;
}
function arrayMap(array, iteratee) {
var index2 = -1, length = array == null ? 0 : array.length, result = Array(length);
while (++index2 < length) {
result[index2] = iteratee(array[index2], index2, array);
}
return result;
}
function arrayPush(array, values) {
var index2 = -1, length = values.length, offset = array.length;
while (++index2 < length) {
array[offset + index2] = values[index2];
}
return array;
}
function arrayReduce(array, iteratee, accumulator, initAccum) {
var index2 = -1, length = array == null ? 0 : array.length;
if (initAccum && length) {
accumulator = array[++index2];
}
while (++index2 < length) {
accumulator = iteratee(accumulator, array[index2], index2, array);
}
return accumulator;
}
function arrayReduceRight(array, iteratee, accumulator, initAccum) {
var length = array == null ? 0 : array.length;
if (initAccum && length) {
accumulator = array[--length];
}
while (length--) {
accumulator = iteratee(accumulator, array[length], length, array);
}
return accumulator;
}
function arraySome(array, predicate) {
var index2 = -1, length = array == null ? 0 : array.length;
while (++index2 < length) {
if (predicate(array[index2], index2, array)) {
return true;
}
}
return false;
}
var asciiSize = baseProperty("length");
function asciiToArray(string) {
return string.split("");
}
function asciiWords(string) {
return string.match(reAsciiWord) || [];
}
function baseFindKey(collection, predicate, eachFunc) {
var result;
eachFunc(collection, function(value, key, collection2) {
if (predicate(value, key, collection2)) {
result = key;
return false;
}
});
return result;
}
function baseFindIndex(array, predicate, fromIndex, fromRight) {
var length = array.length, index2 = fromIndex + (fromRight ? 1 : -1);
while (fromRight ? index2-- : ++index2 < length) {
if (predicate(array[index2], index2, array)) {
return index2;
}
}
return -1;
}
function baseIndexOf(array, value, fromIndex) {
return value === value ? strictIndexOf(array, value, fromIndex) : baseFindIndex(array, baseIsNaN, fromIndex);
}
function baseIndexOfWith(array, value, fromIndex, comparator) {
var index2 = fromIndex - 1, length = array.length;
while (++index2 < length) {
if (comparator(array[index2], value)) {
return index2;
}
}
return -1;
}
function baseIsNaN(value) {
return value !== value;
}
function baseMean(array, iteratee) {
var length = array == null ? 0 : array.length;
return length ? baseSum(array, iteratee) / length : NAN;
}
function baseProperty(key) {
return function(object) {
return object == null ? undefined$1 : object[key];
};
}
function basePropertyOf2(object) {
return function(key) {
return object == null ? undefined$1 : object[key];
};
}
function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
eachFunc(collection, function(value, index2, collection2) {
accumulator = initAccum ? (initAccum = false, value) : iteratee(accumulator, value, index2, collection2);
});
return accumulator;
}
function baseSortBy(array, comparer) {
var length = array.length;
array.sort(comparer);
while (length--) {
array[length] = array[length].value;
}
return array;
}
function baseSum(array, iteratee) {
var result, index2 = -1, length = array.length;
while (++index2 < length) {
var current = iteratee(array[index2]);
if (current !== undefined$1) {
result = result === undefined$1 ? current : result + current;
}
}
return result;
}
function baseTimes(n, iteratee) {
var index2 = -1, result = Array(n);
while (++index2 < n) {
result[index2] = iteratee(index2);
}
return result;
}
function baseToPairs(object, props) {
return arrayMap(props, function(key) {
return [key, object[key]];
});
}
function baseTrim(string) {
return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, "") : string;
}
function baseUnary(func) {
return function(value) {
return func(value);
};
}
function baseValues(object, props) {
return arrayMap(props, function(key) {
return object[key];
});
}
function cacheHas(cache, key) {
return cache.has(key);
}
function charsStartIndex(strSymbols, chrSymbols) {
var index2 = -1, length = strSymbols.length;
while (++index2 < length && baseIndexOf(chrSymbols, strSymbols[index2], 0) > -1) {
}
return index2;
}
function charsEndIndex(strSymbols, chrSymbols) {
var index2 = strSymbols.length;
while (index2-- && baseIndexOf(chrSymbols, strSymbols[index2], 0) > -1) {
}
return index2;
}
function countHolders(array, placeholder2) {
var length = array.length, result = 0;
while (length--) {
if (array[length] === placeholder2) {
++result;
}
}
return result;
}
var deburrLetter2 = basePropertyOf2(deburredLetters2);
var escapeHtmlChar = basePropertyOf2(htmlEscapes);
function escapeStringChar(chr) {
return "\\" + stringEscapes[chr];
}
function getValue(object, key) {
return object == null ? undefined$1 : object[key];
}
function hasUnicode(string) {
return reHasUnicode.test(string);
}
function hasUnicodeWord(string) {
return reHasUnicodeWord.test(string);
}
function iteratorToArray(iterator) {
var data, result = [];
while (!(data = iterator.next()).done) {
result.push(data.value);
}
return result;
}
function mapToArray(map2) {
var index2 = -1, result = Array(map2.size);
map2.forEach(function(value, key) {
result[++index2] = [key, value];
});
return result;
}
function overArg(func, transform2) {
return function(arg) {
return func(transform2(arg));
};
}
function replaceHolders(array, placeholder2) {
var index2 = -1, length = array.length, resIndex = 0, result = [];
while (++index2 < length) {
var value = array[index2];
if (value === placeholder2 || value === PLACEHOLDER) {
array[index2] = PLACEHOLDER;
result[resIndex++] = index2;
}
}
return result;
}
function setToArray(set2) {
var index2 = -1, result = Array(set2.size);
set2.forEach(function(value) {
result[++index2] = value;
});
return result;
}
function setToPairs(set2) {
var index2 = -1, result = Array(set2.size);
set2.forEach(function(value) {
result[++index2] = [value, value];
});
return result;
}
function strictIndexOf(array, value, fromIndex) {
var index2 = fromIndex - 1, length = array.length;
while (++index2 < length) {
if (array[index2] === value) {
return index2;
}
}
return -1;
}
function strictLastIndexOf(array, value, fromIndex) {
var index2 = fromIndex + 1;
while (index2--) {
if (array[index2] === value) {
return index2;
}
}
return index2;
}
function stringSize(string) {
return hasUnicode(string) ? unicodeSize(string) : asciiSize(string);
}
function stringToArray(string) {
return hasUnicode(string) ? unicodeToArray(string) : asciiToArray(string);
}
function trimmedEndIndex(string) {
var index2 = string.length;
while (index2-- && reWhitespace.test(string.charAt(index2))) {
}
return index2;
}
var unescapeHtmlChar = basePropertyOf2(htmlUnescapes);
function unicodeSize(string) {
var result = reUnicode.lastIndex = 0;
while (reUnicode.test(string)) {
++result;
}
return result;
}
function unicodeToArray(string) {
return string.match(reUnicode) || [];
}
function unicodeWords(string) {
return string.match(reUnicodeWord) || [];
}
var runInContext = function runInContext2(context) {
context = context == null ? root2 : _2.defaults(root2.Object(), context, _2.pick(root2, contextProps));
var Array2 = context.Array, Date2 = context.Date, Error2 = context.Error, Function2 = context.Function, Math2 = context.Math, Object2 = context.Object, RegExp2 = context.RegExp, String2 = context.String, TypeError2 = context.TypeError;
var arrayProto = Array2.prototype, funcProto = Function2.prototype, objectProto2 = Object2.prototype;
var coreJsData = context["__core-js_shared__"];
var funcToString = funcProto.toString;
var hasOwnProperty = objectProto2.hasOwnProperty;
var idCounter = 0;
var maskSrcKey = function() {
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || "");
return uid ? "Symbol(src)_1." + uid : "";
}();
var nativeObjectToString = objectProto2.toString;
var objectCtorString = funcToString.call(Object2);
var oldDash = root2._;
var reIsNative = RegExp2(
"^" + funcToString.call(hasOwnProperty).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"
);
var Buffer2 = moduleExports ? context.Buffer : undefined$1, Symbol2 = context.Symbol, Uint8Array = context.Uint8Array, allocUnsafe = Buffer2 ? Buffer2.allocUnsafe : undefined$1, getPrototype = overArg(Object2.getPrototypeOf, Object2), objectCreate = Object2.create, propertyIsEnumerable = objectProto2.propertyIsEnumerable, splice = arrayProto.splice, spreadableSymbol = Symbol2 ? Symbol2.isConcatSpreadable : undefined$1, symIterator = Symbol2 ? Symbol2.iterator : undefined$1, symToStringTag = Symbol2 ? Symbol2.toStringTag : undefined$1;
var defineProperty = function() {
try {
var func = getNative(Object2, "defineProperty");
func({}, "", {});
return func;
} catch (e) {
}
}();
var ctxClearTimeout = context.clearTimeout !== root2.clearTimeout && context.clearTimeout, ctxNow = Date2 && Date2.now !== root2.Date.now && Date2.now, ctxSetTimeout = context.setTimeout !== root2.setTimeout && context.setTimeout;
var nativeCeil = Math2.ceil, nativeFloor = Math2.floor, nativeGetSymbols = Object2.getOwnPropertySymbols, nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : undefined$1, nativeIsFinite = context.isFinite, nativeJoin = arrayProto.join, nativeKeys = overArg(Object2.keys, Object2), nativeMax = Math2.max, nativeMin = Math2.min, nativeNow = Date2.now, nativeParseInt = context.parseInt, nativeRandom = Math2.random, nativeReverse = arrayProto.reverse;
var DataView = getNative(context, "DataView"), Map2 = getNative(context, "Map"), Promise2 = getNative(context, "Promise"), Set2 = getNative(context, "Set"), WeakMap2 = getNative(context, "WeakMap"), nativeCreate = getNative(Object2, "create");
var metaMap = WeakMap2 && new WeakMap2();
var realNames = {};
var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map2), promiseCtorString = toSource(Promise2), setCtorString = toSource(Set2), weakMapCtorString = toSource(WeakMap2);
var symbolProto2 = Symbol2 ? Symbol2.prototype : undefined$1, symbolValueOf = symbolProto2 ? symbolProto2.valueOf : undefined$1, symbolToString2 = symbolProto2 ? symbolProto2.toString : undefined$1;
function lodash2(value) {
if (isObjectLike2(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
if (value instanceof LodashWrapper) {
return value;
}
if (hasOwnProperty.call(value, "__wrapped__")) {
return wrapperClone(value);
}
}
return new LodashWrapper(value);
}
var baseCreate = /* @__PURE__ */ function() {
function object() {
}
return function(proto) {
if (!isObject2(proto)) {
return {};
}
if (objectCreate) {
return objectCreate(proto);
}
object.prototype = proto;
var result2 = new object();
object.prototype = undefined$1;
return result2;
};
}();
function baseLodash() {
}
function LodashWrapper(value, chainAll) {
this.__wrapped__ = value;
this.__actions__ = [];
this.__chain__ = !!chainAll;
this.__index__ = 0;
this.__values__ = undefined$1;
}
lodash2.templateSettings = {
/**
* Used to detect `data` property values to be HTML-escaped.
*
* @memberOf _.templateSettings
* @type {RegExp}
*/
"escape": reEscape,
/**
* Used to detect code to be evaluated.
*
* @memberOf _.templateSettings
* @type {RegExp}
*/
"evaluate": reEvaluate,
/**
* Used to detect `data` property values to inject.
*
* @memberOf _.templateSettings
* @type {RegExp}
*/
"interpolate": reInterpolate,
/**
* Used to reference the data object in the template text.
*
* @memberOf _.templateSettings
* @type {string}
*/
"variable": "",
/**
* Used to import variables into the compiled template.
*
* @memberOf _.templateSettings
* @type {Object}
*/
"imports": {
/**
* A reference to the `lodash` function.
*
* @memberOf _.templateSettings.imports
* @type {Function}
*/
"_": lodash2
}
};
lodash2.prototype = baseLodash.prototype;
lodash2.prototype.constructor = lodash2;
LodashWrapper.prototype = baseCreate(baseLodash.prototype);
LodashWrapper.prototype.constructor = LodashWrapper;
function LazyWrapper(value) {
this.__wrapped__ = value;
this.__actions__ = [];
this.__dir__ = 1;
this.__filtered__ = false;
this.__iteratees__ = [];
this.__takeCount__ = MAX_ARRAY_LENGTH;
this.__views__ = [];
}
function lazyClone() {
var result2 = new LazyWrapper(this.__wrapped__);
result2.__actions__ = copyArray(this.__actions__);
result2.__dir__ = this.__dir__;
result2.__filtered__ = this.__filtered__;
result2.__iteratees__ = copyArray(this.__iteratees__);
result2.__takeCount__ = this.__takeCount__;
result2.__views__ = copyArray(this.__views__);
return result2;
}
function lazyReverse() {
if (this.__filtered__) {
var result2 = new LazyWrapper(this);
result2.__dir__ = -1;
result2.__filtered__ = true;
} else {
result2 = this.clone();
result2.__dir__ *= -1;
}
return result2;
}
function lazyValue() {
var array = this.__wrapped__.value(), dir = this.__dir__, isArr = isArray(array), isRight = dir < 0, arrLength = isArr ? array.length : 0, view = getView(0, arrLength, this.__views__), start = view.start, end = view.end, length = end - start, index2 = isRight ? end : start - 1, iteratees = this.__iteratees__, iterLength = iteratees.length, resIndex = 0, takeCount = nativeMin(length, this.__takeCount__);
if (!isArr || !isRight && arrLength == length && takeCount == length) {
return baseWrapperValue(array, this.__actions__);
}
var result2 = [];
outer:
while (length-- && resIndex < takeCount) {
index2 += dir;
var iterIndex = -1, value = array[index2];
while (++iterIndex < iterLength) {
var data = iteratees[iterIndex], iteratee2 = data.iteratee, type2 = data.type, computed = iteratee2(value);
if (type2 == LAZY_MAP_FLAG) {
value = computed;
} else if (!computed) {
if (type2 == LAZY_FILTER_FLAG) {
continue outer;
} else {
break outer;
}
}
}
result2[resIndex++] = value;
}
return result2;
}
LazyWrapper.prototype = baseCreate(baseLodash.prototype);
LazyWrapper.prototype.constructor = LazyWrapper;
function Hash(entries) {
var index2 = -1, length = entries == null ? 0 : entries.length;
this.clear();
while (++index2 < length) {
var entry = entries[index2];
this.set(entry[0], entry[1]);
}
}
f