diff --git a/packages/builder/package.json b/packages/builder/package.json
index f3c5171364..478ec2be25 100644
--- a/packages/builder/package.json
+++ b/packages/builder/package.json
@@ -33,7 +33,6 @@
},
"dependencies": {
"@nx-js/compiler-util": "^2.0.0",
- "budibase-core": "file:../core/dist",
"date-fns": "^1.29.0",
"feather-icons": "^4.21.0",
"flatpickr": "^4.5.7",
diff --git a/packages/builder/rollup.config.js b/packages/builder/rollup.config.js
index 1bed877de9..58278d37d6 100644
--- a/packages/builder/rollup.config.js
+++ b/packages/builder/rollup.config.js
@@ -9,6 +9,7 @@ import nodeglobals from 'rollup-plugin-node-globals';
import copy from 'rollup-plugin-copy';
import browsersync from "rollup-plugin-browsersync";
import proxy from "http-proxy-middleware";
+import corePackageJson from "../core/package.json";
const target = 'http://localhost:4001/_builder';
const _builderProxy = proxy('/_builder', {
@@ -41,6 +42,12 @@ const lodash_exports = ["toNumber", "flow", "isArray", "join", "replace", "trim"
const outputpath = "../server/builder";
+const coreExternal = [
+ "lodash", "lodash/fp", "date-fns",
+ "lunr", "safe-buffer", "shortid",
+ "@nx-js/compiler-util"
+];
+
const globals = {
"lodash/fp": "fp",
lodash: "_",
@@ -56,14 +63,14 @@ export default {
sourcemap: true,
format: 'iife',
name: 'app',
- file: `${outputpath}/bundle.js`,
- globals
+ file: `${outputpath}/bundle.js`
+ //globals
},
- external: [
+ /*external: [
"lodash", "lodash/fp", "date-fns",
"lunr", "safe-buffer", "shortid",
"@nx-js/compiler-util"
- ],
+ ],*/
plugins: [
copy({
targets: [
@@ -85,7 +92,11 @@ export default {
resolve({
browser: true,
- dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/')
+ dedupe: importee => {
+ return importee === 'svelte'
+ || importee.startsWith('svelte/')
+ || coreExternal.includes(importee);
+ }
}),
commonjs({
@@ -93,8 +104,7 @@ export default {
"lodash/fp": lodash_fp_exports,
"lodash":lodash_exports,
"shortid": ["generate"]
- },
- include: /node_modules/
+ }
}),
url({
limit: 0,
diff --git a/packages/builder/src/builderStore/store.js b/packages/builder/src/builderStore/store.js
index f51c28ff4f..7e5dfdd6f3 100644
--- a/packages/builder/src/builderStore/store.js
+++ b/packages/builder/src/builderStore/store.js
@@ -1,7 +1,7 @@
import {
hierarchy as hierarchyFunctions,
common
-} from "budibase-core";
+} from "../../../core/src";
import {
filter,
cloneDeep,
diff --git a/packages/builder/src/common/core.js b/packages/builder/src/common/core.js
index bbbbd030e2..c04ed3211c 100644
--- a/packages/builder/src/common/core.js
+++ b/packages/builder/src/common/core.js
@@ -1,5 +1,5 @@
import {hierarchy as hierarchyFunctions,
- common, getTemplateApi, getAuthApi } from "budibase-core";
+ common, getTemplateApi, getAuthApi } from "../../../core/src";
import {find, filter, includes, keyBy, some,
flatten, map} from "lodash/fp";
diff --git a/packages/builder/src/database/DatabaseRoot.svelte b/packages/builder/src/database/DatabaseRoot.svelte
index cd7fcbd802..bcfd7c2e76 100644
--- a/packages/builder/src/database/DatabaseRoot.svelte
+++ b/packages/builder/src/database/DatabaseRoot.svelte
@@ -7,7 +7,7 @@ import ActionsHeader from "./ActionsHeader.svelte";
import {database} from "../builderStore";
import getIcon from "../common/icon";
import DropdownButton from "../common/DropdownButton.svelte";
-import {hierarchy as hierarchyFunctions} from "budibase-core";
+import {hierarchy as hierarchyFunctions} from "../../../core/src";
const hierarchyWidth = "200px";
diff --git a/packages/builder/src/database/IndexView.svelte b/packages/builder/src/database/IndexView.svelte
index c1f5bfd7a0..8635c8c056 100644
--- a/packages/builder/src/database/IndexView.svelte
+++ b/packages/builder/src/database/IndexView.svelte
@@ -6,7 +6,7 @@ import Button from "../common/Button.svelte";
import Dropdown from "../common/Dropdown.svelte";
import {database} from "../builderStore";
import {filter, some, map} from "lodash/fp";
-import {hierarchy as hierarchyFunctions, common} from "budibase-core";
+import {hierarchy as hierarchyFunctions, common} from "../../../core/src";
const chain = common.$;
diff --git a/packages/builder/src/database/RecordView.svelte b/packages/builder/src/database/RecordView.svelte
index ea3be006cb..33751fc147 100644
--- a/packages/builder/src/database/RecordView.svelte
+++ b/packages/builder/src/database/RecordView.svelte
@@ -8,7 +8,7 @@ import Modal from "../common/Modal.svelte";
import {map, join, filter, some,
find, keys, isDate} from "lodash/fp";
import { database } from "../builderStore";
-import {common, hierarchy as h} from "budibase-core";
+import {common, hierarchy as h} from "../../../core/src";
import {templateApi, chain, validate} from "../common/core";
let record;
diff --git a/packages/builder/src/userInterface/pagesParsing/searchComponents.js b/packages/builder/src/userInterface/pagesParsing/searchComponents.js
index e61be6122b..3f7b7e8fe6 100644
--- a/packages/builder/src/userInterface/pagesParsing/searchComponents.js
+++ b/packages/builder/src/userInterface/pagesParsing/searchComponents.js
@@ -8,7 +8,7 @@ import {
import {
common
-} from "budibase-core";
+} from "../../../../core/src";
const pipe = common.$;
diff --git a/packages/builder/src/userInterface/pagesParsing/validatePages.js b/packages/builder/src/userInterface/pagesParsing/validatePages.js
index 7d48c58b6c..a831357784 100644
--- a/packages/builder/src/userInterface/pagesParsing/validatePages.js
+++ b/packages/builder/src/userInterface/pagesParsing/validatePages.js
@@ -7,7 +7,7 @@ import {
map,
filter
} from "lodash/fp";
-import { common } from "budibase-core";
+import { common } from "../../../../core/src";
const pipe = common.$;
export const validatePage = (page, getComponent) => {
diff --git a/packages/builder/src/userInterface/pagesParsing/validateProps.js b/packages/builder/src/userInterface/pagesParsing/validateProps.js
index dedfd17ca8..6ea2f166b6 100644
--- a/packages/builder/src/userInterface/pagesParsing/validateProps.js
+++ b/packages/builder/src/userInterface/pagesParsing/validateProps.js
@@ -10,7 +10,7 @@ import {
flattenDeep,
each,
indexOf } from "lodash/fp";
-import { common } from "budibase-core";
+import { common } from "../../../../core/src";
const pipe = common.$;
diff --git a/packages/server/builder/bundle.css b/packages/server/builder/bundle.css
index e6731c813b..d8bb743193 100644
--- a/packages/server/builder/bundle.css
+++ b/packages/server/builder/bundle.css
@@ -1,30 +1,30 @@
main.svelte-j8mzr7{height:100%;width:100%;font-family:"Lato", Helvetica, Arial, sans-serif}
-.root.svelte-jymnqv{position:fixed;margin:0 auto;text-align:center;top:20%;width:100%}.inner.svelte-jymnqv{display:inline-block;margin:auto}.logo.svelte-jymnqv{width:300px;margin-bottom:40px}.root.svelte-jymnqv .option{width:250px}.app-link.svelte-jymnqv{margin-top:10px;display:block}
.root.svelte-1rxbdcd{height:100%}.content.svelte-1rxbdcd{position:fixed;height:100%;background-color:var(--white);margin:0}
+.root.svelte-jymnqv{position:fixed;margin:0 auto;text-align:center;top:20%;width:100%}.inner.svelte-jymnqv{display:inline-block;margin:auto}.logo.svelte-jymnqv{width:300px;margin-bottom:40px}.root.svelte-jymnqv .option{width:250px}.app-link.svelte-jymnqv{margin-top:10px;display:block}
+.root.svelte-1bhe8g7{display:grid;grid-template-columns:[uiNav] 200px [preview] auto;height:100%}.ui-nav.svelte-1bhe8g7{grid-column-start:uiNav}.component-preview.svelte-1bhe8g7{grid-column-start:preview}
+.root.svelte-1y6dy5x{padding:10px}
h4.svelte-o0id5a{margin-top:20px}
+.root.svelte-z7gm0t{display:flex;height:100%;position:relative}.hierarchy.svelte-z7gm0t{flex:0 1 auto;background-color:var(--primary10);overflow-y:auto;height:100%}.node-container.svelte-z7gm0t{flex:1 1 auto;display:flex;flex-direction:column}.actions-header.svelte-z7gm0t{flex:0 1 auto}.node-view.svelte-z7gm0t{overflow-y:auto;flex:1 1 auto}.hierarchy-title-row.svelte-z7gm0t{padding:15px 7px;font-size:11pt;display:flex;font-weight:bold}.hierarchy-title.svelte-z7gm0t{flex:auto 1 1}
.border-normal.svelte-7rfkdx{border-radius:var(--borderradiusall)}.border-left.svelte-7rfkdx{border-radius:var(--borderradius) 0 0 var(--borderradius)}.border-right.svelte-7rfkdx{border-radius:0 var(--borderradius) var(--borderradius) 0}.border-middle.svelte-7rfkdx{border-radius:0}button.svelte-7rfkdx{border-style:solid;padding:7px 15px;cursor:pointer}.primary.svelte-7rfkdx{background-color:var(--primary100);border-color:var(--primary100);color:var(--white)}.primary.svelte-7rfkdx:hover{background-color:var(--primary75);border-color:var(--primary75)}.primary.svelte-7rfkdx:active{background-color:var(--primarydark);border-color:var(--primarydark)}.primary-outline.svelte-7rfkdx{background-color:var(--white);border-color:var(--primary100);color:var(--primary100)}.primary-outline.svelte-7rfkdx:hover{background-color:var(--primary10)}.primary-outline.svelte-7rfkdx:pressed{background-color:var(--primary25)}.secondary.svelte-7rfkdx{background-color:var(--secondary100);border-color:var(--secondary100);color:var(--white)}.secondary.svelte-7rfkdx:hover{background-color:var(--secondary75);border-color:var(--secondary75)}.secondary.svelte-7rfkdx:pressed{background-color:var(--secondarydark);border-color:var(--secondarydark)}.secondary-outline.svelte-7rfkdx{background-color:var(--white);border-color:var(--secondary100);color:var(--secondary100)}.secondary-outline.svelte-7rfkdx:hover{background-color:var(--secondary10)}.secondary-outline.svelte-7rfkdx:pressed{background-color:var(--secondary25)}.success.svelte-7rfkdx{background-color:var(--success100);border-color:var(--success100);color:var(--white)}.success.svelte-7rfkdx:hover{background-color:var(--success75);border-color:var(--success75)}.success.svelte-7rfkdx:pressed{background-color:var(--successdark);border-color:var(--successdark)}.success-outline.svelte-7rfkdx{background-color:var(--white);border-color:var(--success100);color:var(--success100)}.success-outline.svelte-7rfkdx:hover{background-color:var(--success10)}.success-outline.svelte-7rfkdx:pressed{background-color:var(--success25)}.deletion.svelte-7rfkdx{background-color:var(--deletion100);border-color:var(--deletion100);color:var(--white)}.deletion.svelte-7rfkdx:hover{background-color:var(--deletion75);border-color:var(--deletion75)}.deletion.svelte-7rfkdx:pressed{background-color:var(--deletiondark);border-color:var(--deletiondark)}.deletion-outline.svelte-7rfkdx{background-color:var(--white);border-color:var(--deletion100);color:var(--deletion100)}.deletion-outline.svelte-7rfkdx:hover{background-color:var(--deletion10)}.deletion-outline.svelte-7rfkdx:pressed{background-color:var(--deletion25)}
.nav.svelte-n1ql72{height:100%;position:fixed;left:0px;background-color:var(--secondary100);color:var(--darkslate)}.nav.svelte-n1ql72>img.svelte-n1ql72{width:100%;margin-bottom:30px;margin-top:5px;margin-left:0px}
-.root.svelte-z7gm0t{display:flex;height:100%;position:relative}.hierarchy.svelte-z7gm0t{flex:0 1 auto;background-color:var(--primary10);overflow-y:auto;height:100%}.node-container.svelte-z7gm0t{flex:1 1 auto;display:flex;flex-direction:column}.actions-header.svelte-z7gm0t{flex:0 1 auto}.node-view.svelte-z7gm0t{overflow-y:auto;flex:1 1 auto}.hierarchy-title-row.svelte-z7gm0t{padding:15px 7px;font-size:11pt;display:flex;font-weight:bold}.hierarchy-title.svelte-z7gm0t{flex:auto 1 1}
-.root.svelte-1bhe8g7{display:grid;grid-template-columns:[uiNav] 200px [preview] auto;height:100%}.ui-nav.svelte-1bhe8g7{grid-column-start:uiNav}.component-preview.svelte-1bhe8g7{grid-column-start:preview}
.root.svelte-1be865r{padding:10px}.edit-button.svelte-1be865r{cursor:pointer;color:var(--white)}tr.svelte-1be865r:hover .edit-button.svelte-1be865r{color:var(--secondary75)}
-.root.svelte-1y6dy5x{padding:10px}
-.nav-item.svelte-td9xyr{padding:0px 5px;display:block;padding:10px;color:var(--slate);cursor:pointer}.inner.svelte-td9xyr{padding:0px 20px 10px 0px;display:inline-block;width:100%}.nav-item.svelte-td9xyr:hover{background-color:var(--primary25)}.icon.svelte-td9xyr{font-size:0.9em;display:inline-block;position:relative;top:5px;margin-right:5px;width:100%}.active.svelte-td9xyr>div.svelte-td9xyr{background-color:var(--primary10);color:var(--secondary100)}.active.svelte-td9xyr>div.svelte-td9xyr:hover{background-color:var(--slate);color:var(--secondary100)}.active.svelte-td9xyr{background-color:white}
+.edit-button.svelte-1le5bpl{cursor:pointer;color:var(--white)}tr.svelte-1le5bpl:hover .edit-button.svelte-1le5bpl{color:var(--secondary75)}
+.root.svelte-d6wwkb{display:flex}.root.svelte-d6wwkb:last-child{border-radius:0 var(--borderradius) var(--borderradius) 0}.root.svelte-d6wwkb:first-child{border-radius:var(--borderradius) 0 0 var(--borderradius)}.root.svelte-d6wwkb:not(:first-child):not(:last-child){border-radius:0}
+.edit-button.svelte-12jzg4k{cursor:pointer;color:var(--white)}tr.svelte-12jzg4k:hover .edit-button.svelte-12jzg4k{color:var(--secondary75)}
.root.svelte-1rctf7f{display:block;font-size:13pt;width:100%;cursor:pointer}.title.svelte-1rctf7f{font:var(--bodytext);padding-top:10px;padding-right:5px;padding-bottom:10px;color:var(--secondary100)}.title.svelte-1rctf7f:hover{background-color:var(--secondary10)}
-.root.svelte-1fkfoam{height:100%;padding:15px}.allowed-records.svelte-1fkfoam{margin:20px 0px}.allowed-records.svelte-1fkfoam>span.svelte-1fkfoam{margin-right:30px}
.root.svelte-160njkp{padding:5px;top:0;width:100%}
.root.svelte-gq7l8x{height:100%;padding:15px}.fields-table.svelte-gq7l8x{margin:10px;border-collapse:collapse}.add-field-button.svelte-gq7l8x{margin-left:15px;cursor:pointer}.edit-button.svelte-gq7l8x{cursor:pointer;color:var(--white)}.edit-button.svelte-gq7l8x:hover{color:var(--secondary75)}th.svelte-gq7l8x{text-align:left}td.svelte-gq7l8x{padding:5px 30px 5px 0px;margin:0}thead.svelte-gq7l8x>tr.svelte-gq7l8x{border-width:0px 0px 1px 0px;border-style:solid;border-color:var(--secondary75);margin-bottom:20px}tbody.svelte-gq7l8x>tr.svelte-gq7l8x{border-width:0px 0px 1px 0px;border-style:solid;border-color:var(--primary10)}tbody.svelte-gq7l8x>tr.svelte-gq7l8x:hover{background-color:var(--primary10)}tbody.svelte-gq7l8x>tr:hover .edit-button.svelte-gq7l8x{color:var(--secondary75)}.index-container.svelte-gq7l8x{border-style:solid;border-width:0 0 1px 0;border-color:var(--secondary25);padding:10px;margin-bottom:5px}.index-label.svelte-gq7l8x{color:var(--slate)}.index-name.svelte-gq7l8x{font-weight:bold;color:var(--primary100)}.index-container.svelte-gq7l8x code.svelte-gq7l8x{margin:0;display:inline;background-color:var(--primary10);color:var(--secondary100);padding:3px}.index-field-row.svelte-gq7l8x{margin-top:7px}
+.root.svelte-1fkfoam{height:100%;padding:15px}.allowed-records.svelte-1fkfoam{margin:20px 0px}.allowed-records.svelte-1fkfoam>span.svelte-1fkfoam{margin-right:30px}
.dropdown-background.svelte-179p8ge{position:fixed;top:0;left:0;width:100vw;height:100vh}.root.svelte-179p8ge{cursor:pointer;z-index:1}.dropdown-content.svelte-179p8ge{position:absolute;background-color:var(--white);min-width:160px;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);z-index:1;font-weight:normal;border-style:solid;border-width:1px;border-color:var(--secondary10)}.dropdown-content.svelte-179p8ge:not(:focus){display:none}.action-row.svelte-179p8ge{padding:7px 10px;cursor:pointer}.action-row.svelte-179p8ge:hover{background-color:var(--primary100);color:var(--white)}
-.edit-button.svelte-12jzg4k{cursor:pointer;color:var(--white)}tr.svelte-12jzg4k:hover .edit-button.svelte-12jzg4k{color:var(--secondary75)}
-.root.svelte-d6wwkb{display:flex}.root.svelte-d6wwkb:last-child{border-radius:0 var(--borderradius) var(--borderradius) 0}.root.svelte-d6wwkb:first-child{border-radius:var(--borderradius) 0 0 var(--borderradius)}.root.svelte-d6wwkb:not(:first-child):not(:last-child){border-radius:0}
-.edit-button.svelte-1le5bpl{cursor:pointer;color:var(--white)}tr.svelte-1le5bpl:hover .edit-button.svelte-1le5bpl{color:var(--secondary75)}
-textarea.svelte-1ooq0hh{padding:3px;background:var(--darkslate);color:var(--white);font-family:'Courier New', Courier, monospace;width:95%;height:100px}
-.container.svelte-bm0783{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-bm0783{grid-column-start:label;align-self:center}.control.svelte-bm0783{grid-column-start:control;align-self:center;margin:0}select.svelte-bm0783{width:300px}
+.nav-item.svelte-td9xyr{padding:0px 5px;display:block;padding:10px;color:var(--slate);cursor:pointer}.inner.svelte-td9xyr{padding:0px 20px 10px 0px;display:inline-block;width:100%}.nav-item.svelte-td9xyr:hover{background-color:var(--primary25)}.icon.svelte-td9xyr{font-size:0.9em;display:inline-block;position:relative;top:5px;margin-right:5px;width:100%}.active.svelte-td9xyr>div.svelte-td9xyr{background-color:var(--primary10);color:var(--secondary100)}.active.svelte-td9xyr>div.svelte-td9xyr:hover{background-color:var(--slate);color:var(--secondary100)}.active.svelte-td9xyr{background-color:white}
+.root.svelte-emcy8y{padding:10px}.option-container.svelte-emcy8y{border-style:dotted;border-width:1px;border-color:var(--primary75);padding:3px;margin-right:5px}
.container.svelte-umifqh{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-umifqh{grid-column-start:label;align-self:center}.control.svelte-umifqh{grid-column-start:control;align-self:center;margin:0}input.svelte-umifqh{width:300px}
.error-container.svelte-jwy920{padding:10px;border-style:solid;border-color:var(--deletion100);border-radius:var(--borderradiusall);background:var(--deletion75)}.error-row.svelte-jwy920{padding:5px 0px}
+textarea.svelte-1ooq0hh{padding:3px;background:var(--darkslate);color:var(--white);font-family:'Courier New', Courier, monospace;width:95%;height:100px}
+.container.svelte-bm0783{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-bm0783{grid-column-start:label;align-self:center}.control.svelte-bm0783{grid-column-start:control;align-self:center;margin:0}select.svelte-bm0783{width:300px}
input.svelte-66516k{margin-right:7px}
-.root.svelte-emcy8y{padding:10px}.option-container.svelte-emcy8y{border-style:dotted;border-width:1px;border-color:var(--primary75);padding:3px;margin-right:5px}
.container.svelte-85b8gk{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-85b8gk{grid-column-start:label;align-self:center}.control.svelte-85b8gk{grid-column-start:control;align-self:center;margin:0}textarea.svelte-85b8gk{width:300px;height:200px}
-.container.svelte-umifqh{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-umifqh{grid-column-start:label;align-self:center}.control.svelte-umifqh{grid-column-start:control;align-self:center;margin:0}input.svelte-umifqh{width:300px}
.container.svelte-1pf9x5k{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-1pf9x5k{grid-column-start:label;align-self:center}.control.svelte-1pf9x5k{grid-column-start:control;align-self:center;margin:0}input.svelte-1pf9x5k{width:300px}
+.container.svelte-umifqh{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-umifqh{grid-column-start:label;align-self:center}.control.svelte-umifqh{grid-column-start:control;align-self:center;margin:0}input.svelte-umifqh{width:300px}
/*# sourceMappingURL=bundle.css.map */
\ No newline at end of file
diff --git a/packages/server/builder/bundle.css.map b/packages/server/builder/bundle.css.map
index b63a5bb96e..cf48ed5064 100644
--- a/packages/server/builder/bundle.css.map
+++ b/packages/server/builder/bundle.css.map
@@ -3,64 +3,64 @@
"file": "bundle.css",
"sources": [
"..\\..\\builder\\src\\App.svelte",
- "..\\..\\builder\\src\\NoPackage.svelte",
"..\\..\\builder\\src\\PackageRoot.svelte",
+ "..\\..\\builder\\src\\NoPackage.svelte",
+ "..\\..\\builder\\src\\userInterface\\UserInterfaceRoot.svelte",
+ "..\\..\\builder\\src\\actionsAndTriggers\\ActionsAndTriggersRoot.svelte",
"..\\..\\builder\\src\\common\\ComingSoon.svelte",
+ "..\\..\\builder\\src\\database\\DatabaseRoot.svelte",
"..\\..\\builder\\src\\common\\Button.svelte",
"..\\..\\builder\\src\\nav\\Nav.svelte",
- "..\\..\\builder\\src\\database\\DatabaseRoot.svelte",
- "..\\..\\builder\\src\\userInterface\\UserInterfaceRoot.svelte",
"..\\..\\builder\\src\\accessLevels\\AccessLevelsRoot.svelte",
- "..\\..\\builder\\src\\actionsAndTriggers\\ActionsAndTriggersRoot.svelte",
- "..\\..\\builder\\src\\nav\\NavItem.svelte",
+ "..\\..\\builder\\src\\actionsAndTriggers\\Triggers.svelte",
+ "..\\..\\builder\\src\\common\\ButtonGroup.svelte",
+ "..\\..\\builder\\src\\actionsAndTriggers\\Actions.svelte",
"..\\..\\builder\\src\\database\\HierarchyRow.svelte",
- "..\\..\\builder\\src\\database\\IndexView.svelte",
"..\\..\\builder\\src\\database\\ActionsHeader.svelte",
"..\\..\\builder\\src\\database\\RecordView.svelte",
+ "..\\..\\builder\\src\\database\\IndexView.svelte",
"..\\..\\builder\\src\\common\\DropdownButton.svelte",
- "..\\..\\builder\\src\\actionsAndTriggers\\Actions.svelte",
- "..\\..\\builder\\src\\common\\ButtonGroup.svelte",
- "..\\..\\builder\\src\\actionsAndTriggers\\Triggers.svelte",
- "..\\..\\builder\\src\\common\\CodeArea.svelte",
- "..\\..\\builder\\src\\common\\Dropdown.svelte",
+ "..\\..\\builder\\src\\nav\\NavItem.svelte",
+ "..\\..\\builder\\src\\actionsAndTriggers\\ActionView.svelte",
"..\\..\\builder\\src\\common\\Textbox.svelte",
"..\\..\\builder\\src\\common\\ErrorsBox.svelte",
+ "..\\..\\builder\\src\\common\\CodeArea.svelte",
+ "..\\..\\builder\\src\\common\\Dropdown.svelte",
"..\\..\\builder\\src\\common\\Checkbox.svelte",
- "..\\..\\builder\\src\\actionsAndTriggers\\ActionView.svelte",
"..\\..\\builder\\src\\common\\ValuesList.svelte",
- "..\\..\\builder\\src\\common\\NumberBox.svelte",
- "..\\..\\builder\\src\\common\\DatePicker.svelte"
+ "..\\..\\builder\\src\\common\\DatePicker.svelte",
+ "..\\..\\builder\\src\\common\\NumberBox.svelte"
],
"sourcesContent": [
"\n\nloading
\n\n\t{:then result}\n\t\t{#if $database.hasAppPackage}\n\t\t{err}
\n\t{/await}\n
Name | \r\nPermissions | \r\n\r\n |
---|---|---|
{level.name} | \r\n{getPermissionsString(level.permissions)} | \r\n\r\n onLevelEdit(level)}>{@html getIcon(\"edit\")}\r\n onLevelDelete(level)}>{@html getIcon(\"trash\")}\r\n | \r\n
Name | \r\nType | \r\nOptions | \r\n\r\n |
---|---|---|---|
\r\n {field.label} \r\n {field.name} \r\n | \r\n {field.type} | \r\n{@html getTypeOptions(field.typeOptions)} | \r\n\r\n | \r\n \r\n \r\n
{index.map}
\r\n {index.filter}
\r\n Description | \r\nBehaviour Source | \r\nBehaviour Name | \r\nDefault Options | \r\n\r\n |
---|---|---|---|---|
{action.name} | \r\n{action.behaviourSource} | \r\n{action.behaviourName} | \r\n{@html getDefaultOptionsHtml(action.initialOptions)} | \r\n\r\n onActionEdit(action)}>{@html getIcon(\"edit\")}\r\n onActionDelete(action)}>{@html getIcon(\"trash\")}\r\n | \r\n
Event | \r\nAction | \r\nCondition | \r\nCreate Options | \r\n\r\n |
---|---|---|---|---|
{trigger.eventName} | \r\n{trigger.actionName} | \r\n{trigger.condition} | \r\n{trigger.optionsCreator} | \r\n\r\n onTriggerEdit(trigger)}>{@html getIcon(\"edit\")}\r\n onTriggerDelete(trigger)}>{@html getIcon(\"trash\")}\r\n | \r\n
Description | \r\nBehaviour Source | \r\nBehaviour Name | \r\nDefault Options | \r\n\r\n |
---|---|---|---|---|
{action.name} | \r\n{action.behaviourSource} | \r\n{action.behaviourName} | \r\n{@html getDefaultOptionsHtml(action.initialOptions)} | \r\n\r\n onActionEdit(action)}>{@html getIcon(\"edit\")}\r\n onActionDelete(action)}>{@html getIcon(\"trash\")}\r\n | \r\n
Name | \r\nType | \r\nOptions | \r\n\r\n |
---|---|---|---|
\r\n {field.label} \r\n {field.name} \r\n | \r\n {field.type} | \r\n{@html getTypeOptions(field.typeOptions)} | \r\n\r\n | \r\n \r\n \r\n
{index.map}
\r\n {index.filter}
\r\n ' + func(text) + '
'; + * }); + * + * p('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles
' + */ + function wrap(value, wrapper) { + return partial(castFunction(wrapper), value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + return baseClone(value, CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined`, + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @see _.cloneDeepWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ + function cloneWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @see _.cloneWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ + function cloneDeepWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); + } + + /** + * Checks if `object` conforms to `source` by invoking the predicate + * properties of `source` with the corresponding property values of `object`. + * + * **Note:** This method is equivalent to `_.conforms` when `source` is + * partially applied. + * + * @static + * @memberOf _ + * @since 4.14.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); + * // => true + * + * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); + * // => false + */ + function conformsTo(object, source) { + return source == null || baseConformsTo(object, source, keys(source)); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + * @see _.lt + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + var gt = createRelationalOperation(baseGt); + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to + * `other`, else `false`. + * @see _.lte + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + var gte = createRelationalOperation(function(value, other) { + return value >= other; + }); + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ + var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; + + /** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); + } + + /** + * Checks if `value` is an empty object, collection, map, or set. + * + * Objects are considered empty if they have no own enumerable string keyed + * properties. + * + * Array-like values such as `arguments` objects, arrays, buffers, strings, or + * jQuery-like collections are considered empty if they have a `length` of `0`. + * Similarly, maps and sets are considered empty if they have a `size` of `0`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && + (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || + isBuffer(value) || isTypedArray(value) || isArguments(value))) { + return !value.length; + } + var tag = getTag(value); + if (tag == mapTag || tag == setTag) { + return !value.size; + } + if (isPrototype(value)) { + return !baseKeys(value).length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ + function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + var result = customizer ? customizer(value, other) : undefined$1; + return result === undefined$1 ? baseIsEqual(value, other, undefined$1, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + if (!isObjectLike(value)) { + return false; + } + var tag = baseGetTag(value); + return tag == errorTag || tag == domExcTag || + (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on + * [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MIN_VALUE); + * // => true + * + * _.isFinite(Infinity); + * // => false + * + * _.isFinite('3'); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** + * Checks if `value` is an integer. + * + * **Note:** This method is based on + * [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ + function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ + var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + + /** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. + * + * **Note:** This method is equivalent to `_.matches` when `source` is + * partially applied. + * + * Partial comparisons will match empty array and empty object `source` + * values against any array or object value, respectively. See `_.isEqual` + * for a list of supported value comparisons. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.isMatch(object, { 'b': 2 }); + * // => true + * + * _.isMatch(object, { 'b': 1 }); + * // => false + */ + function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); + } + + /** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ + function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return baseIsMatch(object, source, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a pristine native function. + * + * **Note:** This method can't reliably detect native functions in the presence + * of the core-js package because core-js circumvents this kind of detection. + * Despite multiple requests, the core-js maintainer has made it clear: any + * attempt to fix the detection will be obstructed. As a result, we're left + * with little choice but to throw an error. Unfortunately, this also affects + * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), + * which rely on core-js. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (isMaskable(value)) { + throw new Error(CORE_ERROR_TEXT); + } + return baseIsNative(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ + function isNil(value) { + return value == null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + + /** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on + * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ + function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ + var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined$1; + } + + /** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ + function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; + } + + /** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ + function isWeakSet(value) { + return isObjectLike(value) && baseGetTag(value) == weakSetTag; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + * @see _.gt + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + var lt = createRelationalOperation(baseLt); + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to + * `other`, else `false`. + * @see _.gte + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + var lte = createRelationalOperation(function(value, other) { + return value <= other; + }); + + /** + * Converts `value` to an array. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!value) { + return []; + } + if (isArrayLike(value)) { + return isString(value) ? stringToArray(value) : copyArray(value); + } + if (symIterator && value[symIterator]) { + return iteratorToArray(value[symIterator]()); + } + var tag = getTag(value), + func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); + + return func(value); + } + + /** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + + /** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ + function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; + } + + /** + * Converts `value` to an integer suitable for use as the length of an + * array-like object. + * + * **Note:** This method is based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toLength(3.2); + * // => 3 + * + * _.toLength(Number.MIN_VALUE); + * // => 0 + * + * _.toLength(Infinity); + * // => 4294967295 + * + * _.toLength('3.2'); + * // => 3 + */ + function toLength(value) { + return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * Converts `value` to a safe integer. A safe integer can be compared and + * represented correctly. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toSafeInteger(3.2); + * // => 3 + * + * _.toSafeInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toSafeInteger(Infinity); + * // => 9007199254740991 + * + * _.toSafeInteger('3.2'); + * // => 3 + */ + function toSafeInteger(value) { + return value + ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) + : (value === 0 ? value : 0); + } + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assign({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3 } + */ + var assign = createAssigner(function(object, source) { + if (isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } + }); + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assign + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assignIn({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } + */ + var assignIn = createAssigner(function(object, source) { + copyObject(source, keysIn(source), object); + }); + + /** + * This method is like `_.assignIn` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keysIn(source), object, customizer); + }); + + /** + * This method is like `_.assign` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignInWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keys(source), object, customizer); + }); + + /** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Array} Returns the picked values. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + */ + var at = flatRest(baseAt); + + /** + * Creates an object that inherits from the `prototype` object. If a + * `properties` object is given, its own enumerable string keyed properties + * are assigned to the created object. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties == null ? result : baseAssign(result, properties); + } + + /** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var defaults = baseRest(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined$1; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = keysIn(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined$1 || + (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; + }); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaults + * @example + * + * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); + * // => { 'a': { 'b': 2, 'c': 3 } } + */ + var defaultsDeep = baseRest(function(args) { + args.push(undefined$1, customDefaultsMerge); + return apply(mergeWith, undefined$1, args); + }); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); + } + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + function findLastKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); + } + + /** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ + function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, getIteratee(iteratee, 3), keysIn); + } + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forIn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. + */ + function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, getIteratee(iteratee, 3), keysIn); + } + + /** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forOwn(object, iteratee) { + return object && baseForOwn(object, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. + */ + function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, getIteratee(iteratee, 3)); + } + + /** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functionsIn + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ + function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); + } + + /** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functions + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ + function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined$1 : baseGet(object, path); + return result === undefined$1 ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return object != null && hasPath(object, path, baseHas); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite + * property assignments of previous values. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ + var invert = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + result[value] = key; + }, constant(identity)); + + /** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` thru `iteratee`. The + * corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Object + * @param {Object} object The object to invert. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ + var invertBy = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + }, getIteratee); + + /** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ + var invoke = baseRest(baseInvoke); + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * string keyed property of `object` thru `iteratee`. The iteratee is invoked + * with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapValues + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, iteratee(value, key, object), value); + }); + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined`, merging is handled by the + * method instead. The `customizer` is invoked with six arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { 'a': [1], 'b': [2] }; + * var other = { 'a': [3], 'b': [4] }; + * + * _.mergeWith(object, other, customizer); + * // => { 'a': [1, 3], 'b': [2, 4] } + */ + var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); + }); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable property paths of `object` that are not omitted. + * + * **Note:** This method is considerably slower than `_.pick`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to omit. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } + */ + var omit = flatRest(function(object, paths) { + var result = {}; + if (object == null) { + return result; + } + var isDeep = false; + paths = arrayMap(paths, function(path) { + path = castPath(path, object); + isDeep || (isDeep = path.length > 1); + return path; + }); + copyObject(object, getAllKeysIn(object), result); + if (isDeep) { + result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); + } + var length = paths.length; + while (length--) { + baseUnset(result, paths[length]); + } + return result; + }); + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + return pickBy(object, negate(getIteratee(predicate))); + } + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = flatRest(function(object, paths) { + return object == null ? {} : basePick(object, paths); + }); + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = getIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); + } + + /** + * This method is like `_.get` except that if the resolved value is a + * function it's invoked with the `this` binding of its parent object and + * its result is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + path = castPath(path, object); + + var index = -1, + length = path.length; + + // Ensure the loop is entered when path is empty. + if (!length) { + length = 1; + object = undefined$1; + } + while (++index < length) { + var value = object == null ? undefined$1 : object[toKey(path[index])]; + if (value === undefined$1) { + index = length; + value = defaultValue; + } + object = isFunction(value) ? value.call(object) : value; + } + return object; + } + + /** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, ['x', '0', 'y', 'z'], 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); + } + + /** + * This method is like `_.set` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.setWith(object, '[0][1]', 'a', Object); + * // => { '0': { '1': 'a' } } + */ + function setWith(object, path, value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return object == null ? object : baseSet(object, path, value, customizer); + } + + /** + * Creates an array of own enumerable string keyed-value pairs for `object` + * which can be consumed by `_.fromPairs`. If `object` is a map or set, its + * entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entries + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairs(new Foo); + * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) + */ + var toPairs = createToPairs(keys); + + /** + * Creates an array of own and inherited enumerable string keyed-value pairs + * for `object` which can be consumed by `_.fromPairs`. If `object` is a map + * or set, its entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entriesIn + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairsIn(new Foo); + * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) + */ + var toPairsIn = createToPairs(keysIn); + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable string keyed properties thru `iteratee`, with each invocation + * potentially mutating the `accumulator` object. If `accumulator` is not + * provided, a new object with the same `[[Prototype]]` will be used. The + * iteratee is invoked with four arguments: (accumulator, value, key, object). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }, []); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function transform(object, iteratee, accumulator) { + var isArr = isArray(object), + isArrLike = isArr || isBuffer(object) || isTypedArray(object); + + iteratee = getIteratee(iteratee, 4); + if (accumulator == null) { + var Ctor = object && object.constructor; + if (isArrLike) { + accumulator = isArr ? new Ctor : []; + } + else if (isObject(object)) { + accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; + } + else { + accumulator = {}; + } + } + (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Removes the property at `path` of `object`. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 7 } }] }; + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + * + * _.unset(object, ['a', '0', 'b', 'c']); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + */ + function unset(object, path) { + return object == null ? true : baseUnset(object, path); + } + + /** + * This method is like `_.set` except that accepts `updater` to produce the + * value to set. Use `_.updateWith` to customize `path` creation. The `updater` + * is invoked with one argument: (value). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.update(object, 'a[0].b.c', function(n) { return n * n; }); + * console.log(object.a[0].b.c); + * // => 9 + * + * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); + * console.log(object.x[0].y.z); + * // => 0 + */ + function update(object, path, updater) { + return object == null ? object : baseUpdate(object, path, castFunction(updater)); + } + + /** + * This method is like `_.update` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.updateWith(object, '[0][1]', _.constant('a'), Object); + * // => { '0': { '1': 'a' } } + */ + function updateWith(object, path, updater, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); + } + + /** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object == null ? [] : baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable string keyed property + * values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return object == null ? [] : baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ + function clamp(number, lower, upper) { + if (upper === undefined$1) { + upper = lower; + lower = undefined$1; + } + if (upper !== undefined$1) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined$1) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); + } + + /** + * Checks if `n` is between `start` and up to, but not including, `end`. If + * `end` is not specified, it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @since 3.3.0 + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @see _.range, _.rangeRight + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ + function inRange(number, start, end) { + start = toFinite(start); + if (end === undefined$1) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + number = toNumber(number); + return baseInRange(number, start, end); + } + + /** + * Produces a random number between the inclusive `lower` and `upper` bounds. + * If only one argument is provided a number between `0` and the given number + * is returned. If `floating` is `true`, or either `lower` or `upper` are + * floats, a floating-point number is returned instead of an integer. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Number + * @param {number} [lower=0] The lower bound. + * @param {number} [upper=1] The upper bound. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(lower, upper, floating) { + if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { + upper = floating = undefined$1; + } + if (floating === undefined$1) { + if (typeof upper == 'boolean') { + floating = upper; + upper = undefined$1; + } + else if (typeof lower == 'boolean') { + floating = lower; + lower = undefined$1; + } + } + if (lower === undefined$1 && upper === undefined$1) { + lower = 0; + upper = 1; + } + else { + lower = toFinite(lower); + if (upper === undefined$1) { + upper = lower; + lower = 0; + } else { + upper = toFinite(upper); + } + } + if (lower > upper) { + var temp = lower; + lower = upper; + upper = temp; + } + if (floating || lower % 1 || upper % 1) { + var rand = nativeRandom(); + return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); + } + return baseRandom(lower, upper); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar--'); + * // => 'fooBar' + * + * _.camelCase('__FOO_BAR__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); + }); + + /** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ + function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); + } + + /** + * Deburrs `string` by converting + * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) + * letters to basic Latin letters and removing + * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = toString(string); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search up to. + * @returns {boolean} Returns `true` if `string` ends with `target`, + * else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = toString(string); + target = baseToString(target); + + var length = string.length; + position = position === undefined$1 + ? length + : baseClamp(toInteger(position), 0, length); + + var end = position; + position -= target.length; + return position >= 0 && string.slice(position, end) == target; + } + + /** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ + function escapeRegExp(string) { + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; + } + + /** + * Converts `string` to + * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__FOO_BAR__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Converts `string`, as space separated words, to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the lower cased string. + * @example + * + * _.lowerCase('--Foo-Bar--'); + * // => 'foo bar' + * + * _.lowerCase('fooBar'); + * // => 'foo bar' + * + * _.lowerCase('__FOO_BAR__'); + * // => 'foo bar' + */ + var lowerCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + word.toLowerCase(); + }); + + /** + * Converts the first character of `string` to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.lowerFirst('Fred'); + * // => 'fred' + * + * _.lowerFirst('FRED'); + * // => 'fRED' + */ + var lowerFirst = createCaseFirst('toLowerCase'); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + if (!length || strLength >= length) { + return string; + } + var mid = (length - strLength) / 2; + return ( + createPadding(nativeFloor(mid), chars) + + string + + createPadding(nativeCeil(mid), chars) + ); + } + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padEnd('abc', 6); + * // => 'abc ' + * + * _.padEnd('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padEnd('abc', 3); + * // => 'abc' + */ + function padEnd(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + return (length && strLength < length) + ? (string + createPadding(length - strLength, chars)) + : string; + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padStart('abc', 6); + * // => ' abc' + * + * _.padStart('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padStart('abc', 3); + * // => 'abc' + */ + function padStart(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + return (length && strLength < length) + ? (createPadding(length - strLength, chars) + string) + : string; + } + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a + * hexadecimal, in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the + * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category String + * @param {string} string The string to convert. + * @param {number} [radix=10] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + if (guard || radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=1] The number of times to repeat the string. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n, guard) { + if ((guard ? isIterateeCall(string, n, guard) : n === undefined$1)) { + n = 1; + } else { + n = toInteger(n); + } + return baseRepeat(toString(string), n); + } + + /** + * Replaces matches for `pattern` in `string` with `replacement`. + * + * **Note:** This method is based on + * [`String#replace`](https://mdn.io/String/replace). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to modify. + * @param {RegExp|string} pattern The pattern to replace. + * @param {Function|string} replacement The match replacement. + * @returns {string} Returns the modified string. + * @example + * + * _.replace('Hi Fred', 'Fred', 'Barney'); + * // => 'Hi Barney' + */ + function replace() { + var args = arguments, + string = toString(args[0]); + + return args.length < 3 ? string : string.replace(args[1], args[2]); + } + + /** + * Converts `string` to + * [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--FOO-BAR--'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Splits `string` by `separator`. + * + * **Note:** This method is based on + * [`String#split`](https://mdn.io/String/split). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to split. + * @param {RegExp|string} separator The separator pattern to split by. + * @param {number} [limit] The length to truncate results to. + * @returns {Array} Returns the string segments. + * @example + * + * _.split('a-b-c', '-', 2); + * // => ['a', 'b'] + */ + function split(string, separator, limit) { + if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { + separator = limit = undefined$1; + } + limit = limit === undefined$1 ? MAX_ARRAY_LENGTH : limit >>> 0; + if (!limit) { + return []; + } + string = toString(string); + if (string && ( + typeof separator == 'string' || + (separator != null && !isRegExp(separator)) + )) { + separator = baseToString(separator); + if (!separator && hasUnicode(string)) { + return castSlice(stringToArray(string), 0, limit); + } + } + return string.split(separator, limit); + } + + /** + * Converts `string` to + * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @since 3.1.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar--'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__FOO_BAR__'); + * // => 'FOO BAR' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + upperFirst(word); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, + * else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = toString(string); + position = position == null + ? 0 + : baseClamp(toInteger(position), 0, string.length); + + target = baseToString(target); + return string.slice(position, position + target.length) == target; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is given, it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options={}] The options object. + * @param {RegExp} [options.escape=_.templateSettings.escape] + * The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] + * The "evaluate" delimiter. + * @param {Object} [options.imports=_.templateSettings.imports] + * An object to import into the template as free variables. + * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] + * The "interpolate" delimiter. + * @param {string} [options.sourceURL='lodash.templateSources[n]'] + * The sourceURL of the compiled template. + * @param {string} [options.variable='obj'] + * The data object variable name. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the compiled template function. + * @example + * + * // Use the "interpolate" delimiter to create a compiled template. + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // Use the HTML "escape" delimiter to escape data property values. + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': '\r\n\r\n\r\n\r\n","import { union, reduce, isUndefined, cloneDeep, split, some, map, filter, isEmpty as isEmpty$1, countBy, includes as includes$1, last, find, constant as constant$1, take, first, intersection, mapValues, isNull as isNull$1, has as has$1, isNumber as isNumber$1, isString as isString$1, isBoolean as isBoolean$1, isDate as isDate$1, isArray as isArray$2, isObject, clone, values, keyBy, keys as keys$1, orderBy, concat, reverse, difference, merge as merge$1, flatten, each, pull, join as join$2, max, defaultCase as defaultCase$1, uniqBy, every, uniqWith, isFunction as isFunction$1, groupBy, differenceBy, intersectionBy, isEqual } from 'lodash/fp';\nimport { generate } from 'shortid';\nimport _, { toNumber, flow, isArray as isArray$1, join as join$1, replace, trim, dropRight, head, takeRight, isUndefined as isUndefined$1, isNull, isNaN as isNaN$1, reduce as reduce$1, isEmpty, constant, tail, includes, startsWith, findIndex, isInteger, isDate, isString, split as split$1, cloneDeep as cloneDeep$1, keys, isFunction, merge, has, isBoolean, isNumber, isObjectLike, assign, some as some$1, each as each$1, find as find$1, orderBy as orderBy$1, union as union$1 } from 'lodash';\nimport { compileCode as compileCode$1, compileExpression as compileExpression$1 } from '@nx-js/compiler-util';\nimport lunr from 'lunr';\nimport { Buffer as Buffer$1 } from 'safe-buffer';\n\nconst commonPlus = extra => union(['onBegin', 'onComplete', 'onError'])(extra);\n\nconst common = () => commonPlus([]);\n\nconst _events = {\n recordApi: {\n save: commonPlus([\n 'onInvalid',\n 'onRecordUpdated',\n 'onRecordCreated']),\n delete: common(),\n getContext: common(),\n getNew: common(),\n load: common(),\n validate: common(),\n uploadFile: common(),\n downloadFile: common(),\n },\n indexApi: {\n buildIndex: common(),\n listItems: common(),\n delete: common(),\n aggregates: common(),\n },\n collectionApi: {\n getAllowedRecordTypes: common(),\n initialise: common(),\n delete: common(),\n },\n authApi: {\n authenticate: common(),\n authenticateTemporaryAccess: common(),\n createTemporaryAccess: common(),\n createUser: common(),\n enableUser: common(),\n disableUser: common(),\n loadAccessLevels: common(),\n getNewAccessLevel: common(),\n getNewUser: common(),\n getNewUserAuth: common(),\n getUsers: common(),\n saveAccessLevels: common(),\n isAuthorized: common(),\n changeMyPassword: common(),\n setPasswordFromTemporaryCode: common(),\n scorePassword: common(),\n isValidPassword: common(),\n validateUser: common(),\n validateAccessLevels: common(),\n setUserAccessLevels: common(),\n },\n templateApi: {\n saveApplicationHierarchy: common(),\n saveActionsAndTriggers: common(),\n },\n actionsApi: {\n execute: common(),\n },\n};\n\nconst _eventsList = [];\n\nconst makeEvent = (area, method, name) => `${area}:${method}:${name}`;\n\nfor (const areaKey in _events) {\n for (const methodKey in _events[areaKey]) {\n _events[areaKey][methodKey] = reduce((obj, s) => {\n obj[s] = makeEvent(areaKey, methodKey, s);\n return obj;\n },\n {})(_events[areaKey][methodKey]);\n }\n}\n\n\nfor (const areaKey in _events) {\n for (const methodKey in _events[areaKey]) {\n for (const name in _events[areaKey][methodKey]) {\n _eventsList.push(\n _events[areaKey][methodKey][name],\n );\n }\n }\n}\n\n\nconst events = _events;\n\nconst eventsList = _eventsList;\n\nclass BadRequestError extends Error {\n constructor(message) {\n super(message);\n this.httpStatusCode = 400;\n }\n}\n\nclass UnauthorisedError extends Error {\n constructor(message) {\n super(message);\n this.httpStatusCode = 401;\n }\n}\n\nclass ForbiddenError extends Error {\n constructor(message) {\n super(message);\n this.httpStatusCode = 403;\n }\n}\n\nclass NotFoundError extends Error {\n constructor(message) {\n super(message);\n this.httpStatusCode = 404;\n }\n}\n\nconst apiWrapper = async (app, eventNamespace, isAuthorized, eventContext, func, ...params) => {\n pushCallStack(app, eventNamespace);\n\n if (!isAuthorized(app)) {\n handleNotAuthorized(app, eventContext, eventNamespace);\n return;\n }\n\n const startDate = Date.now();\n const elapsed = () => (Date.now() - startDate);\n\n try {\n await app.publish(\n eventNamespace.onBegin,\n eventContext,\n );\n\n const result = await func(...params);\n\n await publishComplete(app, eventContext, eventNamespace, elapsed, result);\n return result;\n } catch (error) {\n await publishError(app, eventContext, eventNamespace, elapsed, error);\n throw error;\n }\n};\n\nconst apiWrapperSync = (app, eventNamespace, isAuthorized, eventContext, func, ...params) => {\n pushCallStack(app, eventNamespace);\n\n if (!isAuthorized(app)) {\n handleNotAuthorized(app, eventContext, eventNamespace);\n return;\n }\n\n const startDate = Date.now();\n const elapsed = () => (Date.now() - startDate);\n\n try {\n app.publish(\n eventNamespace.onBegin,\n eventContext,\n );\n\n const result = func(...params);\n\n publishComplete(app, eventContext, eventNamespace, elapsed, result);\n return result;\n } catch (error) {\n publishError(app, eventContext, eventNamespace, elapsed, error);\n throw error;\n }\n};\n\nconst handleNotAuthorized = (app, eventContext, eventNamespace) => {\n const err = new UnauthorisedError(`Unauthorized: ${eventNamespace}`);\n publishError(app, eventContext, eventNamespace, () => 0, err);\n throw err;\n};\n\nconst pushCallStack = (app, eventNamespace, seedCallId) => {\n const callId = generate();\n\n const createCallStack = () => ({\n seedCallId: !isUndefined(seedCallId)\n ? seedCallId\n : callId,\n threadCallId: callId,\n stack: [],\n });\n\n if (isUndefined(app.calls)) {\n app.calls = createCallStack();\n }\n\n app.calls.stack.push({\n namespace: eventNamespace,\n callId,\n });\n};\n\nconst popCallStack = (app) => {\n app.calls.stack.pop();\n if (app.calls.stack.length === 0) {\n delete app.calls;\n }\n};\n\nconst publishError = async (app, eventContext, eventNamespace, elapsed, err) => {\n const ctx = cloneDeep(eventContext);\n ctx.error = err;\n ctx.elapsed = elapsed();\n await app.publish(\n eventNamespace.onError,\n ctx,\n );\n popCallStack(app);\n};\n\nconst publishComplete = async (app, eventContext, eventNamespace, elapsed, result) => {\n const endcontext = cloneDeep(eventContext);\n endcontext.result = result;\n endcontext.elapsed = elapsed();\n await app.publish(\n eventNamespace.onComplete,\n endcontext,\n );\n popCallStack(app);\n return result;\n};\n\nconst lockOverlapMilliseconds = 10;\n\nconst getLock = async (app, lockFile, timeoutMilliseconds, maxLockRetries, retryCount = 0) => {\n try {\n const timeout = (await app.getEpochTime())\n + timeoutMilliseconds;\n\n const lock = {\n timeout,\n key: lockFile,\n totalTimeout: timeoutMilliseconds,\n };\n\n await app.datastore.createFile(\n lockFile,\n getLockFileContent(\n lock.totalTimeout,\n lock.timeout,\n ),\n );\n\n return lock;\n } catch (e) {\n if (retryCount == maxLockRetries) { return NO_LOCK; }\n\n const lock = parseLockFileContent(\n lockFile,\n await app.datastore.loadFile(lockFile),\n );\n\n const currentEpochTime = await app.getEpochTime();\n\n if (currentEpochTime < lock.timeout) {\n return NO_LOCK;\n }\n\n try {\n await app.datastore.deleteFile(lockFile);\n } catch (_) {\n //empty\n }\n\n await sleepForRetry();\n\n return await getLock(\n app, lockFile, timeoutMilliseconds,\n maxLockRetries, retryCount + 1,\n );\n }\n};\n\nconst getLockFileContent = (totalTimeout, epochTime) => `${totalTimeout}:${epochTime.toString()}`;\n\nconst parseLockFileContent = (key, content) => $(content, [\n split(':'),\n parts => ({\n totalTimeout: new Number(parts[0]),\n timeout: new Number(parts[1]),\n key,\n }),\n]);\n\nconst releaseLock = async (app, lock) => {\n const currentEpochTime = await app.getEpochTime();\n // only release if not timedout\n if (currentEpochTime < (lock.timeout - lockOverlapMilliseconds)) {\n try {\n await app.datastore.deleteFile(lock.key);\n } catch (_) {\n //empty\n }\n }\n};\n\nconst NO_LOCK = 'no lock';\nconst isNolock = id => id === NO_LOCK;\n\nconst sleepForRetry = () => new Promise(resolve => setTimeout(resolve, lockOverlapMilliseconds));\n\n// this is the combinator function\nconst $$ = (...funcs) => arg => flow(funcs)(arg);\n\n// this is the pipe function\nconst $ = (arg, funcs) => $$(...funcs)(arg);\n\nconst keySep = '/';\nconst trimKeySep = str => trim(str, keySep);\nconst splitByKeySep = str => split$1(str, keySep);\nconst safeKey = key => replace(`${keySep}${trimKeySep(key)}`, `${keySep}${keySep}`, keySep);\nconst joinKey = (...strs) => {\n const paramsOrArray = strs.length === 1 & isArray$1(strs[0])\n ? strs[0] : strs;\n return safeKey(join$1(paramsOrArray, keySep));\n};\nconst splitKey = $$(trimKeySep, splitByKeySep);\nconst getDirFomKey = $$(splitKey, dropRight, p => joinKey(...p));\nconst getFileFromKey = $$(splitKey, takeRight, head);\n\nconst configFolder = `${keySep}.config`;\nconst fieldDefinitions = joinKey(configFolder, 'fields.json');\nconst templateDefinitions = joinKey(configFolder, 'templates.json');\nconst appDefinitionFile = joinKey(configFolder, 'appDefinition.json');\nconst dirIndex = folderPath => joinKey(configFolder, 'dir', ...splitKey(folderPath), 'dir.idx');\nconst getIndexKeyFromFileKey = $$(getDirFomKey, dirIndex);\n\nconst ifExists = (val, exists, notExists) => (isUndefined$1(val)\n ? isUndefined$1(notExists) ? (() => { })() : notExists()\n : exists());\n\nconst getOrDefault = (val, defaultVal) => ifExists(val, () => val, () => defaultVal);\n\nconst not = func => val => !func(val);\nconst isDefined = not(isUndefined$1);\nconst isNonNull = not(isNull);\nconst isNotNaN = not(isNaN$1);\n\nconst allTrue = (...funcArgs) => val => reduce$1(funcArgs,\n (result, conditionFunc) => (isNull(result) || result == true) && conditionFunc(val),\n null);\n\nconst anyTrue = (...funcArgs) => val => reduce$1(funcArgs,\n (result, conditionFunc) => result == true || conditionFunc(val),\n null);\n\nconst insensitiveEquals = (str1, str2) => str1.trim().toLowerCase() === str2.trim().toLowerCase();\n\nconst isSomething = allTrue(isDefined, isNonNull, isNotNaN);\nconst isNothing = not(isSomething);\nconst isNothingOrEmpty = v => isNothing(v) || isEmpty(v);\nconst somethingOrGetDefault = getDefaultFunc => val => (isSomething(val) ? val : getDefaultFunc());\nconst somethingOrDefault = (val, defaultVal) => somethingOrGetDefault(constant(defaultVal))(val);\n\nconst mapIfSomethingOrDefault = (mapFunc, defaultVal) => val => (isSomething(val) ? mapFunc(val) : defaultVal);\n\nconst mapIfSomethingOrBlank = mapFunc => mapIfSomethingOrDefault(mapFunc, '');\n\nconst none = predicate => collection => !some(predicate)(collection);\n\nconst all = predicate => collection => none(v => !predicate(v))(collection);\n\nconst isNotEmpty = ob => !isEmpty(ob);\nconst isNonEmptyArray = allTrue(isArray$1, isNotEmpty);\nconst isNonEmptyString = allTrue(isString, isNotEmpty);\nconst tryOr = failFunc => (func, ...args) => {\n try {\n return func.apply(null, ...args);\n } catch (_) {\n return failFunc();\n }\n};\n\nconst tryAwaitOr = failFunc => async (func, ...args) => {\n try {\n return await func.apply(null, ...args);\n } catch (_) {\n return await failFunc();\n }\n};\n\nconst defineError = (func, errorPrefix) => {\n try {\n return func();\n } catch (err) {\n err.message = `${errorPrefix} : ${err.message}`;\n throw err;\n }\n};\n\nconst tryOrIgnore = tryOr(() => { });\nconst tryAwaitOrIgnore = tryAwaitOr(async () => { });\nconst causesException = (func) => {\n try {\n func();\n return false;\n } catch (e) {\n return true;\n }\n};\n\nconst executesWithoutException = func => !causesException(func);\n\nconst handleErrorWith = returnValInError => tryOr(constant(returnValInError));\n\nconst handleErrorWithUndefined = handleErrorWith(undefined);\n\nconst switchCase = (...cases) => (value) => {\n const nextCase = () => head(cases)[0](value);\n const nextResult = () => head(cases)[1](value);\n\n if (isEmpty(cases)) return; // undefined\n if (nextCase() === true) return nextResult();\n return switchCase(...tail(cases))(value);\n};\n\nconst isValue = val1 => val2 => (val1 === val2);\nconst isOneOf = (...vals) => val => includes(vals, val);\nconst defaultCase = constant(true);\nconst memberMatches = (member, match) => obj => match(obj[member]);\n\n\nconst StartsWith = searchFor => searchIn => startsWith(searchIn, searchFor);\n\nconst contains = val => array => (findIndex(array, v => v === val) > -1);\n\nconst getHashCode = (s) => {\n let hash = 0; let i; let char; let\n l;\n if (s.length == 0) return hash;\n for (i = 0, l = s.length; i < l; i++) {\n char = s.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash |= 0; // Convert to 32bit integer\n }\n\n // converting to string, but dont want a \"-\" prefixed\n if (hash < 0) { return `n${(hash * -1).toString()}`; }\n return hash.toString();\n};\n\n// thanks to https://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/\nconst awEx = async (promise) => {\n try {\n const result = await promise;\n return [undefined, result];\n } catch (error) {\n return [error, undefined];\n }\n};\n\nconst isSafeInteger = n => isInteger(n)\n && n <= Number.MAX_SAFE_INTEGER\n && n >= 0 - Number.MAX_SAFE_INTEGER;\n\nconst toDateOrNull = s => (isNull(s) ? null\n : isDate(s) ? s : new Date(s));\nconst toBoolOrNull = s => (isNull(s) ? null\n : s === 'true' || s === true);\nconst toNumberOrNull = s => (isNull(s) ? null\n : toNumber(s));\n\nconst isArrayOfString = opts => isArray$1(opts) && all(isString)(opts);\n\nconst pause = async duration => new Promise(res => setTimeout(res, duration));\n\nconst retry = async (fn, retries, delay, ...args) => {\n try {\n return await fn(...args);\n } catch (err) {\n if (retries > 1) {\n return await pause(delay).then(async () => await retry(fn, (retries - 1), delay, ...args));\n }\n throw err;\n }\n};\n\nvar index = {\n ifExists,\n getOrDefault,\n isDefined,\n isNonNull,\n isNotNaN,\n allTrue,\n isSomething,\n mapIfSomethingOrDefault,\n mapIfSomethingOrBlank,\n configFolder,\n fieldDefinitions,\n isNothing,\n not,\n switchCase,\n defaultCase,\n StartsWith,\n contains,\n templateDefinitions,\n handleErrorWith,\n handleErrorWithUndefined,\n tryOr,\n tryOrIgnore,\n tryAwaitOr,\n tryAwaitOrIgnore,\n dirIndex,\n keySep,\n $,\n $$,\n getDirFomKey,\n getFileFromKey,\n splitKey,\n somethingOrDefault,\n getIndexKeyFromFileKey,\n joinKey,\n somethingOrGetDefault,\n appDefinitionFile,\n isValue,\n all,\n isOneOf,\n memberMatches,\n defineError,\n anyTrue,\n isNonEmptyArray,\n causesException,\n executesWithoutException,\n none,\n getHashCode,\n awEx,\n apiWrapper,\n events,\n eventsList,\n isNothingOrEmpty,\n isSafeInteger,\n toNumber,\n toDate: toDateOrNull,\n toBool: toBoolOrNull,\n isArrayOfString,\n getLock,\n NO_LOCK,\n isNolock,\n insensitiveEquals,\n pause,\n retry,\n};\n\nconst stringNotEmpty = s => isSomething(s) && s.trim().length > 0;\n\nconst makerule = (field, error, isValid) => ({ field, error, isValid });\n\nconst validationError = (rule, item) => ({ ...rule, item });\n\nconst applyRuleSet = ruleSet => itemToValidate => $(ruleSet, [\n map(applyRule(itemToValidate)),\n filter(isSomething),\n]);\n\nconst applyRule = itemTovalidate => rule => (rule.isValid(itemTovalidate)\n ? null\n : validationError(rule, itemTovalidate));\n\nconst filterEval = 'FILTER_EVALUATE';\nconst filterCompile = 'FILTER_COMPILE';\nconst mapEval = 'MAP_EVALUATE';\nconst mapCompile = 'MAP_COMPILE';\n\n\nconst getEvaluateResult = () => ({\n isError: false,\n passedFilter: true,\n result: null,\n});\n\nconst compileFilter = index => compileExpression$1(index.filter);\n\nconst compileMap = index => compileCode$1(index.map);\n\nconst passesFilter = (record, index) => {\n const context = { record };\n if (!index.filter) return true;\n\n const compiledFilter = defineError(\n () => compileFilter(index),\n filterCompile,\n );\n\n return defineError(\n () => compiledFilter(context),\n filterEval,\n );\n};\n\nconst mapRecord = (record, index) => {\n const recordClone = cloneDeep$1(record);\n const context = { record: recordClone };\n\n const map = index.map ? index.map : 'return {...record};';\n\n const compiledMap = defineError(\n () => compileCode$1(map),\n mapCompile,\n );\n\n const mapped = defineError(\n () => compiledMap(context),\n mapEval,\n );\n\n const mappedKeys = keys(mapped);\n for (let i = 0; i < mappedKeys.length; i++) {\n const key = mappedKeys[i];\n mapped[key] = isUndefined$1(mapped[key]) ? null : mapped[key];\n if (isFunction(mapped[key])) {\n delete mapped[key];\n }\n }\n\n mapped.key = record.key;\n mapped.sortKey = index.getSortKey\n ? compileCode$1(index.getSortKey)(context)\n : record.id;\n\n return mapped;\n};\n\nconst evaluate = record => (index) => {\n const result = getEvaluateResult();\n\n try {\n result.passedFilter = passesFilter(record, index);\n } catch (err) {\n result.isError = true;\n result.passedFilter = false;\n result.result = err.message;\n }\n\n if (!result.passedFilter) return result;\n\n try {\n result.result = mapRecord(record, index);\n } catch (err) {\n result.isError = true;\n result.result = err.message;\n }\n\n return result;\n};\n\nconst indexTypes = { reference: 'reference', ancestor: 'ancestor' };\n\nconst indexRuleSet = [\n makerule('map', 'index has no map function',\n index => isNonEmptyString(index.map)),\n makerule('map', \"index's map function does not compile\",\n index => !isNonEmptyString(index.map)\n || executesWithoutException(() => compileMap(index))),\n makerule('filter', \"index's filter function does not compile\",\n index => !isNonEmptyString(index.filter)\n || executesWithoutException(() => compileFilter(index))),\n makerule('name', 'must declare a name for index',\n index => isNonEmptyString(index.name)),\n makerule('name', 'there is a duplicate named index on this node',\n index => isEmpty$1(index.name)\n || countBy('name')(index.parent().indexes)[index.name] === 1),\n makerule('indexType', 'reference index may only exist on a record node',\n index => isRecord(index.parent())\n || index.indexType !== indexTypes.reference),\n makerule('indexType', `index type must be one of: ${join$1(', ', keys(indexTypes))}`,\n index => includes$1(index.indexType)(keys(indexTypes))),\n];\n\nconst getFlattenedHierarchy = (appHierarchy, useCached = true) => {\n if (isSomething(appHierarchy.getFlattenedHierarchy) && useCached) { return appHierarchy.getFlattenedHierarchy(); }\n\n const flattenHierarchy = (currentNode, flattened) => {\n flattened.push(currentNode);\n if ((!currentNode.children\n || currentNode.children.length === 0)\n && (!currentNode.indexes\n || currentNode.indexes.length === 0)\n && (!currentNode.aggregateGroups\n || currentNode.aggregateGroups.length === 0)) {\n return flattened;\n }\n\n const unionIfAny = l2 => l1 => union(l1)(!l2 ? [] : l2);\n\n const children = $([], [\n unionIfAny(currentNode.children),\n unionIfAny(currentNode.indexes),\n unionIfAny(currentNode.aggregateGroups),\n ]);\n\n for (const child of children) {\n flattenHierarchy(child, flattened);\n }\n return flattened;\n };\n\n appHierarchy.getFlattenedHierarchy = () => flattenHierarchy(appHierarchy, []);\n return appHierarchy.getFlattenedHierarchy();\n};\n\nconst getLastPartInKey = key => last(splitKey(key));\n\nconst getNodesInPath = appHierarchy => key => $(appHierarchy, [\n getFlattenedHierarchy,\n filter(n => new RegExp(`${n.pathRegx()}`).test(key)),\n]);\n\nconst getExactNodeForPath = appHierarchy => key => $(appHierarchy, [\n getFlattenedHierarchy,\n find(n => new RegExp(`${n.pathRegx()}$`).test(key)),\n]);\n\nconst getNodeForCollectionPath = appHierarchy => collectionKey => $(appHierarchy, [\n getFlattenedHierarchy,\n find(n => (isCollectionRecord(n)\n && new RegExp(`${n.collectionPathRegx()}$`).test(collectionKey))),\n]);\n\nconst hasMatchingAncestor = ancestorPredicate => decendantNode => switchCase(\n\n [node => isNothing(node.parent()),\n constant$1(false)],\n\n [node => ancestorPredicate(node.parent()),\n constant$1(true)],\n\n [defaultCase,\n node => hasMatchingAncestor(ancestorPredicate)(node.parent())],\n\n)(decendantNode);\n\nconst getNode = (appHierarchy, nodeKey) => $(appHierarchy, [\n getFlattenedHierarchy,\n find(n => n.nodeKey() === nodeKey\n || (isCollectionRecord(n)\n && n.collectionNodeKey() === nodeKey)),\n]);\n\nconst getCollectionNode = (appHierarchy, nodeKey) => $(appHierarchy, [\n getFlattenedHierarchy,\n find(n => (isCollectionRecord(n)\n && n.collectionNodeKey() === nodeKey)),\n]);\n\nconst getNodeByKeyOrNodeKey = (appHierarchy, keyOrNodeKey) => {\n const nodeByKey = getExactNodeForPath(appHierarchy)(keyOrNodeKey);\n return isNothing(nodeByKey)\n ? getNode(appHierarchy, keyOrNodeKey)\n : nodeByKey;\n};\n\nconst getCollectionNodeByKeyOrNodeKey = (appHierarchy, keyOrNodeKey) => {\n const nodeByKey = getNodeForCollectionPath(appHierarchy)(keyOrNodeKey);\n return isNothing(nodeByKey)\n ? getCollectionNode(appHierarchy, keyOrNodeKey)\n : nodeByKey;\n};\n\nconst isNode = (appHierarchy, key) => isSomething(getExactNodeForPath(appHierarchy)(key));\n\nconst getActualKeyOfParent = (parentNodeKey, actualChildKey) => $(actualChildKey, [\n splitKey,\n take(splitKey(parentNodeKey).length),\n ks => joinKey(...ks),\n]);\n\nconst getParentKey = (key) => {\n return $(key, [\n splitKey,\n take(splitKey(key).length - 1),\n joinKey,\n ]);\n};\n\nconst isKeyAncestorOf = ancestorKey => decendantNode => hasMatchingAncestor(p => p.nodeKey() === ancestorKey)(decendantNode);\n\nconst hasNoMatchingAncestors = parentPredicate => node => !hasMatchingAncestor(parentPredicate)(node);\n\nconst findField = (recordNode, fieldName) => find(f => f.name == fieldName)(recordNode.fields);\n\nconst isAncestor = decendant => ancestor => isKeyAncestorOf(ancestor.nodeKey())(decendant);\n\nconst isDecendant = ancestor => decendant => isAncestor(decendant)(ancestor);\n\nconst getRecordNodeId = recordKey => $(recordKey, [\n splitKey,\n last,\n getRecordNodeIdFromId,\n]);\n\nconst getRecordNodeIdFromId = recordId => $(recordId, [split('-'), first, parseInt]);\n\nconst getRecordNodeById = (hierarchy, recordId) => $(hierarchy, [\n getFlattenedHierarchy,\n find(n => isRecord(n)\n && n.nodeId === getRecordNodeIdFromId(recordId)),\n]);\n\nconst recordNodeIdIsAllowed = indexNode => nodeId => indexNode.allowedRecordNodeIds.length === 0\n || includes$1(nodeId)(indexNode.allowedRecordNodeIds);\n\nconst recordNodeIsAllowed = indexNode => recordNode => recordNodeIdIsAllowed(indexNode)(recordNode.nodeId);\n\nconst getAllowedRecordNodesForIndex = (appHierarchy, indexNode) => {\n const recordNodes = $(appHierarchy, [\n getFlattenedHierarchy,\n filter(isRecord),\n ]);\n\n if (isGlobalIndex(indexNode)) {\n return $(recordNodes, [\n filter(recordNodeIsAllowed(indexNode)),\n ]);\n }\n\n if (isAncestorIndex(indexNode)) {\n return $(recordNodes, [\n filter(isDecendant(indexNode.parent())),\n filter(recordNodeIsAllowed(indexNode)),\n ]);\n }\n\n if (isReferenceIndex(indexNode)) {\n return $(recordNodes, [\n filter(n => some(fieldReversesReferenceToIndex(indexNode))(n.fields)),\n ]);\n }\n};\n\nconst getNodeFromNodeKeyHash = hierarchy => hash => $(hierarchy, [\n getFlattenedHierarchy,\n find(n => getHashCode(n.nodeKey()) === hash),\n]);\n\nconst isRecord = node => isSomething(node) && node.type === 'record';\nconst isSingleRecord = node => isRecord(node) && node.isSingle;\nconst isCollectionRecord = node => isRecord(node) && !node.isSingle;\nconst isIndex = node => isSomething(node) && node.type === 'index';\nconst isaggregateGroup = node => isSomething(node) && node.type === 'aggregateGroup';\nconst isShardedIndex = node => isIndex(node) && isNonEmptyString(node.getShardName);\nconst isRoot = node => isSomething(node) && node.isRoot();\nconst isDecendantOfARecord = hasMatchingAncestor(isRecord);\nconst isGlobalIndex = node => isIndex(node) && isRoot(node.parent());\nconst isReferenceIndex = node => isIndex(node) && node.indexType === indexTypes.reference;\nconst isAncestorIndex = node => isIndex(node) && node.indexType === indexTypes.ancestor;\n\nconst fieldReversesReferenceToNode = node => field => field.type === 'reference'\n && intersection(field.typeOptions.reverseIndexNodeKeys)(map(i => i.nodeKey())(node.indexes))\n .length > 0;\n\nconst fieldReversesReferenceToIndex = indexNode => field => field.type === 'reference'\n && intersection(field.typeOptions.reverseIndexNodeKeys)([indexNode.nodeKey()])\n .length > 0;\n\nvar hierarchy = {\n getLastPartInKey,\n getNodesInPath,\n getExactNodeForPath,\n hasMatchingAncestor,\n getNode,\n getNodeByKeyOrNodeKey,\n isNode,\n getActualKeyOfParent,\n getParentKey,\n isKeyAncestorOf,\n hasNoMatchingAncestors,\n findField,\n isAncestor,\n isDecendant,\n getRecordNodeId,\n getRecordNodeIdFromId,\n getRecordNodeById,\n recordNodeIdIsAllowed,\n recordNodeIsAllowed,\n getAllowedRecordNodesForIndex,\n getNodeFromNodeKeyHash,\n isRecord,\n isCollectionRecord,\n isIndex,\n isaggregateGroup,\n isShardedIndex,\n isRoot,\n isDecendantOfARecord,\n isGlobalIndex,\n isReferenceIndex,\n isAncestorIndex,\n fieldReversesReferenceToNode,\n fieldReversesReferenceToIndex,\n getFlattenedHierarchy,\n};\n\nconst getSafeFieldParser = (tryParse, defaultValueFunctions) => (field, record) => {\n if (has(record, field.name)) {\n return getSafeValueParser(tryParse, defaultValueFunctions)(record[field.name]);\n }\n return defaultValueFunctions[field.getUndefinedValue]();\n};\n\nconst getSafeValueParser = (tryParse, defaultValueFunctions) => (value) => {\n const parsed = tryParse(value);\n if (parsed.success) {\n return parsed.value;\n }\n return defaultValueFunctions.default();\n};\n\nconst getNewValue = (tryParse, defaultValueFunctions) => (field) => {\n const getInitialValue = isUndefined(field) || isUndefined(field.getInitialValue)\n ? 'default'\n : field.getInitialValue;\n\n return has(defaultValueFunctions, getInitialValue)\n ? defaultValueFunctions[getInitialValue]()\n : getSafeValueParser(tryParse, defaultValueFunctions)(getInitialValue);\n};\n\nconst typeFunctions = specificFunctions => merge({\n value: constant$1,\n null: constant$1(null),\n}, specificFunctions);\n\nconst validateTypeConstraints = validationRules => async (field, record, context) => {\n const fieldValue = record[field.name];\n const validateRule = async r => (!await r.isValid(fieldValue, field.typeOptions, context)\n ? r.getMessage(fieldValue, field.typeOptions)\n : '');\n\n const errors = [];\n for (const r of validationRules) {\n const err = await validateRule(r);\n if (isNotEmpty(err)) errors.push(err);\n }\n\n return errors;\n};\n\nconst getDefaultOptions = mapValues(v => v.defaultValue);\n\nconst makerule$1 = (isValid, getMessage) => ({ isValid, getMessage });\nconst parsedFailed = val => ({ success: false, value: val });\nconst parsedSuccess = val => ({ success: true, value: val });\nconst getDefaultExport = (name, tryParse, functions, options, validationRules, sampleValue, stringify) => ({\n getNew: getNewValue(tryParse, functions),\n safeParseField: getSafeFieldParser(tryParse, functions),\n safeParseValue: getSafeValueParser(tryParse, functions),\n tryParse,\n name,\n getDefaultOptions: () => getDefaultOptions(cloneDeep(options)),\n optionDefinitions: options,\n validateTypeConstraints: validateTypeConstraints(validationRules),\n sampleValue,\n stringify: val => (val === null || val === undefined\n ? '' : stringify(val)),\n getDefaultValue: functions.default,\n});\n\nconst stringFunctions = typeFunctions({\n default: constant(null),\n});\n\nconst stringTryParse = switchCase(\n [isString, parsedSuccess],\n [isNull, parsedSuccess],\n [defaultCase, v => parsedSuccess(v.toString())],\n);\n\nconst options = {\n maxLength: {\n defaultValue: null,\n isValid: n => n === null || isSafeInteger(n) && n > 0,\n requirementDescription: 'max length must be null (no limit) or a greater than zero integer',\n parse: toNumberOrNull,\n },\n values: {\n defaultValue: null,\n isValid: v => v === null || (isArrayOfString(v) && v.length > 0 && v.length < 10000),\n requirementDescription: \"'values' must be null (no values) or an arry of at least one string\",\n parse: s => s,\n },\n allowDeclaredValuesOnly: {\n defaultValue: false,\n isValid: isBoolean,\n requirementDescription: 'allowDeclaredValuesOnly must be true or false',\n parse: toBoolOrNull,\n },\n};\n\nconst typeConstraints = [\n makerule$1(async (val, opts) => val === null || opts.maxLength === null || val.length <= opts.maxLength,\n (val, opts) => `value exceeds maximum length of ${opts.maxLength}`),\n makerule$1(async (val, opts) => val === null\n || opts.allowDeclaredValuesOnly === false\n || includes(opts.values, val),\n (val) => `\"${val}\" does not exist in the list of allowed values`),\n];\n\nvar string = getDefaultExport(\n 'string',\n stringTryParse,\n stringFunctions,\n options,\n typeConstraints,\n 'abcde',\n str => str,\n);\n\nconst boolFunctions = typeFunctions({\n default: constant(null),\n});\n\nconst boolTryParse = switchCase(\n [isBoolean, parsedSuccess],\n [isNull, parsedSuccess],\n [isOneOf('true', '1', 'yes', 'on'), () => parsedSuccess(true)],\n [isOneOf('false', '0', 'no', 'off'), () => parsedSuccess(false)],\n [defaultCase, parsedFailed],\n);\n\nconst options$1 = {\n allowNulls: {\n defaultValue: true,\n isValid: isBoolean,\n requirementDescription: 'must be a true or false',\n parse: toBoolOrNull,\n },\n};\n\nconst typeConstraints$1 = [\n makerule$1(async (val, opts) => opts.allowNulls === true || val !== null,\n () => 'field cannot be null'),\n];\n\nvar bool = getDefaultExport(\n 'bool', boolTryParse, boolFunctions,\n options$1, typeConstraints$1, true, JSON.stringify,\n);\n\nconst numberFunctions = typeFunctions({\n default: constant(null),\n});\n\nconst parseStringtoNumberOrNull = (s) => {\n const num = Number(s);\n return isNaN(num) ? parsedFailed(s) : parsedSuccess(num);\n};\n\nconst numberTryParse = switchCase(\n [isNumber, parsedSuccess],\n [isString, parseStringtoNumberOrNull],\n [isNull, parsedSuccess],\n [defaultCase, parsedFailed],\n);\n\nconst options$2 = {\n maxValue: {\n defaultValue: Number.MAX_SAFE_INTEGER,\n isValid: isSafeInteger,\n requirementDescription: 'must be a valid integer',\n parse: toNumberOrNull,\n },\n minValue: {\n defaultValue: 0 - Number.MAX_SAFE_INTEGER,\n isValid: isSafeInteger,\n requirementDescription: 'must be a valid integer',\n parse: toNumberOrNull,\n },\n decimalPlaces: {\n defaultValue: 0,\n isValid: n => isSafeInteger(n) && n >= 0,\n requirementDescription: 'must be a positive integer',\n parse: toNumberOrNull,\n },\n};\n\nconst getDecimalPlaces = (val) => {\n const splitDecimal = val.toString().split('.');\n if (splitDecimal.length === 1) return 0;\n return splitDecimal[1].length;\n};\n\nconst typeConstraints$2 = [\n makerule$1(async (val, opts) => val === null || opts.minValue === null || val >= opts.minValue,\n (val, opts) => `value (${val.toString()}) must be greater than or equal to ${opts.minValue}`),\n makerule$1(async (val, opts) => val === null || opts.maxValue === null || val <= opts.maxValue,\n (val, opts) => `value (${val.toString()}) must be less than or equal to ${opts.minValue} options`),\n makerule$1(async (val, opts) => val === null || opts.decimalPlaces >= getDecimalPlaces(val),\n (val, opts) => `value (${val.toString()}) must have ${opts.decimalPlaces} decimal places or less`),\n];\n\nvar number = getDefaultExport(\n 'number',\n numberTryParse,\n numberFunctions,\n options$2,\n typeConstraints$2,\n 1,\n num => num.toString(),\n);\n\nconst dateFunctions = typeFunctions({\n default: constant(null),\n now: () => new Date(),\n});\n\nconst isValidDate = d => d instanceof Date && !isNaN(d);\n\nconst parseStringToDate = s => switchCase(\n [isValidDate, parsedSuccess],\n [defaultCase, parsedFailed],\n)(new Date(s));\n\n\nconst dateTryParse = switchCase(\n [isDate, parsedSuccess],\n [isString, parseStringToDate],\n [isNull, parsedSuccess],\n [defaultCase, parsedFailed],\n);\n\nconst options$3 = {\n maxValue: {\n defaultValue: new Date(32503680000000),\n isValid: isDate,\n requirementDescription: 'must be a valid date',\n parse: toDateOrNull,\n },\n minValue: {\n defaultValue: new Date(-8520336000000),\n isValid: isDate,\n requirementDescription: 'must be a valid date',\n parse: toDateOrNull,\n },\n};\n\nconst typeConstraints$3 = [\n makerule$1(async (val, opts) => val === null || opts.minValue === null || val >= opts.minValue,\n (val, opts) => `value (${val.toString()}) must be greater than or equal to ${opts.minValue}`),\n makerule$1(async (val, opts) => val === null || opts.maxValue === null || val <= opts.maxValue,\n (val, opts) => `value (${val.toString()}) must be less than or equal to ${opts.minValue} options`),\n];\n\nvar datetime = getDefaultExport(\n 'datetime',\n dateTryParse,\n dateFunctions,\n options$3,\n typeConstraints$3,\n new Date(1984, 4, 1),\n date => JSON.stringify(date).replace(new RegExp('\"', 'g'), ''),\n);\n\nconst arrayFunctions = () => typeFunctions({\n default: constant([]),\n});\n\nconst mapToParsedArrary = type => $$(\n map(i => type.safeParseValue(i)),\n parsedSuccess,\n);\n\nconst arrayTryParse = type => switchCase(\n [isArray$1, mapToParsedArrary(type)],\n [defaultCase, parsedFailed],\n);\n\nconst typeName = type => `array<${type}>`;\n\n\nconst options$4 = {\n maxLength: {\n defaultValue: 10000,\n isValid: isSafeInteger,\n requirementDescription: 'must be a positive integer',\n parse: toNumberOrNull,\n },\n minLength: {\n defaultValue: 0,\n isValid: n => isSafeInteger(n) && n >= 0,\n requirementDescription: 'must be a positive integer',\n parse: toNumberOrNull,\n },\n};\n\nconst typeConstraints$4 = [\n makerule$1(async (val, opts) => val === null || val.length >= opts.minLength,\n (val, opts) => `must choose ${opts.minLength} or more options`),\n makerule$1(async (val, opts) => val === null || val.length <= opts.maxLength,\n (val, opts) => `cannot choose more than ${opts.maxLength} options`),\n];\n\nvar array = type => getDefaultExport(\n typeName(type.name),\n arrayTryParse(type),\n arrayFunctions(),\n options$4,\n typeConstraints$4,\n [type.sampleValue],\n JSON.stringify,\n);\n\nconst referenceNothing = () => ({ key: '' });\n\nconst referenceFunctions = typeFunctions({\n default: referenceNothing,\n});\n\nconst hasStringValue = (ob, path) => has(ob, path)\n && isString(ob[path]);\n\nconst isObjectWithKey = v => isObjectLike(v)\n && hasStringValue(v, 'key');\n\nconst tryParseFromString = s => {\n\n try {\n const asObj = JSON.parse(s);\n if(isObjectWithKey) {\n return parsedSuccess(asObj);\n }\n }\n catch(_) {\n // EMPTY\n }\n\n return parsedFailed(s);\n};\n\nconst referenceTryParse = v => switchCase(\n [isObjectWithKey, parsedSuccess],\n [isString, tryParseFromString],\n [isNull, () => parsedSuccess(referenceNothing())],\n [defaultCase, parsedFailed],\n)(v);\n\nconst options$5 = {\n indexNodeKey: {\n defaultValue: null,\n isValid: isNonEmptyString,\n requirementDescription: 'must be a non-empty string',\n parse: s => s,\n },\n displayValue: {\n defaultValue: '',\n isValid: isNonEmptyString,\n requirementDescription: 'must be a non-empty string',\n parse: s => s,\n },\n reverseIndexNodeKeys: {\n defaultValue: null,\n isValid: v => isArrayOfString(v) && v.length > 0,\n requirementDescription: 'must be a non-empty array of strings',\n parse: s => s,\n },\n};\n\nconst isEmptyString = s => isString(s) && isEmpty(s);\n\nconst ensureReferenceExists = async (val, opts, context) => isEmptyString(val.key)\n || await context.referenceExists(opts, val.key);\n\nconst typeConstraints$5 = [\n makerule$1(\n ensureReferenceExists,\n (val, opts) => `\"${val[opts.displayValue]}\" does not exist in options list (key: ${val.key})`,\n ),\n];\n\nvar reference = getDefaultExport(\n 'reference',\n referenceTryParse,\n referenceFunctions,\n options$5,\n typeConstraints$5,\n { key: 'key', value: 'value' },\n JSON.stringify,\n);\n\nconst illegalCharacters = '*?\\\\/:<>|\\0\\b\\f\\v';\n\nconst isLegalFilename = (filePath) => {\n const fn = fileName(filePath);\n return fn.length <= 255\n && intersection(fn.split(''))(illegalCharacters.split('')).length === 0\n && none(f => f === '..')(splitKey(filePath));\n};\n\nconst fileNothing = () => ({ relativePath: '', size: 0 });\n\nconst fileFunctions = typeFunctions({\n default: fileNothing,\n});\n\nconst fileTryParse = v => switchCase(\n [isValidFile, parsedSuccess],\n [isNull$1, () => parsedSuccess(fileNothing())],\n [defaultCase, parsedFailed],\n)(v);\n\nconst fileName = filePath => $(filePath, [\n splitKey,\n last,\n]);\n\nconst isValidFile = f => !isNull$1(f)\n && has$1('relativePath')(f) && has$1('size')(f)\n && isNumber$1(f.size)\n && isString$1(f.relativePath)\n && isLegalFilename(f.relativePath);\n\nconst options$6 = {};\n\nconst typeConstraints$6 = [];\n\nvar file = getDefaultExport(\n 'file',\n fileTryParse,\n fileFunctions,\n options$6,\n typeConstraints$6,\n { relativePath: 'some_file.jpg', size: 1000 },\n JSON.stringify,\n);\n\nconst allTypes = () => {\n const basicTypes = {\n string, number, datetime, bool, reference, file,\n };\n\n const arrays = $(basicTypes, [\n keys,\n map((k) => {\n const kvType = {};\n const concreteArray = array(basicTypes[k]);\n kvType[concreteArray.name] = concreteArray;\n return kvType;\n }),\n types => assign({}, ...types),\n ]);\n\n return merge({}, basicTypes, arrays);\n};\n\n\nconst all$1 = allTypes();\n\nconst getType = (typeName) => {\n if (!has(all$1, typeName)) throw new BadRequestError(`Do not recognise type ${typeName}`);\n return all$1[typeName];\n};\n\nconst getSampleFieldValue = field => getType(field.type).sampleValue;\n\nconst getNewFieldValue = field => getType(field.type).getNew(field);\n\nconst safeParseField = (field, record) => getType(field.type).safeParseField(field, record);\n\nconst validateFieldParse = (field, record) => (has(record, field.name)\n ? getType(field.type).tryParse(record[field.name])\n : parsedSuccess(undefined)); // fields may be undefined by default\n\nconst getDefaultOptions$1 = type => getType(type).getDefaultOptions();\n\nconst validateTypeConstraints$1 = async (field, record, context) => await getType(field.type).validateTypeConstraints(field, record, context);\n\nconst detectType = (value) => {\n if (isString$1(value)) return string;\n if (isBoolean$1(value)) return bool;\n if (isNumber$1(value)) return number;\n if (isDate$1(value)) return datetime;\n if (isArray$2(value)) return array(detectType(value[0]));\n if (isObject(value)\n && has(value, 'key')\n && has(value, 'value')) return reference;\n if (isObject(value)\n && has(value, 'relativePath')\n && has(value, 'size')) return file;\n\n throw new BadRequestError(`cannot determine type: ${JSON.stringify(value)}`);\n};\n\n// 5 minutes\nconst tempCodeExpiryLength = 5 * 60 * 1000;\n\nconst AUTH_FOLDER = '/.auth';\nconst USERS_LIST_FILE = joinKey(AUTH_FOLDER, 'users.json');\nconst userAuthFile = username => joinKey(AUTH_FOLDER, `auth_${username}.json`);\nconst USERS_LOCK_FILE = joinKey(AUTH_FOLDER, 'users_lock');\nconst ACCESS_LEVELS_FILE = joinKey(AUTH_FOLDER, 'access_levels.json');\nconst ACCESS_LEVELS_LOCK_FILE = joinKey(AUTH_FOLDER, 'access_levels_lock');\n\nconst permissionTypes = {\n CREATE_RECORD: 'create record',\n UPDATE_RECORD: 'update record',\n READ_RECORD: 'read record',\n DELETE_RECORD: 'delete record',\n READ_INDEX: 'read index',\n MANAGE_INDEX: 'manage index',\n MANAGE_COLLECTION: 'manage collection',\n WRITE_TEMPLATES: 'write templates',\n CREATE_USER: 'create user',\n SET_PASSWORD: 'set password',\n CREATE_TEMPORARY_ACCESS: 'create temporary access',\n ENABLE_DISABLE_USER: 'enable or disable user',\n WRITE_ACCESS_LEVELS: 'write access levels',\n LIST_USERS: 'list users',\n LIST_ACCESS_LEVELS: 'list access levels',\n EXECUTE_ACTION: 'execute action',\n SET_USER_ACCESS_LEVELS: 'set user access levels',\n};\n\nconst getUserByName = (users, name) => $(users, [\n find(u => u.name.toLowerCase() === name.toLowerCase()),\n]);\n\nconst stripUserOfSensitiveStuff = (user) => {\n const stripped = clone(user);\n delete stripped.tempCode;\n return stripped;\n};\n\nconst parseTemporaryCode = fullCode => $(fullCode, [\n split(':'),\n parts => ({\n id: parts[1],\n code: parts[2],\n }),\n]);\n\nconst isAuthorized = app => (permissionType, resourceKey) => apiWrapperSync(\n app,\n events.authApi.isAuthorized,\n alwaysAuthorized,\n { resourceKey, permissionType },\n _isAuthorized, app, permissionType, resourceKey,\n);\n\nconst _isAuthorized = (app, permissionType, resourceKey) => {\n if (!app.user) {\n return false;\n }\n\n const validType = $(permissionTypes, [\n values,\n includes$1(permissionType),\n ]);\n\n if (!validType) {\n return false;\n }\n\n const permMatchesResource = (userperm) => {\n const nodeKey = isNothing(resourceKey)\n ? null\n : isNode(app.hierarchy, resourceKey)\n ? getNodeByKeyOrNodeKey(\n app.hierarchy, resourceKey,\n ).nodeKey()\n : resourceKey;\n\n return (userperm.type === permissionType)\n && (\n isNothing(resourceKey)\n || nodeKey === userperm.nodeKey\n );\n };\n\n return $(app.user.permissions, [\n some(permMatchesResource),\n ]);\n};\n\nconst nodePermission = type => ({\n add: (nodeKey, accessLevel) => accessLevel.permissions.push({ type, nodeKey }),\n isAuthorized: resourceKey => app => isAuthorized(app)(type, resourceKey),\n isNode: true,\n get: nodeKey => ({ type, nodeKey }),\n});\n\nconst staticPermission = type => ({\n add: accessLevel => accessLevel.permissions.push({ type }),\n isAuthorized: app => isAuthorized(app)(type),\n isNode: false,\n get: () => ({ type }),\n});\n\nconst createRecord = nodePermission(permissionTypes.CREATE_RECORD);\n\nconst updateRecord = nodePermission(permissionTypes.UPDATE_RECORD);\n\nconst deleteRecord = nodePermission(permissionTypes.DELETE_RECORD);\n\nconst readRecord = nodePermission(permissionTypes.READ_RECORD);\n\nconst writeTemplates = staticPermission(permissionTypes.WRITE_TEMPLATES);\n\nconst createUser = staticPermission(permissionTypes.CREATE_USER);\n\nconst setPassword = staticPermission(permissionTypes.SET_PASSWORD);\n\nconst readIndex = nodePermission(permissionTypes.READ_INDEX);\n\nconst manageIndex = staticPermission(permissionTypes.MANAGE_INDEX);\n\nconst manageCollection = staticPermission(permissionTypes.MANAGE_COLLECTION);\n\nconst createTemporaryAccess = staticPermission(permissionTypes.CREATE_TEMPORARY_ACCESS);\n\nconst enableDisableUser = staticPermission(permissionTypes.ENABLE_DISABLE_USER);\n\nconst writeAccessLevels = staticPermission(permissionTypes.WRITE_ACCESS_LEVELS);\n\nconst listUsers = staticPermission(permissionTypes.LIST_USERS);\n\nconst listAccessLevels = staticPermission(permissionTypes.LIST_ACCESS_LEVELS);\n\nconst setUserAccessLevels = staticPermission(permissionTypes.SET_USER_ACCESS_LEVELS);\n\nconst executeAction = nodePermission(permissionTypes.EXECUTE_ACTION);\n\nconst alwaysAuthorized = () => true;\n\nconst permission = {\n createRecord,\n updateRecord,\n deleteRecord,\n readRecord,\n writeTemplates,\n createUser,\n setPassword,\n readIndex,\n createTemporaryAccess,\n enableDisableUser,\n writeAccessLevels,\n listUsers,\n listAccessLevels,\n manageIndex,\n manageCollection,\n executeAction,\n setUserAccessLevels,\n};\n\nconst getNew = app => (collectionKey, recordTypeName) => {\n const recordNode = getRecordNode(app, collectionKey);\n return apiWrapperSync(\n app,\n events.recordApi.getNew,\n permission.createRecord.isAuthorized(recordNode.nodeKey()),\n { collectionKey, recordTypeName },\n _getNew, recordNode, collectionKey,\n );\n};\n\nconst _getNew = (recordNode, collectionKey) => constructRecord(recordNode, getNewFieldValue, collectionKey);\n\nconst getRecordNode = (app, collectionKey) => {\n collectionKey = safeKey(collectionKey);\n return getNodeForCollectionPath(app.hierarchy)(collectionKey);\n};\n\nconst getNewChild = app => (recordKey, collectionName, recordTypeName) => \n getNew(app)(joinKey(recordKey, collectionName), recordTypeName);\n\nconst constructRecord = (recordNode, getFieldValue, collectionKey) => {\n const record = $(recordNode.fields, [\n keyBy('name'),\n mapValues(getFieldValue),\n ]);\n\n record.id = `${recordNode.nodeId}-${generate()}`;\n record.key = joinKey(collectionKey, record.id);\n record.isNew = true;\n record.type = recordNode.name;\n return record;\n};\n\nconst getRecordFileName = key => joinKey(key, 'record.json');\n\nconst load = app => async key => apiWrapper(\n app,\n events.recordApi.load,\n permission.readRecord.isAuthorized(key),\n { key },\n _load, app, key,\n);\n\nconst _load = async (app, key, keyStack = []) => {\n key = safeKey(key);\n const recordNode = getExactNodeForPath(app.hierarchy)(key);\n const storedData = await app.datastore.loadJson(\n getRecordFileName(key),\n );\n\n const loadedRecord = $(recordNode.fields, [\n keyBy('name'),\n mapValues(f => safeParseField(f, storedData)),\n ]);\n\n const newKeyStack = [...keyStack, key];\n\n const references = $(recordNode.fields, [\n filter(f => f.type === 'reference'\n && isNonEmptyString(loadedRecord[f.name].key)\n && !includes$1(loadedRecord[f.name].key)(newKeyStack)),\n map(f => ({\n promise: _load(app, loadedRecord[f.name].key, newKeyStack),\n index: getNode(app.hierarchy, f.typeOptions.indexNodeKey),\n field: f,\n })),\n ]);\n\n if (references.length > 0) {\n const refRecords = await Promise.all(\n map(p => p.promise)(references),\n );\n\n for (const ref of references) {\n loadedRecord[ref.field.name] = mapRecord(\n refRecords[references.indexOf(ref)],\n ref.index,\n );\n }\n }\n\n loadedRecord.transactionId = storedData.transactionId;\n loadedRecord.isNew = false;\n loadedRecord.key = key;\n loadedRecord.id = $(key, [splitKey, last]);\n loadedRecord.type = recordNode.name;\n return loadedRecord;\n};\n\n// adapted from https://github.com/dex4er/js-promise-readable\r\n// thanks :)\r\n \r\nconst promiseReadableStream = stream => {\r\n \r\n let _errored;\r\n\r\n const _errorHandler = err => {\r\n _errored = err;\r\n };\r\n\r\n stream.on(\"error\", _errorHandler);\r\n \r\n const read = (size) => {\r\n \r\n return new Promise((resolve, reject) => {\r\n if (_errored) {\r\n const err = _errored;\r\n _errored = undefined;\r\n return reject(err)\r\n }\r\n \r\n if (!stream.readable || stream.closed || stream.destroyed) {\r\n return resolve();\r\n }\r\n \r\n const readableHandler = () => {\r\n const chunk = stream.read(size);\r\n \r\n if (chunk) {\r\n removeListeners();\r\n resolve(chunk);\r\n }\r\n };\r\n \r\n const closeHandler = () => {\r\n removeListeners();\r\n resolve();\r\n };\r\n \r\n const endHandler = () => {\r\n removeListeners();\r\n resolve();\r\n };\r\n \r\n const errorHandler = (err) => {\r\n _errored = undefined;\r\n removeListeners();\r\n reject(err);\r\n };\r\n \r\n const removeListeners = () => {\r\n stream.removeListener(\"close\", closeHandler);\r\n stream.removeListener(\"error\", errorHandler);\r\n stream.removeListener(\"end\", endHandler);\r\n stream.removeListener(\"readable\", readableHandler);\r\n };\r\n \r\n stream.on(\"close\", closeHandler);\r\n stream.on(\"end\", endHandler);\r\n stream.on(\"error\", errorHandler);\r\n stream.on(\"readable\", readableHandler);\r\n \r\n readableHandler();\r\n });\r\n };\r\n \r\n \r\n const destroy = () => {\r\n if (stream) {\r\n if (_errorHandler) {\r\n stream.removeListener(\"error\", _errorHandler);\r\n }\r\n if (typeof stream.destroy === \"function\") {\r\n stream.destroy();\r\n }\r\n }\r\n };\r\n \r\n return {read, destroy, stream};\r\n };\n\nconst getIndexedDataKey = (indexNode, indexKey, record) => {\n const getShardName = (indexNode, record) => {\n const shardNameFunc = compileCode$1(indexNode.getShardName);\n try {\n return shardNameFunc({ record });\n } catch(e) {\n const errorDetails = `shardCode: ${indexNode.getShardName} :: record: ${JSON.stringify(record)} :: `;\n e.message = \"Error running index shardname func: \" + errorDetails + e.message;\n throw e;\n }\n };\n\n const shardName = isNonEmptyString(indexNode.getShardName)\n ? `${getShardName(indexNode, record)}.csv`\n : 'index.csv';\n\n return joinKey(indexKey, shardName);\n};\n\nconst getShardKeysInRange = async (app, indexKey, startRecord = null, endRecord = null) => {\n const indexNode = getExactNodeForPath(app.hierarchy)(indexKey);\n\n const startShardName = !startRecord\n ? null\n : shardNameFromKey(\n getIndexedDataKey(\n indexNode,\n indexKey,\n startRecord,\n ),\n );\n\n const endShardName = !endRecord\n ? null\n : shardNameFromKey(\n getIndexedDataKey(\n indexNode,\n indexKey,\n endRecord,\n ),\n );\n\n return $(await getShardMap(app.datastore, indexKey), [\n filter(k => (startRecord === null || k >= startShardName)\n && (endRecord === null || k <= endShardName)),\n map(k => joinKey(indexKey, `${k}.csv`)),\n ]);\n};\n\nconst ensureShardNameIsInShardMap = async (store, indexKey, indexedDataKey) => {\n const map = await getShardMap(store, indexKey);\n const shardName = shardNameFromKey(indexedDataKey);\n if (!includes$1(shardName)(map)) {\n map.push(shardName);\n await writeShardMap(store, indexKey, map);\n }\n};\n\nconst getShardMap = async (datastore, indexKey) => {\n const shardMapKey = getShardMapKey(indexKey);\n try {\n return await datastore.loadJson(shardMapKey);\n } catch (_) {\n await datastore.createJson(shardMapKey, []);\n return [];\n }\n};\n\nconst writeShardMap = async (datastore, indexKey, shardMap) => await datastore.updateJson(\n getShardMapKey(indexKey),\n shardMap,\n);\n\nconst getAllShardKeys = async (app, indexKey) => await getShardKeysInRange(app, indexKey);\n\nconst getShardMapKey = indexKey => joinKey(indexKey, 'shardMap.json');\n\nconst getUnshardedIndexDataKey = indexKey => joinKey(indexKey, 'index.csv');\n\nconst createIndexFile = async (datastore, indexedDataKey, index) => {\n if (isShardedIndex(index)) {\n const indexKey = getParentKey(indexedDataKey);\n const shardMap = await getShardMap(datastore, indexKey);\n shardMap.push(\n shardNameFromKey(indexedDataKey),\n );\n await writeShardMap(datastore, indexKey, shardMap);\n }\n await datastore.createFile(indexedDataKey, '');\n};\n\nconst shardNameFromKey = key => $(key, [\n splitKey,\n last,\n]).replace('.csv', '');\n\nconst getIndexKey_BasedOnDecendant = (decendantKey, indexNode) => {\n if (isGlobalIndex(indexNode)) { return `${indexNode.nodeKey()}`; }\n\n const indexedDataParentKey = getActualKeyOfParent(\n indexNode.parent().nodeKey(),\n decendantKey,\n );\n\n return joinKey(\n indexedDataParentKey,\n indexNode.name,\n );\n};\n\nconst generateSchema = (hierarchy, indexNode) => {\n const recordNodes = getAllowedRecordNodesForIndex(hierarchy, indexNode);\n const mappedRecords = $(recordNodes, [\n map(n => mapRecord(createSampleRecord(n), indexNode)),\n ]);\n\n // always has record key and sort key\n const schema = {\n sortKey: all$1.string,\n key: all$1.string,\n };\n\n const fieldsHas = has$1(schema);\n const setField = (fieldName, value) => {\n if (value === null || value === undefined) { return; }\n\n const thisType = detectType(value);\n if (fieldsHas(fieldName)) {\n if (schema[fieldName] !== thisType) {\n schema[fieldName] = all$1.string;\n }\n } else {\n schema[fieldName] = thisType;\n }\n };\n\n for (const mappedRec of mappedRecords) {\n for (const f in mappedRec) {\n setField(f, mappedRec[f]);\n }\n }\n\n // returing an array of {name, type}\n return $(schema, [\n keys$1,\n map(k => ({ name: k, type: schema[k].name })),\n filter(s => s.name !== 'sortKey'),\n orderBy('name', ['desc']), // reverse aplha\n concat([{ name: 'sortKey', type: all$1.string.name }]), // sortKey on end\n reverse, // sortKey first, then rest are alphabetical\n ]);\n};\n\nconst createSampleRecord = recordNode => constructRecord(\n recordNode,\n getSampleFieldValue,\n recordNode.parent().nodeKey(),\n);\n\nvar global$1 = (typeof global !== \"undefined\" ? global :\n typeof self !== \"undefined\" ? self :\n typeof window !== \"undefined\" ? window : {});\n\nvar lookup = [];\nvar revLookup = [];\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array;\nvar inited = false;\nfunction init () {\n inited = true;\n var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n for (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i];\n revLookup[code.charCodeAt(i)] = i;\n }\n\n revLookup['-'.charCodeAt(0)] = 62;\n revLookup['_'.charCodeAt(0)] = 63;\n}\n\nfunction toByteArray (b64) {\n if (!inited) {\n init();\n }\n var i, j, l, tmp, placeHolders, arr;\n var len = b64.length;\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // the number of equal signs (place holders)\n // if there are two placeholders, than the two characters before it\n // represent one byte\n // if there is only one, then the three characters before it represent 2 bytes\n // this is just a cheap hack to not do indexOf twice\n placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0;\n\n // base64 is 4/3 + up to two characters of the original data\n arr = new Arr(len * 3 / 4 - placeHolders);\n\n // if there are placeholders, only get up to the last complete 4 chars\n l = placeHolders > 0 ? len - 4 : len;\n\n var L = 0;\n\n for (i = 0, j = 0; i < l; i += 4, j += 3) {\n tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)];\n arr[L++] = (tmp >> 16) & 0xFF;\n arr[L++] = (tmp >> 8) & 0xFF;\n arr[L++] = tmp & 0xFF;\n }\n\n if (placeHolders === 2) {\n tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4);\n arr[L++] = tmp & 0xFF;\n } else if (placeHolders === 1) {\n tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2);\n arr[L++] = (tmp >> 8) & 0xFF;\n arr[L++] = tmp & 0xFF;\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp;\n var output = [];\n for (var i = start; i < end; i += 3) {\n tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]);\n output.push(tripletToBase64(tmp));\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n if (!inited) {\n init();\n }\n var tmp;\n var len = uint8.length;\n var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes\n var output = '';\n var parts = [];\n var maxChunkLength = 16383; // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)));\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1];\n output += lookup[tmp >> 2];\n output += lookup[(tmp << 4) & 0x3F];\n output += '==';\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + (uint8[len - 1]);\n output += lookup[tmp >> 10];\n output += lookup[(tmp >> 4) & 0x3F];\n output += lookup[(tmp << 2) & 0x3F];\n output += '=';\n }\n\n parts.push(output);\n\n return parts.join('')\n}\n\nfunction read (buffer, offset, isLE, mLen, nBytes) {\n var e, m;\n var eLen = nBytes * 8 - mLen - 1;\n var eMax = (1 << eLen) - 1;\n var eBias = eMax >> 1;\n var nBits = -7;\n var i = isLE ? (nBytes - 1) : 0;\n var d = isLE ? -1 : 1;\n var s = buffer[offset + i];\n\n i += d;\n\n e = s & ((1 << (-nBits)) - 1);\n s >>= (-nBits);\n nBits += eLen;\n for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1);\n e >>= (-nBits);\n nBits += mLen;\n for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias;\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen);\n e = e - eBias;\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nfunction write (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c;\n var eLen = nBytes * 8 - mLen - 1;\n var eMax = (1 << eLen) - 1;\n var eBias = eMax >> 1;\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0);\n var i = isLE ? 0 : (nBytes - 1);\n var d = isLE ? 1 : -1;\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;\n\n value = Math.abs(value);\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0;\n e = eMax;\n } else {\n e = Math.floor(Math.log(value) / Math.LN2);\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--;\n c *= 2;\n }\n if (e + eBias >= 1) {\n value += rt / c;\n } else {\n value += rt * Math.pow(2, 1 - eBias);\n }\n if (value * c >= 2) {\n e++;\n c /= 2;\n }\n\n if (e + eBias >= eMax) {\n m = 0;\n e = eMax;\n } else if (e + eBias >= 1) {\n m = (value * c - 1) * Math.pow(2, mLen);\n e = e + eBias;\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);\n e = 0;\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m;\n eLen += mLen;\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128;\n}\n\nvar toString = {}.toString;\n\nvar isArray = Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n\nvar INSPECT_MAX_BYTES = 50;\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined\n ? global$1.TYPED_ARRAY_SUPPORT\n : true;\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length);\n that.__proto__ = Buffer.prototype;\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length);\n }\n that.length = length;\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192; // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype;\n return arr\n};\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n};\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype;\n Buffer.__proto__ = Uint8Array;\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size);\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n};\n\nfunction allocUnsafe (that, size) {\n assertSize(size);\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0);\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0;\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n};\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n};\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8';\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0;\n that = createBuffer(that, length);\n\n var actual = that.write(string, encoding);\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual);\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0;\n that = createBuffer(that, length);\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255;\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength; // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array);\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset);\n } else {\n array = new Uint8Array(array, byteOffset, length);\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array;\n that.__proto__ = Buffer.prototype;\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array);\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (internalIsBuffer(obj)) {\n var len = checked(obj.length) | 0;\n that = createBuffer(that, len);\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len);\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\nBuffer.isBuffer = isBuffer;\nfunction internalIsBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!internalIsBuffer(a) || !internalIsBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length;\n var y = b.length;\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i];\n y = b[i];\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n};\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n};\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i;\n if (length === undefined) {\n length = 0;\n for (i = 0; i < list.length; ++i) {\n length += list[i].length;\n }\n }\n\n var buffer = Buffer.allocUnsafe(length);\n var pos = 0;\n for (i = 0; i < list.length; ++i) {\n var buf = list[i];\n if (!internalIsBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos);\n pos += buf.length;\n }\n return buffer\n};\n\nfunction byteLength (string, encoding) {\n if (internalIsBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string;\n }\n\n var len = string.length;\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false;\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase();\n loweredCase = true;\n }\n }\n}\nBuffer.byteLength = byteLength;\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false;\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0;\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length;\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0;\n start >>>= 0;\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8';\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase();\n loweredCase = true;\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true;\n\nfunction swap (b, n, m) {\n var i = b[n];\n b[n] = b[m];\n b[m] = i;\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length;\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1);\n }\n return this\n};\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length;\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3);\n swap(this, i + 1, i + 2);\n }\n return this\n};\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length;\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7);\n swap(this, i + 1, i + 6);\n swap(this, i + 2, i + 5);\n swap(this, i + 3, i + 4);\n }\n return this\n};\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0;\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n};\n\nBuffer.prototype.equals = function equals (b) {\n if (!internalIsBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n};\n\nBuffer.prototype.inspect = function inspect () {\n var str = '';\n var max = INSPECT_MAX_BYTES;\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ');\n if (this.length > max) str += ' ... ';\n }\n return '