Repository: immerjs/immer Branch: main Commit: cdccf1a6d0d3 Files: 153 Total size: 1.6 MB Directory structure: gitextract__7fir6fk/ ├── .codesandbox/ │ └── ci.json ├── .coveralls.yml ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug.md │ │ ├── feature.md │ │ └── question.md │ ├── lock.yml │ └── workflows/ │ ├── docs-public.yml │ ├── release.yml │ └── test.yml ├── .gitignore ├── .prettierrc ├── .vscode/ │ ├── launch.json │ └── settings.json ├── .watchmanconfig ├── LICENSE ├── SECURITY.md ├── __performance_tests__/ │ ├── add-data.mjs │ ├── data.json │ ├── incremental.mjs │ ├── large-obj.mjs │ ├── measure.mjs │ └── todo.mjs ├── __tests__/ │ ├── __prod_snapshots__/ │ │ ├── base.js.snap │ │ ├── curry.js.snap │ │ ├── frozen.js.snap │ │ ├── manual.js.snap │ │ ├── patch.js.snap │ │ ├── plugins.js.snap │ │ └── readme.js.snap │ ├── __snapshots__/ │ │ ├── base.js.snap │ │ ├── curry.js.snap │ │ ├── frozen.js.snap │ │ ├── manual.js.snap │ │ ├── patch.js.snap │ │ ├── plugins.js.snap │ │ └── readme.js.snap │ ├── base.js │ ├── current.js │ ├── curry.js │ ├── draft.ts │ ├── empty.ts │ ├── flow/ │ │ ├── .flowconfig │ │ └── flow.js.flow │ ├── frozen.js │ ├── immutable.ts │ ├── isDraftable.js │ ├── manual.js │ ├── map-set.js │ ├── not-strict-copy.ts │ ├── null.js │ ├── original.js │ ├── patch.js │ ├── plugins.js │ ├── produce.ts │ ├── readme.js │ ├── redux.ts │ ├── regressions.js │ ├── spec_ts.ts │ ├── test-data.json │ ├── tsconfig.json │ ├── type-external.ts │ └── updateScenarios.js ├── _site/ │ ├── .github/ │ │ └── ISSUE_TEMPLATE/ │ │ ├── bug/ │ │ │ └── index.html │ │ └── feature/ │ │ └── index.html │ └── readme/ │ └── index.html ├── package.json ├── perf-testing/ │ ├── .gitignore │ ├── README.md │ ├── immutability-benchmarks.mjs │ ├── immutability-profiling.mjs │ ├── package.json │ ├── read-cpuprofile.js │ └── rolldown.config.js ├── readme.md ├── src/ │ ├── core/ │ │ ├── current.ts │ │ ├── finalize.ts │ │ ├── immerClass.ts │ │ ├── proxy.ts │ │ └── scope.ts │ ├── immer.ts │ ├── internal.ts │ ├── plugins/ │ │ ├── arrayMethods.ts │ │ ├── mapset.ts │ │ └── patches.ts │ ├── types/ │ │ ├── globals.d.ts │ │ ├── index.js.flow │ │ ├── types-external.ts │ │ └── types-internal.ts │ └── utils/ │ ├── common.ts │ ├── env.ts │ ├── errors.ts │ └── plugins.ts ├── tsconfig.json ├── tsup.config.ts ├── vitest-custom-reporter.ts ├── vitest.config.build.ts ├── vitest.config.ts └── website/ ├── docs/ │ ├── api.md │ ├── array-methods.md │ ├── async.mdx │ ├── built-with.md │ ├── complex-objects.md │ ├── current.md │ ├── curried-produce.mdx │ ├── example-setstate.mdx │ ├── faq.md │ ├── freezing.mdx │ ├── installation.mdx │ ├── introduction.md │ ├── map-set.md │ ├── original.md │ ├── other-lang.md │ ├── patches.mdx │ ├── performance.mdx │ ├── pitfalls.md │ ├── produce.mdx │ ├── resources.md │ ├── return.mdx │ ├── support.md │ ├── typescript.mdx │ └── update-patterns.md ├── docusaurus.config.js ├── i18n/ │ └── zh-CN/ │ ├── docusaurus-plugin-content-docs/ │ │ ├── current/ │ │ │ ├── api.md │ │ │ ├── async.mdx │ │ │ ├── built-with.md │ │ │ ├── complex-objects.md │ │ │ ├── current.md │ │ │ ├── curried-produce.mdx │ │ │ ├── example-setstate.mdx │ │ │ ├── faq.md │ │ │ ├── freezing.mdx │ │ │ ├── installation.mdx │ │ │ ├── introduction.md │ │ │ ├── map-set.md │ │ │ ├── original.md │ │ │ ├── other-lang.md │ │ │ ├── patches.mdx │ │ │ ├── performance.mdx │ │ │ ├── pitfalls.md │ │ │ ├── produce.mdx │ │ │ ├── resources.md │ │ │ ├── return.mdx │ │ │ ├── support.md │ │ │ ├── typescript.mdx │ │ │ └── update-patterns.md │ │ └── current.json │ └── docusaurus-theme-classic/ │ ├── footer.json │ └── navbar.json ├── package.json ├── sidebars.js ├── src/ │ └── css/ │ └── immer-infima.css └── static/ └── .nojekyll ================================================ FILE CONTENTS ================================================ ================================================ FILE: .codesandbox/ci.json ================================================ { "sandboxes": ["82zqr6n3kj"] } ================================================ FILE: .coveralls.yml ================================================ repo_token: EcsPD2u7ovNdmEGttaSGFaXqetDUAbnZ3 ================================================ FILE: .github/FUNDING.yml ================================================ open_collective: immer custom: https://www.paypal.me/michelweststrate patreon: mweststrate ================================================ FILE: .github/ISSUE_TEMPLATE/bug.md ================================================ --- name: 🐛 Bug report labels: about: Create a report to help us improve --- ## 🐛 Bug Report A clear and concise description of what the bug is. If your bug report involves classes, check the [docs](https://immerjs.github.io/immer/docs/complex-objects) on how classes are handled first. For patches, don't file issues if they are not optimal, only if they are incorrect. ## Link to repro _A bug report without a reproduction is not a bug report. Failing to follow this templately is likely to result in an immediate close & lock of the issue._ Please provide either a [CodeSandbox demo](https://codesandbox.io/s/immer-sandbox-6wijw), or a PR with a unit test. In limited cases, a _minimal_ repository on GitHub is accepted as well. ## To Reproduce Steps to reproduce the behavior: ## Observed behavior A description of what behavior you observed and why you consider it faulty. ## Expected behavior A clear and concise description of what you expected to happen instead. ## Environment We only accept bug reports against the latest Immer version. - **Immer version:** - [ ] I filed this report against the _latest_ version of Immer - [ ] Occurs with `setUseProxies(true)` - [ ] Occurs with `setUseProxies(false)` (ES5 only) ================================================ FILE: .github/ISSUE_TEMPLATE/feature.md ================================================ --- name: 🚀 Feature Proposal labels: "proposal" about: Submit a proposal for a new feature --- ## 🚀 Feature Proposal A clear and concise description of what the feature is. ## Motivation Please outline the motivation for the proposal. ## Can this be solved in user-land code? Request that can be solved in user-land code, or are out of scope of Immer (Immer is not a general data management library!) will typically be declined. We try to stay lean and mean here. ## Example Please provide an example for how this feature would be used. ================================================ FILE: .github/ISSUE_TEMPLATE/question.md ================================================ --- name: 🙋‍♂ Question labels: "question" about: Submit a generic question --- ## 🙋‍♂ Question A clear and concise description of what the question is. In general we recommend to use Stack Overflow for questions. Questions typically are processed with less priority. ## Link to repro Please provide a [CodeSandbox demo](https://codesandbox.io/s/immer-sandbox-6wijw) to clarify your question if possible. Typically, questions without minimal codesandbox demo won't be answered. ## Environment We only accept questions against the latest Immer version. - **Immer version:** - [ ] Occurs with `setUseProxies(true)` - [ ] Occurs with `setUseProxies(false)` (ES5 only) ================================================ FILE: .github/lock.yml ================================================ # Configuration for Lock Threads - https://github.com/dessant/lock-threads # Number of days of inactivity before a closed issue or pull request is locked daysUntilLock: 60 # Skip issues and pull requests created before a given timestamp. Timestamp must # follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable skipCreatedBefore: 2019-01-01 # Issues and pull requests with these labels will be ignored. Set to `[]` to disable exemptLabels: [] # Label to add before locking, such as `outdated`. Set to `false` to disable lockLabel: false # Comment to post before locking. Set to `false` to disable lockComment: > This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs or questions. # Assign `resolved` as the reason for locking. Set to `false` to disable setLockReason: true # Limit to only `issues` or `pulls` only: issues ================================================ FILE: .github/workflows/docs-public.yml ================================================ # This is a basic workflow to help you get started with Actions name: Public docs on: push: branches: [main] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" build: # The type of runner that the job will run on runs-on: ubuntu-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 - name: Build website run: cd website && yarn && yarn build - name: Deploy to GitHub Pages if: success() uses: crazy-max/ghaction-github-pages@v2 with: target_branch: gh-pages build_dir: website/build env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .github/workflows/release.yml ================================================ # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages name: Release on: push: branches: - main jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 20 - name: install run: yarn - name: test run: yarn test - name: build run: yarn build - name: publish # avoid release on fork if: github.repository == 'immerjs/immer' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: yarn semantic-release --branches main ================================================ FILE: .github/workflows/test.yml ================================================ # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions name: Test on: ["push", "pull_request"] jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: [20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} cache: "yarn" - name: yarn install run: yarn --frozen-lockfile - name: test run: yarn test - name: coverage test run: yarn coverage - name: perf test run: yarn test:perf - uses: coverallsapp/github-action@v1.1.2 with: github-token: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # nyc test coverage .nyc_output # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-waf configuration .lock-wscript # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ jspm_packages/ # Typescript v1 declaration files typings/ # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variables file .env .idea /dist* website/build website/.docusaurus .rts2* .gitpod.yml .watchman-cookie* ================================================ FILE: .prettierrc ================================================ { "bracketSpacing": false, "printWidth": 80, "proseWrap": "never", "requirePragma": false, "semi": false, "singleQuote": false, "trailingComma": "none", "useTabs": true, "overrides": [ { "files": [".prettierrc", "*.json"], "options": { "printWidth": 200, "tabWidth": 2, "useTabs": false } } ] } ================================================ FILE: .vscode/launch.json ================================================ { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { // Note; this config requires node 8.4 or higher "type": "node", "protocol": "auto", "request": "launch", "name": "debug unit test", "stopOnEntry": false, "program": "${workspaceRoot}/node_modules/jest-cli/bin/jest.js", "args": ["--verbose", "-i", "${file}"], "runtimeArgs": ["--nolazy"] } ] } ================================================ FILE: .vscode/settings.json ================================================ { "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "javascript.validate.enable": false, "typescript.tsdk": "node_modules/typescript/lib", "jest.enableInlineErrorMessages": true, "cSpell.enabled": true } ================================================ FILE: .watchmanconfig ================================================ { "ignore_dirs": ["node_modules", "_site", "dist", "coverage"] } ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2017 Michel Weststrate Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Supported Versions Latest only ## Reporting a Vulnerability Security issues can be reported at info@michel.codes. Since this software is provided as-is no follow up, remediation or time lines are guaranteed. ================================================ FILE: __performance_tests__/add-data.mjs ================================================ "use strict" import {measure} from "./measure.mjs" import {produce, setAutoFreeze} from "../dist/immer.mjs" import cloneDeep from "lodash.clonedeep" import immutable from "immutable" const {fromJS} = immutable import Seamless from "seamless-immutable" import deepFreeze from "deep-freeze" console.log("\n# add-data - loading large set of data\n") import dataSet from "./data.json" assert { type: "json" } const baseState = { data: null } const frozenBazeState = deepFreeze(cloneDeep(baseState)) const immutableJsBaseState = fromJS(baseState) const seamlessBaseState = Seamless.from(baseState) const MAX = 10000 measure( "just mutate", () => ({draft: cloneDeep(baseState)}), ({draft}) => { draft.data = dataSet } ) measure( "just mutate, freeze", () => ({draft: cloneDeep(baseState)}), ({draft}) => { draft.data = dataSet deepFreeze(draft) } ) measure("handcrafted reducer (no freeze)", () => { const nextState = { ...baseState, data: dataSet } }) measure("handcrafted reducer (with freeze)", () => { const nextState = deepFreeze({ ...baseState, data: dataSet }) }) measure("immutableJS", () => { let state = immutableJsBaseState.withMutations(state => { state.setIn(["data"], fromJS(dataSet)) }) }) measure("immutableJS + toJS", () => { let state = immutableJsBaseState .withMutations(state => { state.setIn(["data"], fromJS(dataSet)) }) .toJS() }) measure("seamless-immutable", () => { seamlessBaseState.set("data", dataSet) }) measure("seamless-immutable + asMutable", () => { seamlessBaseState.set("data", dataSet).asMutable({deep: true}) }) measure("immer - without autofreeze * " + MAX, () => { setAutoFreeze(false) for (let i = 0; i < MAX; i++) produce(baseState, draft => { draft.data = dataSet }) }) measure("immer - with autofreeze * " + MAX, () => { setAutoFreeze(true) for (let i = 0; i < MAX; i++) produce(frozenBazeState, draft => { draft.data = dataSet }) }) ================================================ FILE: __performance_tests__/data.json ================================================ [ { "_id": "5a5e4826a9061bfcf6184b5a", "index": 0, "guid": "a26788d1-2815-4018-88c0-2c6d1ba2667e", "isActive": false, "balance": "$3,980.02", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "green", "name": "Yates Hudson", "gender": "male", "company": "EXTRO", "email": "yateshudson@extro.com", "phone": "+1 (998) 553-2263", "address": "338 Fillmore Place, Marion, Mississippi, 7074", "about": "Sunt nisi aliqua aute culpa sint nulla irure aute ipsum laboris consequat mollit. Ut ex veniam ullamco consequat ut nisi veniam eiusmod eiusmod eu duis exercitation. Incididunt commodo ad aute occaecat nostrud duis. Irure labore est Lorem irure exercitation veniam. Eu id sint sunt aliquip quis consectetur amet Lorem. Commodo incididunt et dolore sunt dolor.\r\n", "registered": "2015-04-17T03:21:18 -02:00", "latitude": -46.587571, "longitude": -165.215982, "tags": [ "cupidatat", "non", "cupidatat", "esse", "veniam", "dolor", "cupidatat", "dolor", "ut", "eu" ], "friends": [ { "id": 0, "name": "Whitaker Montgomery" }, { "id": 1, "name": "Trevino Nelson" }, { "id": 2, "name": "Gallegos Patrick" }, { "id": 3, "name": "Mattie Burks" }, { "id": 4, "name": "Sweeney Dickerson" } ], "greeting": "Hello, Yates Hudson! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48262d8f809f405b6456", "index": 1, "guid": "6fb51448-783f-42d0-ab03-a3bcfeebd43d", "isActive": false, "balance": "$1,998.44", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "blue", "name": "Letitia Ortega", "gender": "female", "company": "OMATOM", "email": "letitiaortega@omatom.com", "phone": "+1 (901) 434-3696", "address": "781 Jackson Court, Starks, Guam, 2254", "about": "Dolor elit Lorem esse ea. Culpa commodo officia consequat nostrud dolore consequat sunt occaecat. Proident laborum exercitation consequat non minim excepteur amet consectetur consectetur proident. Enim esse sint eu non.\r\n", "registered": "2016-06-01T11:22:56 -02:00", "latitude": 5.631182, "longitude": 22.150513, "tags": [ "labore", "nulla", "laboris", "occaecat", "laborum", "nostrud", "aliqua", "amet", "esse", "duis" ], "friends": [ { "id": 0, "name": "Jarvis Dominguez" }, { "id": 1, "name": "Kendra Mercado" }, { "id": 2, "name": "Lizzie Conway" }, { "id": 3, "name": "Strickland Bean" }, { "id": 4, "name": "Francis Montoya" } ], "greeting": "Hello, Letitia Ortega! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826fef7a50dafbd00ed", "index": 2, "guid": "6b94722f-c9bb-4a31-a010-ec38d2bde335", "isActive": false, "balance": "$2,121.54", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Claire Sellers", "gender": "female", "company": "JUNIPOOR", "email": "clairesellers@junipoor.com", "phone": "+1 (904) 562-2518", "address": "158 Central Avenue, Vowinckel, Louisiana, 7462", "about": "Excepteur id amet aliqua tempor mollit nostrud aute proident. Sint reprehenderit do fugiat non magna. Nulla consectetur duis esse esse dolor aute est veniam cillum commodo voluptate. Reprehenderit ex nostrud laboris velit aliqua ex Lorem et. Enim proident eiusmod officia cupidatat commodo exercitation non.\r\n", "registered": "2017-09-26T05:21:49 -02:00", "latitude": -8.303996, "longitude": -129.33481, "tags": [ "id", "consequat", "fugiat", "qui", "est", "est", "fugiat", "veniam", "elit", "anim" ], "friends": [ { "id": 0, "name": "Luisa Holman" }, { "id": 1, "name": "Diana Floyd" }, { "id": 2, "name": "Owens Santana" }, { "id": 3, "name": "Farrell Tate" }, { "id": 4, "name": "Patrice Barber" } ], "greeting": "Hello, Claire Sellers! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826e23818870dd2621f", "index": 3, "guid": "104def5f-a6d9-4bb8-94dc-bc30eeaa89d3", "isActive": true, "balance": "$3,924.60", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Chang Sawyer", "gender": "male", "company": "BYTREX", "email": "changsawyer@bytrex.com", "phone": "+1 (942) 467-2001", "address": "720 Lafayette Walk, Gorst, South Dakota, 2611", "about": "Est ea proident amet reprehenderit qui. Duis velit pariatur proident ipsum id adipisicing veniam laboris dolor enim ex laborum dolor. Ut commodo do consectetur dolor reprehenderit ea aute tempor.\r\n", "registered": "2016-02-18T05:53:27 -01:00", "latitude": 38.344813, "longitude": 6.385098, "tags": [ "qui", "est", "cillum", "aute", "nisi", "esse", "laborum", "ullamco", "eu", "sint" ], "friends": [ { "id": 0, "name": "Naomi Harrington" }, { "id": 1, "name": "Regina Davenport" }, { "id": 2, "name": "Myers Ferguson" }, { "id": 3, "name": "Buckley Burch" }, { "id": 4, "name": "Vance Maynard" } ], "greeting": "Hello, Chang Sawyer! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ccde80f934165ce8", "index": 4, "guid": "aa51780c-4982-493d-9f60-1074e9378d89", "isActive": true, "balance": "$1,064.78", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Mallory Andrews", "gender": "female", "company": "ANDERSHUN", "email": "malloryandrews@andershun.com", "phone": "+1 (971) 539-2051", "address": "358 Division Avenue, Riner, District Of Columbia, 1114", "about": "Amet labore non proident elit. Labore esse ullamco cupidatat aliqua aliqua. Occaecat voluptate duis exercitation minim do duis non culpa tempor reprehenderit sunt nostrud sunt fugiat. Sit cillum exercitation culpa irure velit fugiat pariatur minim sit occaecat incididunt ea. Consequat laborum reprehenderit commodo aute tempor pariatur veniam laborum Lorem in dolor aliqua. Ipsum ea laboris voluptate consectetur esse. Sunt incididunt exercitation mollit id do commodo occaecat eiusmod culpa ex ea tempor voluptate elit.\r\n", "registered": "2018-01-10T12:46:48 -01:00", "latitude": 19.944778, "longitude": 0.202039, "tags": [ "aliquip", "ipsum", "qui", "id", "incididunt", "cupidatat", "qui", "ad", "sunt", "eiusmod" ], "friends": [ { "id": 0, "name": "Estelle Lott" }, { "id": 1, "name": "Walter Rojas" }, { "id": 2, "name": "Goodwin Lane" }, { "id": 3, "name": "Gonzalez Wells" }, { "id": 4, "name": "Shelly Mullins" } ], "greeting": "Hello, Mallory Andrews! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826343f61c695870c25", "index": 5, "guid": "1ed47068-7cae-4009-9cdb-fd452cfc7815", "isActive": false, "balance": "$1,854.69", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "blue", "name": "Shawna Schroeder", "gender": "female", "company": "PYRAMIS", "email": "shawnaschroeder@pyramis.com", "phone": "+1 (914) 580-2278", "address": "601 Eldert Street, Fredericktown, Puerto Rico, 784", "about": "Est eu commodo exercitation nisi elit laborum in sit magna. Nisi irure id nisi eiusmod consectetur pariatur et nisi qui qui. Nulla eiusmod anim esse enim quis ullamco Lorem aliqua dolor. Enim laborum excepteur incididunt sint ex consequat laborum pariatur. Sit laborum laboris minim excepteur pariatur nostrud laboris occaecat elit ipsum fugiat adipisicing ex. Officia nisi ullamco velit exercitation dolor fugiat non voluptate qui occaecat. Reprehenderit tempor veniam incididunt excepteur consequat cillum non nisi velit proident.\r\n", "registered": "2016-07-11T06:47:31 -02:00", "latitude": 2.881358, "longitude": 8.73891, "tags": [ "dolore", "enim", "sit", "et", "excepteur", "duis", "proident", "voluptate", "consequat", "ea" ], "friends": [ { "id": 0, "name": "Sheppard Frazier" }, { "id": 1, "name": "Clarke Robles" }, { "id": 2, "name": "Fay Beard" }, { "id": 3, "name": "Fern Stout" }, { "id": 4, "name": "Tanisha Cameron" } ], "greeting": "Hello, Shawna Schroeder! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48261d983cb3269eb414", "index": 6, "guid": "f7919c7d-7d3a-4fc4-b788-e1e00b07f911", "isActive": false, "balance": "$1,521.50", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "blue", "name": "Frances Briggs", "gender": "female", "company": "COMCUR", "email": "francesbriggs@comcur.com", "phone": "+1 (916) 454-3217", "address": "781 Battery Avenue, Shaft, Maine, 9666", "about": "Ea qui exercitation pariatur in labore velit amet minim consequat velit elit qui incididunt. Reprehenderit nulla qui enim duis ea laborum consequat. Irure id nisi consequat amet. Velit et pariatur Lorem do sunt incididunt excepteur.\r\n", "registered": "2016-05-22T10:14:26 -02:00", "latitude": 35.388453, "longitude": -87.230619, "tags": [ "labore", "magna", "est", "sunt", "non", "velit", "eu", "do", "consequat", "qui" ], "friends": [ { "id": 0, "name": "Marsha Dodson" }, { "id": 1, "name": "Jeannie Gross" }, { "id": 2, "name": "Sears Bridges" }, { "id": 3, "name": "Kay Todd" }, { "id": 4, "name": "Mari Simpson" } ], "greeting": "Hello, Frances Briggs! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ab15a28be85ec98d", "index": 7, "guid": "6a19d71d-b6fb-44e0-a013-d0217c1e61ea", "isActive": false, "balance": "$2,605.96", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "brown", "name": "Lambert Peck", "gender": "male", "company": "CYTREK", "email": "lambertpeck@cytrek.com", "phone": "+1 (821) 554-3164", "address": "920 Remsen Avenue, Biddle, New Jersey, 1527", "about": "Aliqua ut veniam esse irure occaecat nulla sunt. Culpa do quis ad incididunt labore consectetur. Minim fugiat enim incididunt voluptate laboris consectetur do exercitation ea occaecat elit. Nisi cillum non enim amet Lorem est in eu voluptate Lorem veniam. Minim elit et amet cillum. Esse labore deserunt cillum sint enim consequat.\r\n", "registered": "2014-09-21T12:39:07 -02:00", "latitude": 11.412462, "longitude": 56.021748, "tags": [ "occaecat", "mollit", "irure", "nostrud", "nostrud", "cupidatat", "Lorem", "elit", "mollit", "sit" ], "friends": [ { "id": 0, "name": "Joyce Marquez" }, { "id": 1, "name": "Ines Medina" }, { "id": 2, "name": "Marian Snider" }, { "id": 3, "name": "Noemi Nieves" }, { "id": 4, "name": "Short Pugh" } ], "greeting": "Hello, Lambert Peck! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826cefe1e4dd2aa6e13", "index": 8, "guid": "bf593920-ca9b-40f0-b48e-95d90040281a", "isActive": false, "balance": "$3,739.68", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Ratliff Young", "gender": "male", "company": "OLUCORE", "email": "ratliffyoung@olucore.com", "phone": "+1 (933) 588-2877", "address": "308 Will Place, Fairmount, Michigan, 702", "about": "Culpa sunt laboris sunt adipisicing. Ut dolore enim eu cillum do qui minim ea dolore. Officia pariatur enim fugiat aliquip minim culpa id excepteur laborum cillum veniam ipsum.\r\n", "registered": "2014-12-19T11:33:31 -01:00", "latitude": 66.699271, "longitude": 79.298368, "tags": [ "elit", "fugiat", "aliqua", "nulla", "incididunt", "non", "voluptate", "laboris", "esse", "id" ], "friends": [ { "id": 0, "name": "Jeanne Garza" }, { "id": 1, "name": "Rios Tyson" }, { "id": 2, "name": "Bush Dalton" }, { "id": 3, "name": "Shields Pearson" }, { "id": 4, "name": "Minerva Sloan" } ], "greeting": "Hello, Ratliff Young! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c572b42a02515c87", "index": 9, "guid": "1166fc8b-0464-4395-8501-e79b0fd45fa2", "isActive": true, "balance": "$1,812.89", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "green", "name": "Myrtle Wade", "gender": "female", "company": "NAMEBOX", "email": "myrtlewade@namebox.com", "phone": "+1 (945) 600-2293", "address": "174 Burnett Street, Allison, Rhode Island, 3044", "about": "Voluptate ea esse voluptate quis ullamco consectetur. Reprehenderit elit qui cupidatat adipisicing laboris nisi dolore id ipsum adipisicing. Fugiat officia cillum est esse incididunt. Aute voluptate reprehenderit tempor sunt non quis laboris minim. Ut cillum eu amet deserunt minim anim. Sint laborum qui duis do ea magna dolore nisi incididunt eu irure amet dolor.\r\n", "registered": "2017-10-27T12:30:14 -02:00", "latitude": 38.003082, "longitude": -15.190544, "tags": [ "consectetur", "proident", "mollit", "do", "officia", "voluptate", "qui", "ex", "nostrud", "cillum" ], "friends": [ { "id": 0, "name": "Ballard Burt" }, { "id": 1, "name": "Loretta Shelton" }, { "id": 2, "name": "Tracey Combs" }, { "id": 3, "name": "Vicki Duncan" }, { "id": 4, "name": "Ilene Holmes" } ], "greeting": "Hello, Myrtle Wade! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48262a86859b60637059", "index": 10, "guid": "c0a0aa75-b9bd-4010-9899-c33b5f1cf467", "isActive": false, "balance": "$3,851.63", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "brown", "name": "Karla Moss", "gender": "female", "company": "BALOOBA", "email": "karlamoss@balooba.com", "phone": "+1 (982) 471-2628", "address": "898 Knight Court, Cochranville, Kansas, 6514", "about": "Sint commodo culpa qui cillum nisi tempor laboris laborum exercitation qui Lorem culpa. Cillum et nisi ad ea. Ipsum ad quis sint proident sunt elit.\r\n", "registered": "2014-03-25T06:51:19 -01:00", "latitude": -84.28587, "longitude": 141.360447, "tags": [ "anim", "laborum", "Lorem", "dolor", "sint", "non", "et", "velit", "cillum", "ea" ], "friends": [ { "id": 0, "name": "Mayer Gill" }, { "id": 1, "name": "Blair Roy" }, { "id": 2, "name": "Church Duke" }, { "id": 3, "name": "Tina Rush" }, { "id": 4, "name": "Rosella Wall" } ], "greeting": "Hello, Karla Moss! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c37894cb0447d91c", "index": 11, "guid": "53dcc9e1-5044-4efc-b3b0-9c71922b3124", "isActive": true, "balance": "$2,802.34", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Caldwell Cervantes", "gender": "male", "company": "EXOSPEED", "email": "caldwellcervantes@exospeed.com", "phone": "+1 (909) 409-3787", "address": "674 Hunts Lane, Cawood, West Virginia, 5766", "about": "Ex mollit magna excepteur ipsum aliqua nisi. Sunt eiusmod qui ullamco sint consequat. Id labore cillum esse ut id dolor enim et sint labore proident nisi eu.\r\n", "registered": "2017-04-06T05:25:24 -02:00", "latitude": 72.5169, "longitude": -157.547122, "tags": [ "qui", "do", "duis", "velit", "esse", "veniam", "enim", "quis", "cupidatat", "cupidatat" ], "friends": [ { "id": 0, "name": "Rosales Chan" }, { "id": 1, "name": "Meadows Hewitt" }, { "id": 2, "name": "Deanna Witt" }, { "id": 3, "name": "Kimberly Marshall" }, { "id": 4, "name": "Aisha Ruiz" } ], "greeting": "Hello, Caldwell Cervantes! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826589c958a758c91c0", "index": 12, "guid": "d3374826-acc5-4fb9-a1f5-8dbfebdc2cbd", "isActive": true, "balance": "$2,108.09", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "brown", "name": "Foreman Richard", "gender": "male", "company": "SPORTAN", "email": "foremanrichard@sportan.com", "phone": "+1 (927) 429-2799", "address": "718 Lawn Court, Cloverdale, American Samoa, 7939", "about": "Dolore velit laboris aliqua nisi cillum cillum dolor. Laborum id nulla exercitation irure aute amet nostrud. Officia voluptate amet aliquip in laborum ullamco eiusmod sunt irure ut sint deserunt sunt. Quis laboris aliquip id deserunt anim. Ipsum elit commodo ut mollit velit proident labore cupidatat exercitation consectetur anim laboris. Proident et duis non dolor sunt dolor aute dolor culpa ea nostrud do duis quis.\r\n", "registered": "2017-05-31T01:45:06 -02:00", "latitude": 36.582108, "longitude": 146.737135, "tags": [ "cupidatat", "cupidatat", "consectetur", "officia", "consectetur", "irure", "quis", "Lorem", "aliquip", "dolore" ], "friends": [ { "id": 0, "name": "Quinn Cook" }, { "id": 1, "name": "Paige Alvarez" }, { "id": 2, "name": "Bolton Gardner" }, { "id": 3, "name": "Michael West" }, { "id": 4, "name": "Tiffany Carter" } ], "greeting": "Hello, Foreman Richard! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ad4d1a3649f55365", "index": 13, "guid": "b3cdda29-1d1c-4f36-a2d2-e5097f0367b2", "isActive": true, "balance": "$2,978.98", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "brown", "name": "Reba Farmer", "gender": "female", "company": "EQUITOX", "email": "rebafarmer@equitox.com", "phone": "+1 (843) 557-2223", "address": "296 McKibbin Street, Jamestown, Maryland, 6158", "about": "Est Lorem elit eiusmod eu enim consectetur irure quis. Ea est dolore exercitation et cillum. Eu pariatur quis eiusmod esse cillum sit ad anim labore consequat eiusmod eiusmod. Id ad culpa nisi occaecat consectetur. Sunt consectetur excepteur esse enim ad cillum ullamco cillum dolore Lorem magna proident elit fugiat.\r\n", "registered": "2014-02-16T12:33:00 -01:00", "latitude": 55.983489, "longitude": 149.694175, "tags": [ "adipisicing", "culpa", "laborum", "ullamco", "incididunt", "duis", "culpa", "veniam", "occaecat", "nulla" ], "friends": [ { "id": 0, "name": "Bethany Michael" }, { "id": 1, "name": "Dale Joseph" }, { "id": 2, "name": "Callie Bird" }, { "id": 3, "name": "Hale Humphrey" }, { "id": 4, "name": "Daniels Bray" } ], "greeting": "Hello, Reba Farmer! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826fada0aadea0d3573", "index": 14, "guid": "8752d3c2-1a52-474d-ab5f-325cc77a9027", "isActive": true, "balance": "$2,782.86", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "brown", "name": "Alexandria Moody", "gender": "female", "company": "CEPRENE", "email": "alexandriamoody@ceprene.com", "phone": "+1 (997) 578-3432", "address": "624 Douglass Street, Rockhill, California, 5972", "about": "Qui laboris occaecat veniam anim reprehenderit esse adipisicing excepteur adipisicing est. Lorem dolor non in est dolore sunt aliqua id nisi magna. Ad irure enim aute irure aliquip eiusmod. Est eiusmod pariatur laborum in labore consequat cupidatat magna quis tempor duis exercitation nisi. Ut irure ut sunt id.\r\n", "registered": "2015-01-04T04:26:57 -01:00", "latitude": 35.089776, "longitude": 132.40054, "tags": [ "aliquip", "ea", "aliqua", "reprehenderit", "occaecat", "cupidatat", "elit", "eiusmod", "qui", "fugiat" ], "friends": [ { "id": 0, "name": "Coffey Hatfield" }, { "id": 1, "name": "Haley Clayton" }, { "id": 2, "name": "Black Mcbride" }, { "id": 3, "name": "Mitchell Barlow" }, { "id": 4, "name": "William Mcgowan" } ], "greeting": "Hello, Alexandria Moody! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f660319ea93a529c", "index": 15, "guid": "5d91aa74-a204-4ecb-a02a-5479a7c97ee7", "isActive": false, "balance": "$3,066.50", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Dixie Hancock", "gender": "female", "company": "MANTRO", "email": "dixiehancock@mantro.com", "phone": "+1 (988) 516-3066", "address": "729 Hubbard Place, Neahkahnie, Utah, 1607", "about": "Pariatur amet amet et minim. Consectetur consequat sunt sint voluptate labore nostrud velit commodo eiusmod velit eu tempor. Proident sint ea ipsum anim excepteur irure occaecat ullamco sit mollit anim dolor ullamco. Eu esse ipsum exercitation deserunt fugiat dolore. Cupidatat officia elit esse minim eu sunt. Labore amet dolor excepteur non ipsum adipisicing Lorem esse culpa dolor dolor velit consectetur. Sunt ipsum culpa esse esse pariatur tempor proident.\r\n", "registered": "2017-12-19T11:29:33 -01:00", "latitude": 18.767575, "longitude": 73.219373, "tags": [ "occaecat", "culpa", "consectetur", "elit", "et", "sit", "voluptate", "aliqua", "irure", "quis" ], "friends": [ { "id": 0, "name": "Conway Preston" }, { "id": 1, "name": "Beck Marks" }, { "id": 2, "name": "Daisy Carson" }, { "id": 3, "name": "Wong Quinn" }, { "id": 4, "name": "Keisha Warren" } ], "greeting": "Hello, Dixie Hancock! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48262e7781a67f814c8c", "index": 16, "guid": "b20bfa8e-c2ea-4047-8646-f59ca0eb7a51", "isActive": true, "balance": "$3,639.45", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "brown", "name": "Larson Copeland", "gender": "male", "company": "KAGE", "email": "larsoncopeland@kage.com", "phone": "+1 (858) 497-2454", "address": "390 Hawthorne Street, Cataract, Iowa, 4802", "about": "Dolore sit commodo eiusmod ut sunt ut tempor consequat. Duis minim sit pariatur proident culpa. Incididunt in fugiat anim officia aute quis amet minim sunt esse aliqua ut id. Non velit occaecat laboris aliquip fugiat sit elit in culpa commodo excepteur dolore eiusmod aliqua. Incididunt proident qui sit ex sit irure labore tempor dolore. Adipisicing sint non nisi ipsum velit et dolore aute amet ullamco ipsum. Officia voluptate voluptate cupidatat fugiat duis in proident deserunt voluptate.\r\n", "registered": "2017-03-13T04:56:22 -01:00", "latitude": 21.46204, "longitude": 173.921282, "tags": [ "ea", "duis", "adipisicing", "mollit", "esse", "minim", "commodo", "labore", "aliqua", "mollit" ], "friends": [ { "id": 0, "name": "Davidson Buchanan" }, { "id": 1, "name": "Ina Roberts" }, { "id": 2, "name": "Nina Clements" }, { "id": 3, "name": "Kathrine Figueroa" }, { "id": 4, "name": "Staci Weaver" } ], "greeting": "Hello, Larson Copeland! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826927e6fa042a226b8", "index": 17, "guid": "993920db-4b00-4f6e-8a26-fa1364046a3f", "isActive": true, "balance": "$3,089.29", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Dunlap Rasmussen", "gender": "male", "company": "ZANILLA", "email": "dunlaprasmussen@zanilla.com", "phone": "+1 (992) 482-3097", "address": "865 Visitation Place, Greer, North Dakota, 5046", "about": "Minim anim fugiat id officia ea qui consequat est officia aliquip irure qui. Consectetur consequat irure labore excepteur tempor veniam aliquip minim do. Voluptate duis ea sint magna esse pariatur pariatur aliquip. Sint reprehenderit fugiat aliquip id reprehenderit id ea esse culpa adipisicing.\r\n", "registered": "2016-06-17T01:41:28 -02:00", "latitude": -42.286095, "longitude": 170.172008, "tags": [ "dolore", "non", "ad", "ad", "nisi", "nisi", "id", "aliqua", "adipisicing", "cupidatat" ], "friends": [ { "id": 0, "name": "Natalia Hoffman" }, { "id": 1, "name": "Myra Scott" }, { "id": 2, "name": "Graves Raymond" }, { "id": 3, "name": "Valdez Atkins" }, { "id": 4, "name": "Allen Dickson" } ], "greeting": "Hello, Dunlap Rasmussen! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48269869075ea7708d94", "index": 18, "guid": "3b114586-9808-47aa-a53d-98eb4a970518", "isActive": true, "balance": "$2,613.09", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "blue", "name": "Acosta Mcguire", "gender": "male", "company": "MICRONAUT", "email": "acostamcguire@micronaut.com", "phone": "+1 (866) 479-3103", "address": "576 Bokee Court, Matheny, Kentucky, 2132", "about": "Duis elit ut officia deserunt. Laborum culpa adipisicing tempor ex esse fugiat magna veniam voluptate Lorem et nostrud ea. Occaecat sunt irure nostrud sit aliquip ex deserunt officia. Anim cillum fugiat id eu minim sit.\r\n", "registered": "2014-03-11T04:47:14 -01:00", "latitude": -2.283186, "longitude": 34.78155, "tags": [ "veniam", "non", "nulla", "exercitation", "enim", "non", "laboris", "ex", "voluptate", "eu" ], "friends": [ { "id": 0, "name": "Booth Osborn" }, { "id": 1, "name": "Conrad Fields" }, { "id": 2, "name": "Frye Dillard" }, { "id": 3, "name": "Lynch Jarvis" }, { "id": 4, "name": "Christian Hubbard" } ], "greeting": "Hello, Acosta Mcguire! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826a3a1285d73c248bd", "index": 19, "guid": "f649fdf1-c1cf-4df3-832a-e0ec3d150f70", "isActive": true, "balance": "$3,016.72", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "brown", "name": "Wood Elliott", "gender": "male", "company": "KONNECT", "email": "woodelliott@konnect.com", "phone": "+1 (986) 536-2957", "address": "902 Montana Place, Chumuckla, Colorado, 2890", "about": "Tempor dolore mollit proident fugiat velit dolore. Id sit cillum consequat culpa. Minim qui ipsum nisi cupidatat quis pariatur excepteur. Proident ullamco laborum do ut sunt dolore. Ea amet tempor ad cillum pariatur ad ad.\r\n", "registered": "2016-08-11T09:33:56 -02:00", "latitude": 1.108328, "longitude": -148.073999, "tags": [ "aliqua", "duis", "tempor", "ut", "cillum", "non", "sunt", "tempor", "sunt", "minim" ], "friends": [ { "id": 0, "name": "Langley Davidson" }, { "id": 1, "name": "Kristie Cole" }, { "id": 2, "name": "Carla William" }, { "id": 3, "name": "Macias Pollard" }, { "id": 4, "name": "Myrna Green" } ], "greeting": "Hello, Wood Elliott! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826439ed2ec654afbe4", "index": 20, "guid": "75d75041-86cf-457a-8185-a30992ab5dfc", "isActive": false, "balance": "$2,768.42", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Conner Hampton", "gender": "male", "company": "ARTWORLDS", "email": "connerhampton@artworlds.com", "phone": "+1 (834) 510-3051", "address": "209 National Drive, Bainbridge, New Hampshire, 8521", "about": "Incididunt occaecat in amet commodo nisi esse Lorem proident ex exercitation est. In adipisicing excepteur deserunt excepteur est et mollit ea. Laborum elit qui culpa duis mollit. In cupidatat sunt sit quis enim laborum excepteur Lorem eiusmod ex duis tempor commodo ipsum. Aliquip reprehenderit fugiat ut minim esse excepteur eiusmod excepteur Lorem Lorem. Cillum nostrud eu incididunt dolore dolor. Ipsum cupidatat exercitation adipisicing nisi laboris sint laboris in ut ut.\r\n", "registered": "2017-05-04T08:38:56 -02:00", "latitude": 22.862427, "longitude": 120.64414, "tags": [ "pariatur", "sint", "duis", "esse", "minim", "ad", "sunt", "dolor", "sunt", "dolore" ], "friends": [ { "id": 0, "name": "Mercer Abbott" }, { "id": 1, "name": "Sophie Campos" }, { "id": 2, "name": "Tonya Pickett" }, { "id": 3, "name": "Kristina Ingram" }, { "id": 4, "name": "Carmela Howell" } ], "greeting": "Hello, Conner Hampton! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826d69021a6f65fdfb3", "index": 21, "guid": "ed8e3f49-7d02-4285-8510-67f311260986", "isActive": true, "balance": "$2,923.04", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Cole Greene", "gender": "male", "company": "HOMETOWN", "email": "colegreene@hometown.com", "phone": "+1 (869) 403-3686", "address": "808 Maple Street, Stockdale, Wisconsin, 710", "about": "Duis mollit consequat anim est mollit elit labore adipisicing anim minim laborum do ut. Mollit tempor excepteur quis officia incididunt nostrud qui nisi id consequat veniam ipsum irure. In mollit proident reprehenderit laborum aliqua cillum ad enim cupidatat. Amet occaecat aliqua sint sint nostrud.\r\n", "registered": "2017-05-29T04:23:32 -02:00", "latitude": -21.764898, "longitude": 42.346497, "tags": [ "incididunt", "eu", "excepteur", "consectetur", "quis", "velit", "aute", "excepteur", "eu", "ad" ], "friends": [ { "id": 0, "name": "Noreen Christensen" }, { "id": 1, "name": "Mann Miles" }, { "id": 2, "name": "Dorothy Holden" }, { "id": 3, "name": "Claudia Newton" }, { "id": 4, "name": "Abbott Bowen" } ], "greeting": "Hello, Cole Greene! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826aef1c6014dc01146", "index": 22, "guid": "0ec634ae-13ba-4c44-99de-09642456444a", "isActive": false, "balance": "$1,570.19", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "green", "name": "Jerry Griffith", "gender": "female", "company": "CRUSTATIA", "email": "jerrygriffith@crustatia.com", "phone": "+1 (936) 460-2262", "address": "903 Royce Place, Longoria, Idaho, 4485", "about": "Qui dolor do irure laboris ut. Sit anim tempor reprehenderit sit sit in adipisicing cillum. Reprehenderit sunt eu pariatur culpa cupidatat consectetur nulla voluptate est. Enim ut proident elit aliqua sit amet laboris enim et do ex nostrud. Pariatur laborum minim cillum laborum cillum enim. Veniam proident ullamco est quis.\r\n", "registered": "2014-02-21T08:40:40 -01:00", "latitude": -89.906506, "longitude": 174.810933, "tags": [ "nostrud", "culpa", "adipisicing", "incididunt", "sint", "ullamco", "ut", "officia", "elit", "esse" ], "friends": [ { "id": 0, "name": "Olive Martin" }, { "id": 1, "name": "Odom Glass" }, { "id": 2, "name": "Rogers Barker" }, { "id": 3, "name": "Garrison Torres" }, { "id": 4, "name": "Hooper Beasley" } ], "greeting": "Hello, Jerry Griffith! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826a93ae5589aa97d1e", "index": 23, "guid": "02d26d85-cee0-4866-b17c-7d41554edc86", "isActive": true, "balance": "$1,788.94", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Cunningham Roman", "gender": "male", "company": "PURIA", "email": "cunninghamroman@puria.com", "phone": "+1 (804) 495-3519", "address": "449 Bancroft Place, Farmington, Georgia, 7332", "about": "Lorem laboris labore officia sint culpa reprehenderit reprehenderit. Proident pariatur laborum tempor excepteur eiusmod aliqua. Quis voluptate adipisicing exercitation fugiat nostrud eiusmod consequat nulla occaecat aliqua ad eiusmod deserunt veniam. Aliqua in tempor ullamco quis consequat mollit Lorem qui velit officia enim ea nulla. Lorem proident qui elit excepteur.\r\n", "registered": "2015-03-12T08:55:51 -01:00", "latitude": -1.94298, "longitude": -29.700733, "tags": [ "Lorem", "deserunt", "qui", "Lorem", "amet", "incididunt", "commodo", "laborum", "non", "aliquip" ], "friends": [ { "id": 0, "name": "Sharron Powell" }, { "id": 1, "name": "Griffith Booker" }, { "id": 2, "name": "Ana Garcia" }, { "id": 3, "name": "Annabelle Grant" }, { "id": 4, "name": "Tisha Wilkinson" } ], "greeting": "Hello, Cunningham Roman! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48265b7556aa890d504c", "index": 24, "guid": "e92bc884-a19a-4929-88b3-7e83dc576a6d", "isActive": true, "balance": "$3,231.51", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "green", "name": "Dollie Delaney", "gender": "female", "company": "PANZENT", "email": "dolliedelaney@panzent.com", "phone": "+1 (938) 567-3531", "address": "853 Barwell Terrace, Williams, Virgin Islands, 8601", "about": "Esse non commodo nisi non. Ullamco laboris tempor consectetur nisi id aliquip elit cillum laborum. Occaecat culpa magna id in eiusmod ipsum consectetur consectetur duis exercitation. Consectetur ex reprehenderit dolore elit qui ullamco nisi id ullamco officia et ea aute nostrud. Quis mollit deserunt eu pariatur.\r\n", "registered": "2015-09-28T09:58:35 -02:00", "latitude": 70.920678, "longitude": 81.202664, "tags": [ "Lorem", "culpa", "sint", "magna", "esse", "dolor", "irure", "do", "nostrud", "tempor" ], "friends": [ { "id": 0, "name": "Butler Logan" }, { "id": 1, "name": "Robert Reid" }, { "id": 2, "name": "Cote Kinney" }, { "id": 3, "name": "Ryan Graves" }, { "id": 4, "name": "Becky Berry" } ], "greeting": "Hello, Dollie Delaney! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826ccdbb59b899dde61", "index": 25, "guid": "51ff9ab1-2c6b-460a-813c-4c033bd10f7a", "isActive": false, "balance": "$2,518.87", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Wright Ramsey", "gender": "male", "company": "TROLLERY", "email": "wrightramsey@trollery.com", "phone": "+1 (895) 535-2459", "address": "980 Crystal Street, Grazierville, Minnesota, 2923", "about": "Enim magna Lorem non sit exercitation ullamco ullamco laborum minim commodo ea deserunt ut velit. Reprehenderit proident eiusmod aute anim aliqua nostrud proident proident. Tempor esse occaecat aute est amet consequat proident nulla duis cupidatat Lorem laborum esse. Amet labore anim enim laborum pariatur do pariatur pariatur sunt officia irure fugiat magna non. Aliqua magna et duis officia voluptate. Nulla duis nulla laboris qui anim ea veniam officia ullamco velit velit fugiat tempor. Commodo minim consectetur ea commodo velit veniam culpa dolor sint duis eu aute commodo sint.\r\n", "registered": "2016-11-25T12:30:36 -01:00", "latitude": 6.731527, "longitude": 126.276599, "tags": [ "est", "consequat", "duis", "amet", "qui", "in", "et", "esse", "commodo", "ipsum" ], "friends": [ { "id": 0, "name": "Pace Richmond" }, { "id": 1, "name": "Harris Kline" }, { "id": 2, "name": "Peggy Peterson" }, { "id": 3, "name": "Vazquez Bentley" }, { "id": 4, "name": "Oneal Wagner" } ], "greeting": "Hello, Wright Ramsey! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c6b9ab14d52b39d4", "index": 26, "guid": "ee84f398-aa03-42fd-bcfe-6b9395ab4ef4", "isActive": false, "balance": "$1,265.85", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "green", "name": "Snow Shepard", "gender": "male", "company": "ZORK", "email": "snowshepard@zork.com", "phone": "+1 (939) 471-3758", "address": "843 Grant Avenue, Robinson, South Carolina, 4868", "about": "Sit ea non esse cupidatat mollit. Quis quis sint ullamco qui tempor et id minim ad occaecat cupidatat. Ipsum cupidatat velit cupidatat cillum incididunt ut duis aliqua. Fugiat eiusmod commodo tempor amet amet aliquip cupidatat veniam do. Enim minim velit id enim aliqua laboris ut eu fugiat. Anim ullamco consequat velit proident quis amet. Pariatur incididunt ut sunt elit do.\r\n", "registered": "2017-08-24T10:59:47 -02:00", "latitude": 45.989546, "longitude": -96.791778, "tags": [ "aliquip", "culpa", "consequat", "consectetur", "ea", "officia", "elit", "nostrud", "quis", "tempor" ], "friends": [ { "id": 0, "name": "Sondra Merrill" }, { "id": 1, "name": "Cathy Armstrong" }, { "id": 2, "name": "Marcy Shepherd" }, { "id": 3, "name": "Knox Spence" }, { "id": 4, "name": "Thelma Conrad" } ], "greeting": "Hello, Snow Shepard! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826ded6dd8e567858b4", "index": 27, "guid": "5639a3ce-03e9-4800-a01c-de92f1bddc52", "isActive": true, "balance": "$2,005.87", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Cash Wolf", "gender": "male", "company": "COMVEYOR", "email": "cashwolf@comveyor.com", "phone": "+1 (835) 527-3713", "address": "163 Chester Avenue, Ada, Northern Mariana Islands, 211", "about": "Eu exercitation anim velit officia magna proident in occaecat fugiat nisi eu eiusmod. Laboris minim incididunt ex nostrud. Ullamco esse cillum eu sint magna laborum consectetur elit aute laboris in. Ipsum magna quis commodo aute elit pariatur adipisicing incididunt ut consectetur anim eiusmod. Minim do reprehenderit aliquip commodo eiusmod magna enim sint consequat ullamco. Esse exercitation sint fugiat occaecat amet officia aute ea.\r\n", "registered": "2014-03-07T05:02:27 -01:00", "latitude": -20.427825, "longitude": -31.971807, "tags": [ "cupidatat", "labore", "occaecat", "tempor", "adipisicing", "nulla", "magna", "occaecat", "reprehenderit", "adipisicing" ], "friends": [ { "id": 0, "name": "Moon Myers" }, { "id": 1, "name": "Margret Bullock" }, { "id": 2, "name": "Rocha Navarro" }, { "id": 3, "name": "Moreno Haynes" }, { "id": 4, "name": "Wiggins Benson" } ], "greeting": "Hello, Cash Wolf! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48262d1c7eaabe072697", "index": 28, "guid": "5cd7a4e4-2481-4d6d-a013-6b5433632ac5", "isActive": false, "balance": "$2,685.60", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Cleo Stuart", "gender": "female", "company": "FLEXIGEN", "email": "cleostuart@flexigen.com", "phone": "+1 (849) 432-3327", "address": "412 Cherry Street, Westphalia, Pennsylvania, 2074", "about": "Occaecat ea proident nostrud minim nisi non aliquip ea veniam veniam ut magna qui. Occaecat do eu ea aliquip sit excepteur proident laborum laboris ullamco duis. Ut cupidatat culpa aute esse. Elit excepteur et aliquip eu eu proident nisi Lorem nostrud irure. Eu id Lorem mollit magna excepteur. Dolore proident sunt cillum nostrud anim adipisicing et velit minim. Ipsum dolore cupidatat minim est voluptate deserunt reprehenderit ipsum dolore minim duis commodo tempor do.\r\n", "registered": "2016-09-11T11:19:30 -02:00", "latitude": 35.904247, "longitude": -98.691594, "tags": [ "id", "ea", "ullamco", "duis", "enim", "proident", "et", "adipisicing", "tempor", "voluptate" ], "friends": [ { "id": 0, "name": "Patty Sweet" }, { "id": 1, "name": "Carrillo Watts" }, { "id": 2, "name": "Figueroa Sims" }, { "id": 3, "name": "Goff Hernandez" }, { "id": 4, "name": "York Knox" } ], "greeting": "Hello, Cleo Stuart! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482697428618c6bfa0b8", "index": 29, "guid": "6d1ab961-ccfa-42e0-bb41-9c74a47aa251", "isActive": false, "balance": "$1,367.61", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Angel Norris", "gender": "female", "company": "DREAMIA", "email": "angelnorris@dreamia.com", "phone": "+1 (898) 447-3134", "address": "596 Campus Road, Waverly, Arkansas, 1917", "about": "Irure labore anim sit pariatur excepteur ipsum occaecat laborum dolore enim et pariatur pariatur. Eiusmod commodo ut ullamco deserunt tempor duis fugiat aliquip est excepteur sunt proident incididunt. Nulla sunt esse id enim excepteur dolor cillum id minim. Voluptate exercitation cupidatat nostrud eiusmod irure eu. Aliqua occaecat do velit id aliquip velit enim fugiat veniam adipisicing laboris aute nostrud.\r\n", "registered": "2015-12-12T10:36:31 -01:00", "latitude": 14.169491, "longitude": 128.286099, "tags": [ "est", "sit", "sit", "sunt", "voluptate", "ipsum", "do", "tempor", "enim", "fugiat" ], "friends": [ { "id": 0, "name": "Ester Cotton" }, { "id": 1, "name": "Therese Guzman" }, { "id": 2, "name": "Emilia Ferrell" }, { "id": 3, "name": "Maude Nichols" }, { "id": 4, "name": "Elvia Flores" } ], "greeting": "Hello, Angel Norris! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482621f3417f0ed7eeb3", "index": 30, "guid": "7c38399a-e40e-4cee-b776-06a20243386a", "isActive": false, "balance": "$3,059.42", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "brown", "name": "Gaines Cabrera", "gender": "male", "company": "QUALITERN", "email": "gainescabrera@qualitern.com", "phone": "+1 (936) 534-3780", "address": "959 George Street, Joppa, Palau, 1149", "about": "Sunt commodo sint et eiusmod cupidatat. Occaecat nisi cillum aliqua do minim dolor amet laboris. Nostrud exercitation esse deserunt aliquip voluptate est reprehenderit do consequat Lorem. Est anim quis adipisicing Lorem velit. Et voluptate ad sunt sint eiusmod consequat cupidatat culpa est culpa ipsum.\r\n", "registered": "2015-08-07T03:38:19 -02:00", "latitude": -6.205206, "longitude": -21.271189, "tags": [ "quis", "nulla", "ex", "exercitation", "irure", "dolore", "aute", "tempor", "excepteur", "ex" ], "friends": [ { "id": 0, "name": "Carolina Hunter" }, { "id": 1, "name": "Schmidt Hanson" }, { "id": 2, "name": "Medina Stevenson" }, { "id": 3, "name": "Cherry Lowe" }, { "id": 4, "name": "French Wise" } ], "greeting": "Hello, Gaines Cabrera! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48264af983a4dc84b5df", "index": 31, "guid": "b7bbc2fe-9f06-46a3-9c85-6b698832f042", "isActive": false, "balance": "$3,510.22", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Morse Conner", "gender": "male", "company": "AMRIL", "email": "morseconner@amril.com", "phone": "+1 (829) 583-2993", "address": "721 Flatlands Avenue, Crayne, Connecticut, 6482", "about": "Lorem excepteur voluptate aliquip tempor laborum sit. Esse ad in quis laborum dolor tempor quis tempor voluptate adipisicing dolore sit exercitation incididunt. Lorem exercitation dolore enim aliqua anim labore culpa cupidatat consectetur irure ullamco duis tempor. Lorem tempor cupidatat minim commodo sint anim cupidatat exercitation enim consequat velit duis voluptate. Enim nulla voluptate laboris reprehenderit reprehenderit minim. Deserunt incididunt sit enim ipsum pariatur. Fugiat tempor Lorem officia reprehenderit sit do ea velit.\r\n", "registered": "2017-11-23T04:49:43 -01:00", "latitude": -40.154222, "longitude": 82.631925, "tags": [ "velit", "est", "consectetur", "enim", "irure", "ullamco", "id", "tempor", "non", "est" ], "friends": [ { "id": 0, "name": "Karina Mcdowell" }, { "id": 1, "name": "Hazel Middleton" }, { "id": 2, "name": "Mosley Guthrie" }, { "id": 3, "name": "Kitty Chandler" }, { "id": 4, "name": "Wheeler Mclaughlin" } ], "greeting": "Hello, Morse Conner! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826f734f48d3eb6c950", "index": 32, "guid": "88bc433e-306d-4f1a-9395-187a7354d224", "isActive": true, "balance": "$1,573.97", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "brown", "name": "Peck Lucas", "gender": "male", "company": "CENTURIA", "email": "pecklucas@centuria.com", "phone": "+1 (914) 471-2155", "address": "317 Noel Avenue, Strykersville, North Carolina, 894", "about": "Amet et ullamco deserunt sit id ex laboris Lorem pariatur incididunt est. Ex duis duis cupidatat eiusmod eu laborum in aute. Laboris laborum officia aliqua laborum velit fugiat veniam elit et veniam sit. Incididunt sit velit voluptate amet incididunt aliquip officia ullamco incididunt. Id nulla sit do aliquip. Ea tempor aute quis ex ad amet eiusmod enim tempor anim. Laborum sint deserunt nulla culpa dolor consectetur id duis laboris culpa minim sunt.\r\n", "registered": "2014-01-06T04:54:25 -01:00", "latitude": -61.349611, "longitude": 141.056565, "tags": [ "aute", "voluptate", "deserunt", "laborum", "sint", "quis", "cillum", "tempor", "sit", "amet" ], "friends": [ { "id": 0, "name": "Donovan Page" }, { "id": 1, "name": "Kelli Butler" }, { "id": 2, "name": "Veronica Prince" }, { "id": 3, "name": "Marina Jordan" }, { "id": 4, "name": "Santana Morton" } ], "greeting": "Hello, Peck Lucas! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48265a026350e856c133", "index": 33, "guid": "1f4dc5ac-c69e-48da-a7aa-c65f5373f050", "isActive": true, "balance": "$1,075.53", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "May Hobbs", "gender": "female", "company": "DATAGEN", "email": "mayhobbs@datagen.com", "phone": "+1 (864) 500-3208", "address": "244 Middagh Street, Levant, Missouri, 5802", "about": "Enim culpa veniam in quis in cupidatat non qui cillum sint. Enim tempor Lorem officia sit magna occaecat incididunt voluptate dolore consequat cupidatat ea est. Deserunt dolore nulla do eu labore cillum voluptate incididunt sit commodo ad. Commodo enim voluptate duis officia culpa exercitation nostrud cupidatat quis enim laborum deserunt dolor.\r\n", "registered": "2014-04-20T10:01:03 -02:00", "latitude": -5.448807, "longitude": 32.186328, "tags": [ "sit", "amet", "est", "in", "amet", "nulla", "velit", "ipsum", "in", "nostrud" ], "friends": [ { "id": 0, "name": "Mejia Deleon" }, { "id": 1, "name": "Hobbs Perkins" }, { "id": 2, "name": "Spence Kemp" }, { "id": 3, "name": "Jocelyn Hogan" }, { "id": 4, "name": "Beryl Webster" } ], "greeting": "Hello, May Hobbs! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c05473e26dd1a9ca", "index": 34, "guid": "29914231-63ea-42f3-992a-8444c245fb3c", "isActive": true, "balance": "$3,707.62", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "blue", "name": "Marcie Hunt", "gender": "female", "company": "ZYTRAX", "email": "marciehunt@zytrax.com", "phone": "+1 (846) 590-2940", "address": "703 Matthews Court, Marenisco, Ohio, 1544", "about": "Minim nostrud eiusmod minim consequat fugiat ut veniam. Elit cillum amet sunt commodo ullamco consectetur consectetur ullamco et sunt enim voluptate eu eiusmod. Nostrud quis magna nostrud exercitation magna in est reprehenderit eiusmod. Eiusmod esse proident pariatur nulla magna ut est adipisicing aliquip pariatur fugiat. Eu quis elit quis ullamco deserunt fugiat. Cupidatat excepteur quis dolore deserunt id tempor eu enim sit in duis aute.\r\n", "registered": "2016-03-18T07:11:38 -01:00", "latitude": 50.213175, "longitude": -8.075369, "tags": [ "incididunt", "sint", "voluptate", "ipsum", "aliqua", "mollit", "officia", "dolore", "incididunt", "exercitation" ], "friends": [ { "id": 0, "name": "Casey Emerson" }, { "id": 1, "name": "Beach Mcleod" }, { "id": 2, "name": "Duffy Hughes" }, { "id": 3, "name": "Fleming Haley" }, { "id": 4, "name": "Sara Lyons" } ], "greeting": "Hello, Marcie Hunt! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826990df89f1ad9f531", "index": 35, "guid": "cd452a66-e949-4bf7-a0bf-0093cfd22eaa", "isActive": false, "balance": "$3,255.86", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "brown", "name": "Tracy Walton", "gender": "female", "company": "POLARAX", "email": "tracywalton@polarax.com", "phone": "+1 (846) 478-2428", "address": "752 Gatling Place, Linganore, Arizona, 883", "about": "Consequat adipisicing voluptate aute reprehenderit in aute consectetur laboris minim enim deserunt quis. Irure laboris do aliquip commodo. Elit sit officia elit dolor excepteur fugiat.\r\n", "registered": "2017-08-27T03:49:38 -02:00", "latitude": 28.307459, "longitude": 109.311303, "tags": [ "sint", "aute", "esse", "incididunt", "dolor", "minim", "fugiat", "fugiat", "sunt", "laboris" ], "friends": [ { "id": 0, "name": "Hyde Guy" }, { "id": 1, "name": "Graciela Irwin" }, { "id": 2, "name": "Robinson Herring" }, { "id": 3, "name": "Collier Solis" }, { "id": 4, "name": "Yesenia Fuller" } ], "greeting": "Hello, Tracy Walton! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826a073940b635322e1", "index": 36, "guid": "8a5c6af5-5979-45c2-8a75-ef90983fd4b8", "isActive": false, "balance": "$3,151.58", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Kristin Bruce", "gender": "female", "company": "ONTAGENE", "email": "kristinbruce@ontagene.com", "phone": "+1 (977) 554-3528", "address": "851 Butler Street, Valle, Montana, 6243", "about": "Ipsum laborum dolor id elit ut est ex. Amet nulla tempor incididunt esse voluptate. Labore sit do labore ut ullamco culpa tempor voluptate sit dolore deserunt quis. Culpa non labore mollit deserunt pariatur laboris cupidatat elit. In quis occaecat enim laboris irure cupidatat. Anim quis veniam proident mollit eiusmod elit pariatur minim sunt. Nisi excepteur consectetur consequat ut culpa sint irure.\r\n", "registered": "2015-05-30T07:00:26 -02:00", "latitude": 2.232596, "longitude": -141.881434, "tags": [ "dolore", "ullamco", "et", "duis", "labore", "minim", "quis", "excepteur", "esse", "dolore" ], "friends": [ { "id": 0, "name": "Elaine Benton" }, { "id": 1, "name": "Heather Oneal" }, { "id": 2, "name": "Jacobson Hess" }, { "id": 3, "name": "Kennedy Leach" }, { "id": 4, "name": "Skinner Sargent" } ], "greeting": "Hello, Kristin Bruce! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482652d2bd5e152a52e3", "index": 37, "guid": "3b81f598-c29b-4cc8-882b-7d5835305ae1", "isActive": false, "balance": "$1,125.30", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Paulette Leblanc", "gender": "female", "company": "CEDWARD", "email": "pauletteleblanc@cedward.com", "phone": "+1 (921) 516-3065", "address": "378 Utica Avenue, Kansas, Texas, 3967", "about": "Et sunt labore do Lorem non quis quis cillum ullamco eiusmod voluptate aute reprehenderit. Velit laborum cillum est aliqua non aliqua cupidatat esse minim exercitation ipsum aute velit. Non ullamco velit consequat ipsum ex magna id aliqua et. Anim laborum ea consequat tempor quis occaecat consequat laboris ad sunt culpa aliquip non qui. Sit cupidatat veniam voluptate aute ut.\r\n", "registered": "2017-08-02T01:06:44 -02:00", "latitude": -42.137111, "longitude": 44.81247, "tags": [ "mollit", "quis", "Lorem", "officia", "velit", "cupidatat", "ea", "incididunt", "mollit", "minim" ], "friends": [ { "id": 0, "name": "Joanne Jenkins" }, { "id": 1, "name": "Monique Gordon" }, { "id": 2, "name": "Ethel Conley" }, { "id": 3, "name": "Anthony Rutledge" }, { "id": 4, "name": "Alta Baird" } ], "greeting": "Hello, Paulette Leblanc! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826405d4ad3681ed1e5", "index": 38, "guid": "75206ddb-dbfe-4733-8ad8-a8d02d9029c2", "isActive": true, "balance": "$3,970.55", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Emma Finch", "gender": "female", "company": "METROZ", "email": "emmafinch@metroz.com", "phone": "+1 (858) 438-2046", "address": "748 Folsom Place, Oasis, Washington, 2009", "about": "Dolor Lorem proident enim consectetur est enim irure magna anim. Tempor fugiat anim aliqua aliqua deserunt ex. Laborum culpa minim exercitation elit incididunt laborum culpa nisi consectetur aute ex consequat.\r\n", "registered": "2015-03-17T02:23:09 -01:00", "latitude": 76.657937, "longitude": 47.289191, "tags": [ "Lorem", "ipsum", "fugiat", "laboris", "ipsum", "labore", "pariatur", "proident", "consectetur", "quis" ], "friends": [ { "id": 0, "name": "Fuller Cruz" }, { "id": 1, "name": "Lisa Bailey" }, { "id": 2, "name": "Alyson England" }, { "id": 3, "name": "Freda Gamble" }, { "id": 4, "name": "Gates Chambers" } ], "greeting": "Hello, Emma Finch! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ec08f224dd8e75c4", "index": 39, "guid": "359625de-075d-4eec-88da-a78b33ab52ca", "isActive": true, "balance": "$1,066.14", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Rutledge Castillo", "gender": "male", "company": "CODACT", "email": "rutledgecastillo@codact.com", "phone": "+1 (883) 456-3933", "address": "706 Aviation Road, Advance, Wyoming, 2139", "about": "Ut aliquip aute officia adipisicing pariatur ipsum consectetur laborum Lorem est id deserunt. Nisi duis nisi in adipisicing. Occaecat est enim adipisicing laborum. Culpa duis elit tempor cupidatat elit. Sunt ea est irure do incididunt excepteur reprehenderit. Adipisicing irure aliquip do elit voluptate sunt exercitation.\r\n", "registered": "2016-08-30T03:27:41 -02:00", "latitude": 89.181277, "longitude": -141.911807, "tags": [ "nulla", "esse", "aliqua", "occaecat", "duis", "esse", "occaecat", "cupidatat", "eu", "incididunt" ], "friends": [ { "id": 0, "name": "Marlene Lowery" }, { "id": 1, "name": "Doreen Cross" }, { "id": 2, "name": "Shawn Santos" }, { "id": 3, "name": "Blanche Langley" }, { "id": 4, "name": "Pearl Good" } ], "greeting": "Hello, Rutledge Castillo! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48267bb3144b2c25bba9", "index": 40, "guid": "e6b27e33-4a17-406c-85fe-4ba0ca740415", "isActive": true, "balance": "$2,624.64", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "blue", "name": "Alfreda Jimenez", "gender": "female", "company": "BOILICON", "email": "alfredajimenez@boilicon.com", "phone": "+1 (834) 451-2709", "address": "349 Baycliff Terrace, Tryon, Indiana, 8964", "about": "Et laborum dolor magna do proident et nulla nostrud culpa elit ipsum ad pariatur amet. Sit cillum do magna ad ut ipsum do. Ut aute labore ipsum ullamco. Nisi elit adipisicing nostrud Lorem aliquip id dolor officia Lorem proident sint sit adipisicing enim. Ipsum pariatur pariatur aliqua mollit veniam minim. Consequat dolore laborum ullamco elit esse esse non non dolor minim. Eu non Lorem adipisicing et ut quis est ea esse.\r\n", "registered": "2015-03-08T06:18:30 -01:00", "latitude": 18.005935, "longitude": 162.519814, "tags": [ "labore", "dolore", "esse", "veniam", "irure", "sunt", "ullamco", "culpa", "nulla", "irure" ], "friends": [ { "id": 0, "name": "Stefanie Fernandez" }, { "id": 1, "name": "Letha Parrish" }, { "id": 2, "name": "Helga Avery" }, { "id": 3, "name": "Becker Hurst" }, { "id": 4, "name": "Krista Suarez" } ], "greeting": "Hello, Alfreda Jimenez! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b9a25b4154ff8057", "index": 41, "guid": "8329c642-99a5-4223-abb2-b1c74edc9479", "isActive": false, "balance": "$3,570.89", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Watson Reeves", "gender": "male", "company": "STRALOY", "email": "watsonreeves@straloy.com", "phone": "+1 (883) 498-2487", "address": "170 Nassau Avenue, Malo, Alabama, 9472", "about": "Consectetur culpa nulla do qui minim fugiat sunt Lorem cillum non. Veniam eiusmod laboris reprehenderit sit exercitation ut ullamco proident exercitation. Nostrud dolore exercitation eu mollit quis nisi nisi consectetur ex aliqua reprehenderit irure reprehenderit dolore. Aliquip dolor ea consequat elit. Magna aliqua id sit esse velit cupidatat irure voluptate in veniam dolor laborum enim mollit. Ipsum consequat fugiat irure ea ut nostrud. Eu tempor sit ex nisi.\r\n", "registered": "2015-12-26T08:15:47 -01:00", "latitude": 64.088122, "longitude": 141.783941, "tags": [ "sint", "anim", "dolore", "velit", "sint", "sit", "quis", "officia", "nisi", "aute" ], "friends": [ { "id": 0, "name": "Stafford Mclean" }, { "id": 1, "name": "Tami Guerrero" }, { "id": 2, "name": "Daugherty Perry" }, { "id": 3, "name": "Rivera Fulton" }, { "id": 4, "name": "Kristi Harrell" } ], "greeting": "Hello, Watson Reeves! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826412622e940c517ba", "index": 42, "guid": "2fb9fb79-c1cb-4164-840f-fd0c7d5f09bb", "isActive": true, "balance": "$1,247.81", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "blue", "name": "Katy Odom", "gender": "female", "company": "FLYBOYZ", "email": "katyodom@flyboyz.com", "phone": "+1 (973) 469-3385", "address": "655 Empire Boulevard, Kimmell, Virginia, 6044", "about": "Veniam elit labore excepteur sint ut commodo adipisicing commodo dolore eiusmod tempor. Proident anim nulla laboris laboris aliqua irure commodo in veniam amet quis. Non aliqua aliqua do ex incididunt cillum officia esse adipisicing laborum est fugiat nostrud.\r\n", "registered": "2017-05-14T11:41:38 -02:00", "latitude": 82.114923, "longitude": -132.831875, "tags": [ "ex", "cupidatat", "aliquip", "quis", "veniam", "mollit", "est", "incididunt", "dolore", "elit" ], "friends": [ { "id": 0, "name": "Carrie Newman" }, { "id": 1, "name": "Matilda Cote" }, { "id": 2, "name": "Evangelina Yang" }, { "id": 3, "name": "Pope Mayer" }, { "id": 4, "name": "Jeri Mendez" } ], "greeting": "Hello, Katy Odom! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826d6b3e5309ae64763", "index": 43, "guid": "6e0c6569-10a9-4ff8-8ea0-65732ac717a3", "isActive": true, "balance": "$3,532.08", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Hood Watson", "gender": "male", "company": "ZAJ", "email": "hoodwatson@zaj.com", "phone": "+1 (876) 576-2971", "address": "147 Luquer Street, Nile, New Mexico, 1747", "about": "Ullamco amet magna nulla eu deserunt minim ex. Cillum quis sit anim ipsum aliquip enim magna. Minim laborum nisi esse incididunt excepteur. Nostrud proident duis elit mollit commodo et incididunt ut enim et.\r\n", "registered": "2015-08-09T04:35:22 -02:00", "latitude": -6.773575, "longitude": 159.404116, "tags": [ "cupidatat", "ut", "fugiat", "deserunt", "cupidatat", "aute", "velit", "consequat", "aute", "irure" ], "friends": [ { "id": 0, "name": "Maryann Washington" }, { "id": 1, "name": "Burton Lang" }, { "id": 2, "name": "Yang Cardenas" }, { "id": 3, "name": "Lily Wynn" }, { "id": 4, "name": "Mayra Golden" } ], "greeting": "Hello, Hood Watson! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826e9a7aaff7c403121", "index": 44, "guid": "5bc275d4-e663-4713-a3f1-5cba344b154c", "isActive": true, "balance": "$2,013.46", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Eliza Cantu", "gender": "female", "company": "VIRXO", "email": "elizacantu@virxo.com", "phone": "+1 (851) 448-3191", "address": "101 Dunne Place, Bethpage, Hawaii, 3283", "about": "Et cupidatat mollit tempor cupidatat commodo veniam. Eu non nisi tempor ut ut. Cupidatat veniam pariatur magna duis do in minim cillum non officia pariatur aliqua aute. Quis deserunt laboris voluptate aliquip consectetur elit enim aute ea laboris velit deserunt. Duis sint est esse quis eiusmod mollit.\r\n", "registered": "2015-11-04T11:38:15 -01:00", "latitude": -16.922323, "longitude": 145.576441, "tags": [ "ad", "tempor", "nisi", "consectetur", "voluptate", "sunt", "magna", "amet", "labore", "fugiat" ], "friends": [ { "id": 0, "name": "Hilda Morse" }, { "id": 1, "name": "Finley Luna" }, { "id": 2, "name": "Winifred Santiago" }, { "id": 3, "name": "Battle Vinson" }, { "id": 4, "name": "Richardson Salas" } ], "greeting": "Hello, Eliza Cantu! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826a7ea94cae14427c2", "index": 45, "guid": "9d558b3b-18cb-412a-9d8b-3f8c2970caa2", "isActive": false, "balance": "$2,968.65", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Haney Mayo", "gender": "male", "company": "BIOTICA", "email": "haneymayo@biotica.com", "phone": "+1 (849) 401-3023", "address": "528 Havens Place, Alden, Nebraska, 9622", "about": "Tempor mollit dolore ea labore. Reprehenderit do do adipisicing voluptate magna eu fugiat pariatur ipsum. In duis est do occaecat tempor occaecat qui sit exercitation ullamco aliqua consequat. Quis voluptate consectetur nostrud dolor minim ipsum minim est sint. Et sunt officia laboris consectetur enim et consectetur ipsum ad sunt. Cupidatat sunt cillum tempor veniam irure nostrud in ad eiusmod nulla fugiat ad.\r\n", "registered": "2016-07-27T03:27:37 -02:00", "latitude": 43.004708, "longitude": 65.779027, "tags": [ "eu", "sit", "exercitation", "elit", "laborum", "magna", "aute", "incididunt", "cupidatat", "amet" ], "friends": [ { "id": 0, "name": "Delaney Herman" }, { "id": 1, "name": "Leblanc Pena" }, { "id": 2, "name": "Hester Murray" }, { "id": 3, "name": "Hensley Thomas" }, { "id": 4, "name": "Queen Phelps" } ], "greeting": "Hello, Haney Mayo! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482649ced340bbddcec6", "index": 46, "guid": "3e677a36-e24c-4642-b26d-c500a2c256e4", "isActive": false, "balance": "$1,906.90", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "green", "name": "Rhoda Wolfe", "gender": "female", "company": "EMOLTRA", "email": "rhodawolfe@emoltra.com", "phone": "+1 (855) 547-3204", "address": "517 Raleigh Place, Wescosville, New York, 9851", "about": "Aute in fugiat aliquip aliquip qui adipisicing eiusmod. Non minim in officia fugiat nostrud eiusmod sunt quis. Do do deserunt non nisi deserunt fugiat id dolor fugiat proident culpa amet. Sunt ex occaecat amet elit fugiat enim aute cillum. Minim commodo duis aute adipisicing sint est do aliquip exercitation voluptate ea cupidatat. Proident id Lorem eiusmod ullamco minim aute non culpa elit. Dolor occaecat irure quis cupidatat laborum anim do eiusmod in aute duis.\r\n", "registered": "2016-09-21T06:47:55 -02:00", "latitude": -53.244083, "longitude": 97.532668, "tags": [ "voluptate", "velit", "id", "nisi", "ut", "adipisicing", "ut", "incididunt", "elit", "id" ], "friends": [ { "id": 0, "name": "Toni Tanner" }, { "id": 1, "name": "Karin Turner" }, { "id": 2, "name": "Loraine Horn" }, { "id": 3, "name": "Nadia Mcclain" }, { "id": 4, "name": "Monica Serrano" } ], "greeting": "Hello, Rhoda Wolfe! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826a57fa2d1fa3e16df", "index": 47, "guid": "10ed5739-e0d5-4b99-a475-3940f5016086", "isActive": false, "balance": "$1,213.39", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "brown", "name": "Alejandra Molina", "gender": "female", "company": "EXOBLUE", "email": "alejandramolina@exoblue.com", "phone": "+1 (868) 506-3861", "address": "779 Miller Avenue, Drytown, Marshall Islands, 6897", "about": "Amet Lorem Lorem amet irure reprehenderit ad aliqua sint proident eiusmod excepteur irure amet do. Laborum proident cillum culpa Lorem eiusmod irure commodo occaecat laborum adipisicing. Eu anim ex aliquip sint consectetur duis. Tempor irure minim veniam laborum duis cillum nulla enim ipsum. Ad pariatur dolore dolor Lorem commodo mollit adipisicing qui Lorem proident ut aute. Cillum consectetur exercitation ea velit exercitation mollit amet aute mollit labore consectetur dolore. Esse esse ullamco amet ut non tempor qui.\r\n", "registered": "2017-02-19T08:15:06 -01:00", "latitude": 2.184507, "longitude": 45.762181, "tags": [ "est", "fugiat", "deserunt", "nisi", "officia", "enim", "id", "magna", "et", "dolore" ], "friends": [ { "id": 0, "name": "Phoebe Mccarty" }, { "id": 1, "name": "Vaughn Workman" }, { "id": 2, "name": "Rowe Ross" }, { "id": 3, "name": "Hodges Ramos" }, { "id": 4, "name": "Ada Russell" } ], "greeting": "Hello, Alejandra Molina! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826567c8148b093c3ce", "index": 48, "guid": "77b03d6d-aed3-4133-87ba-6504b5c91d90", "isActive": false, "balance": "$2,399.89", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Shaffer Cochran", "gender": "male", "company": "MONDICIL", "email": "shaffercochran@mondicil.com", "phone": "+1 (903) 506-3812", "address": "145 Madison Street, Sims, Oregon, 7198", "about": "Veniam ullamco pariatur adipisicing pariatur quis duis id veniam deserunt dolore. Adipisicing nulla in nulla duis do ex dolor laboris velit. Tempor incididunt exercitation sit mollit magna enim anim. Laboris esse officia pariatur eiusmod excepteur commodo pariatur eu magna est. Commodo veniam veniam nisi laboris velit. Non cillum et id aute non proident nisi sint aliqua eiusmod sit enim.\r\n", "registered": "2016-08-22T12:03:05 -02:00", "latitude": 25.675379, "longitude": -14.960697, "tags": [ "aute", "aliquip", "ex", "officia", "sint", "exercitation", "adipisicing", "duis", "tempor", "culpa" ], "friends": [ { "id": 0, "name": "Tamika Taylor" }, { "id": 1, "name": "Sophia Dale" }, { "id": 2, "name": "Danielle Adkins" }, { "id": 3, "name": "Brenda Noel" }, { "id": 4, "name": "Mamie Moran" } ], "greeting": "Hello, Shaffer Cochran! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826cbbd5b451aaed255", "index": 49, "guid": "b0785bbd-ebb5-4442-860a-b739729cd6b4", "isActive": true, "balance": "$2,068.72", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Perez Byers", "gender": "male", "company": "GENMY", "email": "perezbyers@genmy.com", "phone": "+1 (818) 453-3221", "address": "409 Village Court, Cedarville, Tennessee, 1827", "about": "Consectetur labore labore amet amet voluptate proident. Dolore labore cillum aute tempor fugiat. Aliqua nulla incididunt labore laboris adipisicing culpa aliquip et sit. Exercitation ut officia adipisicing veniam proident Lorem mollit in qui officia veniam. Nisi dolore nulla cupidatat proident sint consequat ex laborum labore aute ullamco excepteur.\r\n", "registered": "2015-11-21T08:23:04 -01:00", "latitude": -29.133347, "longitude": -67.72039, "tags": [ "sit", "ipsum", "magna", "non", "non", "elit", "nostrud", "qui", "enim", "ullamco" ], "friends": [ { "id": 0, "name": "Gilmore Houston" }, { "id": 1, "name": "Shannon Lindsey" }, { "id": 2, "name": "Miriam Dyer" }, { "id": 3, "name": "Lana Shields" }, { "id": 4, "name": "Jerri Lancaster" } ], "greeting": "Hello, Perez Byers! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826d639d75a4f7dc36a", "index": 50, "guid": "b4d76fb9-8527-4564-b593-2a02bb0976af", "isActive": false, "balance": "$1,865.97", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "brown", "name": "Michael Harrison", "gender": "male", "company": "APPLIDECK", "email": "michaelharrison@applideck.com", "phone": "+1 (901) 458-3038", "address": "400 Irwin Street, Nipinnawasee, Nevada, 4089", "about": "Excepteur consequat mollit est nulla nisi duis dolor sunt nostrud anim. Cillum culpa nostrud pariatur sit labore velit proident velit officia nostrud aliquip eiusmod. Aliquip eiusmod veniam anim aute sit velit dolor reprehenderit veniam exercitation consectetur fugiat exercitation. Tempor dolor nisi anim consectetur ipsum sit aute magna laborum sit. Adipisicing incididunt mollit quis proident exercitation nulla. Reprehenderit voluptate duis consequat nisi nisi consequat consequat nostrud culpa cillum in ut do ad.\r\n", "registered": "2014-04-01T02:28:02 -02:00", "latitude": 44.997838, "longitude": 2.787228, "tags": [ "consectetur", "aliquip", "proident", "eiusmod", "ad", "minim", "ea", "nulla", "ea", "in" ], "friends": [ { "id": 0, "name": "Candy Sosa" }, { "id": 1, "name": "Levy Thompson" }, { "id": 2, "name": "Woods Kidd" }, { "id": 3, "name": "Carr Joyner" }, { "id": 4, "name": "Patrica Ochoa" } ], "greeting": "Hello, Michael Harrison! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826e570be0265123b00", "index": 51, "guid": "48390a2c-de09-48a2-b319-640e388c9bd2", "isActive": false, "balance": "$2,767.06", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Lott Vang", "gender": "male", "company": "VENOFLEX", "email": "lottvang@venoflex.com", "phone": "+1 (864) 564-2596", "address": "966 Calyer Street, Eden, Alaska, 7769", "about": "Qui adipisicing et cillum esse ullamco deserunt velit fugiat nulla commodo deserunt deserunt. Adipisicing irure qui ullamco nostrud incididunt et sunt aliqua sit amet eu est culpa non. Qui magna proident pariatur deserunt excepteur anim occaecat do fugiat aute aute proident culpa quis. Minim qui consequat nulla pariatur occaecat. Ad Lorem consectetur fugiat nulla. Esse laborum do irure minim voluptate labore ex exercitation quis minim eiusmod aute.\r\n", "registered": "2014-11-09T08:32:01 -01:00", "latitude": 59.014685, "longitude": -26.079277, "tags": [ "labore", "consequat", "excepteur", "id", "adipisicing", "elit", "commodo", "eiusmod", "dolor", "exercitation" ], "friends": [ { "id": 0, "name": "Lauren Pate" }, { "id": 1, "name": "Johanna Webb" }, { "id": 2, "name": "Pierce Mcneil" }, { "id": 3, "name": "Winnie Glenn" }, { "id": 4, "name": "Amalia Hyde" } ], "greeting": "Hello, Lott Vang! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48269d97658ce784c61c", "index": 52, "guid": "8f6e8fe8-cde0-4068-8b2f-f292e635c58b", "isActive": false, "balance": "$2,977.06", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "brown", "name": "Benita Hurley", "gender": "female", "company": "FUELWORKS", "email": "benitahurley@fuelworks.com", "phone": "+1 (895) 549-2806", "address": "291 Brigham Street, Craig, Illinois, 696", "about": "Deserunt cillum velit pariatur aliquip officia aute tempor laborum officia ad. Aliqua eiusmod fugiat proident in eiusmod id nulla laborum eu. Anim est elit culpa consectetur amet ad magna nostrud. In ipsum Lorem ut ex excepteur nulla anim eiusmod. Mollit esse sint eiusmod eiusmod non ea. Veniam adipisicing culpa commodo incididunt nisi incididunt dolore ad nulla labore voluptate. Officia sunt et officia ad amet fugiat veniam nulla voluptate do velit culpa commodo officia.\r\n", "registered": "2017-11-28T05:46:54 -01:00", "latitude": -17.981831, "longitude": -47.871248, "tags": [ "nisi", "aliqua", "magna", "ex", "id", "nisi", "sit", "voluptate", "culpa", "sint" ], "friends": [ { "id": 0, "name": "Aguilar Bartlett" }, { "id": 1, "name": "Jeanette Boyd" }, { "id": 2, "name": "Miller Kent" }, { "id": 3, "name": "Cummings Gillespie" }, { "id": 4, "name": "Robles Stafford" } ], "greeting": "Hello, Benita Hurley! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826f06a482ba2cf8754", "index": 53, "guid": "241f0eb7-f3a9-4d44-af90-f630d5e64814", "isActive": true, "balance": "$2,612.73", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Janine Arnold", "gender": "female", "company": "ISOLOGICA", "email": "janinearnold@isologica.com", "phone": "+1 (924) 479-2129", "address": "991 Lott Avenue, Belleview, Oklahoma, 1948", "about": "Qui fugiat veniam cillum cillum dolor nostrud. Excepteur officia fugiat do incididunt laboris sunt magna adipisicing qui veniam qui proident. Proident commodo ea sunt culpa id et cillum pariatur elit commodo incididunt. Sit incididunt cupidatat in enim cillum deserunt ea ipsum.\r\n", "registered": "2014-07-26T10:52:01 -02:00", "latitude": -79.108914, "longitude": 167.421127, "tags": [ "do", "excepteur", "culpa", "cillum", "aute", "sint", "laboris", "laborum", "ea", "eu" ], "friends": [ { "id": 0, "name": "Ramsey Ballard" }, { "id": 1, "name": "Silva Sweeney" }, { "id": 2, "name": "Mckenzie Wong" }, { "id": 3, "name": "Catherine Delacruz" }, { "id": 4, "name": "Keri Singleton" } ], "greeting": "Hello, Janine Arnold! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b2a80f3af70de3f5", "index": 54, "guid": "bbe229ac-f041-41b7-ab2a-ffabdfb68c17", "isActive": false, "balance": "$1,334.28", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "green", "name": "Holden Mccall", "gender": "male", "company": "ENERSAVE", "email": "holdenmccall@enersave.com", "phone": "+1 (905) 519-3106", "address": "308 Hancock Street, Juntura, Delaware, 8352", "about": "Cupidatat et magna sit et deserunt tempor cupidatat qui esse consectetur commodo aliqua quis. Cupidatat ullamco in officia nisi sit officia ad mollit tempor irure elit enim fugiat ea. Duis aliquip proident veniam eiusmod dolore incididunt tempor sunt ad excepteur tempor sit incididunt ad. Ullamco dolor consequat sint enim irure veniam ea ad commodo. Elit consectetur dolor duis in nulla nisi magna proident duis aliquip amet dolore nulla ex. Consectetur eiusmod esse deserunt excepteur esse veniam consectetur.\r\n", "registered": "2014-07-03T02:17:54 -02:00", "latitude": -21.026956, "longitude": -28.658478, "tags": [ "irure", "qui", "culpa", "dolor", "culpa", "ex", "laborum", "et", "mollit", "veniam" ], "friends": [ { "id": 0, "name": "Boyd Charles" }, { "id": 1, "name": "Estella Wilcox" }, { "id": 2, "name": "Meagan Dorsey" }, { "id": 3, "name": "Susanne Morgan" }, { "id": 4, "name": "Kathie Gay" } ], "greeting": "Hello, Holden Mccall! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48268a044af3b76e7569", "index": 55, "guid": "e6987d87-f6fc-4a45-9138-61aad3f27c15", "isActive": false, "balance": "$1,649.39", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Lawanda Odonnell", "gender": "female", "company": "QUANTASIS", "email": "lawandaodonnell@quantasis.com", "phone": "+1 (970) 590-3493", "address": "430 Lamont Court, Sanders, Federated States Of Micronesia, 4297", "about": "Ex amet esse aliqua aliquip aliqua ipsum id. Esse nostrud exercitation esse labore. Aute magna aute enim adipisicing reprehenderit nisi laboris exercitation aute est magna. Voluptate nisi ea ad proident ea laboris. Reprehenderit pariatur magna in nisi commodo dolore consectetur dolore. Deserunt reprehenderit in dolore sit dolor cillum.\r\n", "registered": "2014-09-05T04:00:58 -02:00", "latitude": -73.89546, "longitude": -99.676411, "tags": [ "sunt", "aute", "ad", "est", "labore", "exercitation", "ex", "commodo", "sunt", "ea" ], "friends": [ { "id": 0, "name": "Darcy Lawson" }, { "id": 1, "name": "Little Massey" }, { "id": 2, "name": "Livingston Holcomb" }, { "id": 3, "name": "Jo Brooks" }, { "id": 4, "name": "Jody Hendrix" } ], "greeting": "Hello, Lawanda Odonnell! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48269289bda5e5617c67", "index": 56, "guid": "bef4f5c6-2443-40c9-b65d-7339333255df", "isActive": true, "balance": "$2,792.68", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Ashley Barnes", "gender": "male", "company": "YOGASM", "email": "ashleybarnes@yogasm.com", "phone": "+1 (822) 454-2408", "address": "896 Glenwood Road, Dalton, Florida, 7621", "about": "In tempor incididunt ut duis in consequat duis aliqua occaecat aliqua. Exercitation est reprehenderit sit laboris proident. Proident ad id culpa ad eu consectetur laboris. Deserunt dolore est non proident laborum dolor ea irure.\r\n", "registered": "2016-08-01T01:39:18 -02:00", "latitude": 19.589234, "longitude": -86.006834, "tags": [ "ea", "in", "do", "Lorem", "ad", "consectetur", "labore", "culpa", "proident", "nisi" ], "friends": [ { "id": 0, "name": "Brandy Cortez" }, { "id": 1, "name": "Emily Kelly" }, { "id": 2, "name": "Ware Shaffer" }, { "id": 3, "name": "Middleton Walters" }, { "id": 4, "name": "Terra English" } ], "greeting": "Hello, Ashley Barnes! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48266efc191a79a23dc3", "index": 57, "guid": "676f9865-0611-4b36-a8b1-f2695edf0159", "isActive": true, "balance": "$1,537.62", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Natalie Osborne", "gender": "female", "company": "QUINEX", "email": "natalieosborne@quinex.com", "phone": "+1 (941) 495-2144", "address": "642 Etna Street, Teasdale, Massachusetts, 4311", "about": "Sunt ut tempor non dolore nisi dolor laborum. Ut eu consectetur ut occaecat dolor velit. Voluptate irure nisi velit culpa do amet ipsum. Deserunt ea ullamco mollit incididunt eiusmod sit consequat est magna qui. Elit aliquip adipisicing cillum culpa id.\r\n", "registered": "2015-10-17T02:12:19 -02:00", "latitude": 20.086363, "longitude": -88.875356, "tags": [ "exercitation", "quis", "dolore", "anim", "sunt", "ad", "id", "et", "fugiat", "tempor" ], "friends": [ { "id": 0, "name": "Hendrix Schultz" }, { "id": 1, "name": "Alexandra Sullivan" }, { "id": 2, "name": "Greene Gomez" }, { "id": 3, "name": "Malinda Maxwell" }, { "id": 4, "name": "Stein Cash" } ], "greeting": "Hello, Natalie Osborne! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826cdbe761a10468678", "index": 58, "guid": "83800a39-95c4-4f5d-bd23-d946d56cc101", "isActive": false, "balance": "$2,639.58", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "brown", "name": "Thompson Rich", "gender": "male", "company": "RETROTEX", "email": "thompsonrich@retrotex.com", "phone": "+1 (838) 444-2633", "address": "338 Manor Court, Orin, Mississippi, 2492", "about": "Dolore pariatur minim excepteur exercitation aliqua minim exercitation tempor nulla esse adipisicing voluptate. Reprehenderit in incididunt dolore exercitation enim exercitation velit. Voluptate nostrud adipisicing mollit excepteur est eiusmod quis.\r\n", "registered": "2016-10-18T11:27:54 -02:00", "latitude": 70.832319, "longitude": 28.200428, "tags": [ "labore", "ex", "consequat", "nostrud", "tempor", "dolore", "cillum", "ullamco", "labore", "adipisicing" ], "friends": [ { "id": 0, "name": "Gayle Gibbs" }, { "id": 1, "name": "Warren Stephenson" }, { "id": 2, "name": "Woodward Hopkins" }, { "id": 3, "name": "Wall Strickland" }, { "id": 4, "name": "Geraldine Lee" } ], "greeting": "Hello, Thompson Rich! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826251d9490956b4d9c", "index": 59, "guid": "4d8cf665-3ac3-4185-af09-ed8f324caa72", "isActive": false, "balance": "$2,417.89", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "brown", "name": "Lidia Meyers", "gender": "female", "company": "BARKARAMA", "email": "lidiameyers@barkarama.com", "phone": "+1 (914) 447-3074", "address": "706 Micieli Place, Salunga, Guam, 473", "about": "Qui mollit enim aliquip ad ut irure non tempor. Excepteur fugiat sint qui dolor eu officia in eiusmod. Pariatur aliqua tempor reprehenderit sint non.\r\n", "registered": "2015-06-29T08:45:39 -02:00", "latitude": -69.535335, "longitude": -7.13001, "tags": [ "excepteur", "sint", "occaecat", "nostrud", "voluptate", "incididunt", "nisi", "eu", "commodo", "duis" ], "friends": [ { "id": 0, "name": "Isabelle Casey" }, { "id": 1, "name": "Henrietta Sanchez" }, { "id": 2, "name": "Pickett Moreno" }, { "id": 3, "name": "Annette Schwartz" }, { "id": 4, "name": "Whitley Munoz" } ], "greeting": "Hello, Lidia Meyers! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261492a04f29d208fe", "index": 60, "guid": "904f075b-7835-4edc-a659-8e49e079898d", "isActive": true, "balance": "$3,703.60", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "brown", "name": "Sonya Terry", "gender": "female", "company": "JUMPSTACK", "email": "sonyaterry@jumpstack.com", "phone": "+1 (987) 491-2631", "address": "492 Underhill Avenue, Dragoon, Louisiana, 5485", "about": "Sit ad esse Lorem pariatur esse amet sint adipisicing anim consectetur deserunt incididunt. Eiusmod aute non ex consequat culpa voluptate incididunt in. Aute labore excepteur ex ex.\r\n", "registered": "2017-05-19T11:49:51 -02:00", "latitude": 65.287185, "longitude": 92.275575, "tags": [ "laboris", "ipsum", "eiusmod", "consequat", "amet", "sunt", "enim", "laborum", "ullamco", "magna" ], "friends": [ { "id": 0, "name": "Christine Thornton" }, { "id": 1, "name": "Griffin Collins" }, { "id": 2, "name": "Hays Welch" }, { "id": 3, "name": "Maynard Fuentes" }, { "id": 4, "name": "Sofia Carlson" } ], "greeting": "Hello, Sonya Terry! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826bd8309ea4096ded8", "index": 61, "guid": "8b71fa1d-be02-4276-abcc-508fc36bfe55", "isActive": true, "balance": "$2,653.77", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Pamela Hawkins", "gender": "female", "company": "IRACK", "email": "pamelahawkins@irack.com", "phone": "+1 (867) 554-3908", "address": "387 Doscher Street, Fillmore, South Dakota, 2070", "about": "Sunt ipsum est dolore proident dolore qui mollit anim consequat officia proident. Qui reprehenderit aute occaecat esse. Enim minim ad exercitation tempor proident deserunt nisi est. Irure ea nulla minim ut. Do nostrud deserunt id velit irure qui id. Deserunt deserunt incididunt voluptate consequat aute Lorem. Enim cupidatat laborum consectetur veniam elit proident consequat reprehenderit non ea esse pariatur.\r\n", "registered": "2015-11-22T02:44:40 -01:00", "latitude": 31.884792, "longitude": -161.980893, "tags": [ "minim", "deserunt", "excepteur", "non", "consectetur", "cillum", "qui", "et", "nostrud", "voluptate" ], "friends": [ { "id": 0, "name": "Angeline Brown" }, { "id": 1, "name": "Lorrie Holt" }, { "id": 2, "name": "Preston Moon" }, { "id": 3, "name": "Pacheco Hull" }, { "id": 4, "name": "Paul Holder" } ], "greeting": "Hello, Pamela Hawkins! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482683825b51ee5d324a", "index": 62, "guid": "e62dfdb1-6d77-44c5-9383-15103b57da70", "isActive": true, "balance": "$2,188.36", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "brown", "name": "Dianne Burns", "gender": "female", "company": "COASH", "email": "dianneburns@coash.com", "phone": "+1 (816) 426-2807", "address": "686 Louisa Street, Nash, District Of Columbia, 3453", "about": "Laboris irure commodo commodo irure sint nostrud est et in id culpa. Laboris velit minim commodo pariatur culpa excepteur amet sint excepteur. Culpa adipisicing in quis voluptate amet consectetur. Fugiat excepteur anim velit officia qui irure laboris ullamco ipsum commodo tempor amet. Id ut nisi duis aliquip consequat in et commodo nulla velit ullamco id. Exercitation ipsum et quis est nisi elit excepteur minim aute fugiat esse tempor labore pariatur.\r\n", "registered": "2015-11-25T03:35:43 -01:00", "latitude": 3.391703, "longitude": 142.599843, "tags": [ "do", "fugiat", "est", "et", "dolor", "fugiat", "id", "eiusmod", "occaecat", "culpa" ], "friends": [ { "id": 0, "name": "Leticia Porter" }, { "id": 1, "name": "Newman Hale" }, { "id": 2, "name": "Dale Atkinson" }, { "id": 3, "name": "Guthrie Jones" }, { "id": 4, "name": "Fitzpatrick Melendez" } ], "greeting": "Hello, Dianne Burns! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48267d180e484f30b7be", "index": 63, "guid": "e2553e9a-1e4b-49ca-ba7e-66457c52b36b", "isActive": true, "balance": "$3,898.54", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "blue", "name": "Cotton Boyle", "gender": "male", "company": "BRAINCLIP", "email": "cottonboyle@brainclip.com", "phone": "+1 (853) 403-2027", "address": "297 Summit Street, Caroline, Puerto Rico, 4525", "about": "Aliqua fugiat ad officia laboris ex est laboris adipisicing tempor aliquip amet. Laboris incididunt consequat minim pariatur velit nulla adipisicing consequat in fugiat Lorem duis incididunt eiusmod. Do sunt proident esse mollit officia nostrud eu amet in quis. Id dolore velit et nisi ullamco occaecat laboris cupidatat. Mollit ea fugiat exercitation irure irure consequat. Magna incididunt cillum ex proident exercitation in cillum laborum esse. Dolor tempor aute ipsum dolor.\r\n", "registered": "2016-08-08T01:52:20 -02:00", "latitude": -21.251958, "longitude": 52.532934, "tags": [ "do", "pariatur", "do", "Lorem", "in", "non", "minim", "laboris", "consectetur", "magna" ], "friends": [ { "id": 0, "name": "Rivas Padilla" }, { "id": 1, "name": "Jackson Travis" }, { "id": 2, "name": "Aguirre Malone" }, { "id": 3, "name": "Dodson Mccray" }, { "id": 4, "name": "Jenny Whitney" } ], "greeting": "Hello, Cotton Boyle! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482605fdcba8fdc224ad", "index": 64, "guid": "c0513654-cebb-44ce-a676-3766984ca6ff", "isActive": false, "balance": "$1,821.82", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Perkins Ward", "gender": "male", "company": "KENGEN", "email": "perkinsward@kengen.com", "phone": "+1 (903) 595-2211", "address": "345 Keen Court, Bancroft, Maine, 5908", "about": "Do sint voluptate duis commodo pariatur anim velit excepteur culpa dolor fugiat ea. Sunt proident proident consequat mollit sunt cupidatat nulla consequat excepteur aliquip. Aute in deserunt ullamco mollit qui laborum id. Commodo aute incididunt pariatur ea officia deserunt ex laborum consectetur eiusmod excepteur. Cupidatat velit enim qui magna nisi deserunt eu sint.\r\n", "registered": "2015-11-26T06:12:46 -01:00", "latitude": 81.234189, "longitude": 34.697606, "tags": [ "nulla", "tempor", "culpa", "qui", "aliquip", "laboris", "fugiat", "proident", "magna", "velit" ], "friends": [ { "id": 0, "name": "Tanya Nolan" }, { "id": 1, "name": "Velma Burnett" }, { "id": 2, "name": "Imelda Poole" }, { "id": 3, "name": "Knapp Calderon" }, { "id": 4, "name": "Ashley Chapman" } ], "greeting": "Hello, Perkins Ward! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48268f3d3f08252d2784", "index": 65, "guid": "ef02728f-9463-4a11-9638-001b6e9c0762", "isActive": true, "balance": "$2,476.48", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "brown", "name": "Lang Russo", "gender": "male", "company": "CONJURICA", "email": "langrusso@conjurica.com", "phone": "+1 (999) 424-2197", "address": "414 Bradford Street, Curtice, New Jersey, 4534", "about": "Lorem proident reprehenderit dolor sunt sunt enim qui. Eiusmod adipisicing in do id pariatur consectetur. Ut do et pariatur deserunt anim sint magna officia nostrud tempor.\r\n", "registered": "2014-02-27T06:22:02 -01:00", "latitude": -46.846908, "longitude": -126.352792, "tags": [ "adipisicing", "occaecat", "aute", "quis", "adipisicing", "exercitation", "velit", "aliquip", "ullamco", "adipisicing" ], "friends": [ { "id": 0, "name": "Kerr Baker" }, { "id": 1, "name": "Marks Hays" }, { "id": 2, "name": "Louise Madden" }, { "id": 3, "name": "Gardner Keller" }, { "id": 4, "name": "Evelyn Kim" } ], "greeting": "Hello, Lang Russo! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826bc6484d1bfcf1e1c", "index": 66, "guid": "13efdc8e-18c9-4abd-9f67-d7611ffce74c", "isActive": false, "balance": "$2,208.45", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Deann Hood", "gender": "female", "company": "SOFTMICRO", "email": "deannhood@softmicro.com", "phone": "+1 (977) 474-2058", "address": "480 Hastings Street, Thynedale, Michigan, 7525", "about": "Dolore eiusmod occaecat quis reprehenderit. Aliqua nostrud commodo nisi excepteur irure ipsum adipisicing non elit ullamco aute dolore duis amet. Cillum culpa anim nostrud nisi do sit laboris fugiat consequat culpa culpa fugiat id. Nisi nostrud id velit nulla.\r\n", "registered": "2015-07-30T10:18:54 -02:00", "latitude": 45.37967, "longitude": 165.354213, "tags": [ "et", "sunt", "ea", "culpa", "veniam", "voluptate", "aute", "sit", "voluptate", "voluptate" ], "friends": [ { "id": 0, "name": "Sandra Patterson" }, { "id": 1, "name": "Serrano Patel" }, { "id": 2, "name": "Beth Knapp" }, { "id": 3, "name": "Pearlie Sanford" }, { "id": 4, "name": "Russell Rodriquez" } ], "greeting": "Hello, Deann Hood! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48266c6bfb3fa1e91cd8", "index": 67, "guid": "ccb24fcf-d906-4b48-80c1-e7a8fa4a35a1", "isActive": true, "balance": "$2,948.98", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "blue", "name": "Jessie Berger", "gender": "female", "company": "MAGNEMO", "email": "jessieberger@magnemo.com", "phone": "+1 (836) 440-3640", "address": "362 Barlow Drive, Boykin, Rhode Island, 1428", "about": "Laborum amet dolore adipisicing officia dolore do quis duis. Irure dolore dolor cupidatat enim. Elit eu eu do commodo eiusmod et dolore nostrud consectetur consectetur. Deserunt Lorem consequat exercitation ut aliqua do commodo.\r\n", "registered": "2015-08-04T01:21:42 -02:00", "latitude": 68.970883, "longitude": -57.437775, "tags": [ "aliqua", "consectetur", "reprehenderit", "deserunt", "dolor", "ad", "cupidatat", "nostrud", "anim", "id" ], "friends": [ { "id": 0, "name": "Maxine Snyder" }, { "id": 1, "name": "April Kirby" }, { "id": 2, "name": "Elsa Gray" }, { "id": 3, "name": "Sullivan Jacobson" }, { "id": 4, "name": "Mcmahon Patton" } ], "greeting": "Hello, Jessie Berger! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826d140347894eaad50", "index": 68, "guid": "81e7fb85-0427-4922-8d93-1c84ab8b7925", "isActive": false, "balance": "$3,825.08", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "green", "name": "Ola Parks", "gender": "female", "company": "ZILENCIO", "email": "olaparks@zilencio.com", "phone": "+1 (866) 597-2682", "address": "930 Hinsdale Street, Cotopaxi, Kansas, 7138", "about": "Lorem sunt laboris minim laboris veniam. Exercitation pariatur aliquip dolor excepteur nostrud sit elit elit aute pariatur. Minim do elit ipsum consectetur qui ea minim adipisicing fugiat ea duis. Est id officia aliquip consequat.\r\n", "registered": "2015-03-22T02:25:38 -01:00", "latitude": -12.363862, "longitude": -129.107555, "tags": [ "commodo", "enim", "duis", "consectetur", "aute", "pariatur", "aliquip", "exercitation", "labore", "incididunt" ], "friends": [ { "id": 0, "name": "Carmella Howard" }, { "id": 1, "name": "Essie Black" }, { "id": 2, "name": "James Hardin" }, { "id": 3, "name": "Katrina Griffin" }, { "id": 4, "name": "Avery Lopez" } ], "greeting": "Hello, Ola Parks! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48260eed99d911d10bda", "index": 69, "guid": "807b9caf-5de2-46ef-9ea0-0803f6d6e949", "isActive": true, "balance": "$1,459.30", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "brown", "name": "Bonita Walls", "gender": "female", "company": "MOREGANIC", "email": "bonitawalls@moreganic.com", "phone": "+1 (838) 431-3217", "address": "813 Forrest Street, Columbus, West Virginia, 107", "about": "Est est id ex nisi sit excepteur. Pariatur magna reprehenderit laboris irure voluptate consequat consequat laboris ad voluptate qui eu deserunt. Voluptate do cupidatat veniam dolor incididunt excepteur velit laboris eiusmod Lorem mollit. Duis exercitation amet ex aute qui. Magna aliquip irure magna aliqua ad in. Et nisi aliqua cillum et commodo. Aliquip exercitation ea exercitation magna amet excepteur esse in ipsum cupidatat elit aliquip commodo.\r\n", "registered": "2015-07-29T07:22:50 -02:00", "latitude": -83.208991, "longitude": -16.952428, "tags": [ "commodo", "commodo", "cupidatat", "reprehenderit", "sint", "culpa", "proident", "qui", "eiusmod", "voluptate" ], "friends": [ { "id": 0, "name": "Hillary Bernard" }, { "id": 1, "name": "Lyons Hooper" }, { "id": 2, "name": "Shelby Maddox" }, { "id": 3, "name": "Diann Mccoy" }, { "id": 4, "name": "Schwartz Sparks" } ], "greeting": "Hello, Bonita Walls! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826fbd1d0409e5380e6", "index": 70, "guid": "f8b33a80-6690-4a50-a352-13d4283813a8", "isActive": false, "balance": "$1,107.37", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "brown", "name": "Imogene Albert", "gender": "female", "company": "XTH", "email": "imogenealbert@xth.com", "phone": "+1 (894) 427-2742", "address": "189 Congress Street, Clarence, American Samoa, 7272", "about": "Sunt occaecat amet cillum do excepteur laboris id magna exercitation fugiat dolore incididunt sint esse. Veniam cillum qui officia tempor qui qui ex. Elit id deserunt ullamco ut labore nisi reprehenderit irure adipisicing pariatur deserunt laboris. Velit adipisicing nisi consectetur sunt nulla Lorem est id incididunt culpa reprehenderit in commodo.\r\n", "registered": "2014-04-16T08:05:46 -02:00", "latitude": 28.370182, "longitude": 37.607232, "tags": [ "ex", "est", "non", "amet", "occaecat", "adipisicing", "dolore", "sint", "duis", "pariatur" ], "friends": [ { "id": 0, "name": "Davis Mejia" }, { "id": 1, "name": "Courtney Riddle" }, { "id": 2, "name": "Roberta Dixon" }, { "id": 3, "name": "Elinor Ortiz" }, { "id": 4, "name": "Pansy Dunn" } ], "greeting": "Hello, Imogene Albert! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482679572203ce563c57", "index": 71, "guid": "ca206e4f-63d6-4cfd-b5da-5bb04117b40a", "isActive": true, "balance": "$3,568.17", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "green", "name": "Hutchinson Palmer", "gender": "male", "company": "WEBIOTIC", "email": "hutchinsonpalmer@webiotic.com", "phone": "+1 (859) 536-3343", "address": "507 Lorraine Street, Eastmont, Maryland, 9324", "about": "Sunt incididunt ex excepteur eu cupidatat nostrud nisi non quis consectetur fugiat irure reprehenderit. Lorem reprehenderit in est quis. Eu aute eiusmod qui do.\r\n", "registered": "2016-01-01T09:11:06 -01:00", "latitude": -22.791505, "longitude": -33.460602, "tags": [ "elit", "consequat", "commodo", "labore", "cillum", "do", "consequat", "enim", "reprehenderit", "velit" ], "friends": [ { "id": 0, "name": "Spencer Ayers" }, { "id": 1, "name": "Fulton Foster" }, { "id": 2, "name": "Barnett Merritt" }, { "id": 3, "name": "David Allison" }, { "id": 4, "name": "Marquez Clemons" } ], "greeting": "Hello, Hutchinson Palmer! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48264eefacfecaf79d78", "index": 72, "guid": "c419fe2b-691a-4c71-9900-a1eb3680de5b", "isActive": false, "balance": "$3,316.45", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "green", "name": "Liliana Mcdonald", "gender": "female", "company": "EWAVES", "email": "lilianamcdonald@ewaves.com", "phone": "+1 (870) 495-2473", "address": "325 Beacon Court, Idledale, California, 456", "about": "Proident mollit magna et in ea occaecat adipisicing mollit excepteur veniam. Irure fugiat consectetur id veniam amet id magna consequat duis Lorem pariatur laboris ea. Commodo aute sit nisi nulla aliqua aliqua dolore non eiusmod in culpa. Ullamco reprehenderit proident pariatur non nulla sit dolore ea fugiat officia do fugiat.\r\n", "registered": "2016-11-07T07:44:14 -01:00", "latitude": 86.861854, "longitude": 176.858653, "tags": [ "sit", "aute", "nisi", "eiusmod", "sint", "excepteur", "eiusmod", "laborum", "irure", "adipisicing" ], "friends": [ { "id": 0, "name": "Corinne Leon" }, { "id": 1, "name": "Whitfield Owen" }, { "id": 2, "name": "Jaime Levy" }, { "id": 3, "name": "Burns Cain" }, { "id": 4, "name": "Robyn Vance" } ], "greeting": "Hello, Liliana Mcdonald! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48262d35433e0beafda9", "index": 73, "guid": "1fe9d702-aa67-442c-862c-63eeca389d45", "isActive": true, "balance": "$1,872.97", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Karyn Harvey", "gender": "female", "company": "CALCU", "email": "karynharvey@calcu.com", "phone": "+1 (971) 436-2386", "address": "125 Kaufman Place, Dexter, Utah, 4381", "about": "Cillum est est labore incididunt reprehenderit labore sunt laborum aute incididunt. Tempor elit nulla cupidatat consequat labore culpa quis elit aliquip commodo. Et consequat officia officia reprehenderit esse incididunt irure ad amet.\r\n", "registered": "2018-01-09T06:43:36 -01:00", "latitude": -67.425568, "longitude": -158.220043, "tags": [ "laboris", "laborum", "consectetur", "dolor", "ea", "exercitation", "exercitation", "anim", "sunt", "proident" ], "friends": [ { "id": 0, "name": "Magdalena Jackson" }, { "id": 1, "name": "Burch Rivas" }, { "id": 2, "name": "Lloyd Craft" }, { "id": 3, "name": "Shepherd Carver" }, { "id": 4, "name": "Gloria Vasquez" } ], "greeting": "Hello, Karyn Harvey! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826c57e4a4412319338", "index": 74, "guid": "be6fde60-05f9-4ba3-a79d-b648f7d9b6a1", "isActive": true, "balance": "$1,210.23", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "brown", "name": "Small Pitts", "gender": "male", "company": "ECOLIGHT", "email": "smallpitts@ecolight.com", "phone": "+1 (837) 489-2393", "address": "252 Sedgwick Street, Williston, Iowa, 8020", "about": "Fugiat laboris commodo excepteur do amet fugiat enim deserunt et proident ad. Laboris aute enim deserunt veniam labore irure. Anim Lorem id eiusmod reprehenderit mollit irure anim. Cupidatat eiusmod dolore magna nisi excepteur mollit exercitation qui adipisicing sunt et quis adipisicing. Eiusmod veniam voluptate nisi eiusmod incididunt enim.\r\n", "registered": "2015-03-15T10:02:25 -01:00", "latitude": 67.947606, "longitude": -96.171244, "tags": [ "esse", "eu", "cupidatat", "mollit", "quis", "labore", "do", "pariatur", "Lorem", "commodo" ], "friends": [ { "id": 0, "name": "Waters Harmon" }, { "id": 1, "name": "Adrienne Stone" }, { "id": 2, "name": "Adriana Mcdaniel" }, { "id": 3, "name": "Talley Mcmillan" }, { "id": 4, "name": "Jasmine Browning" } ], "greeting": "Hello, Small Pitts! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ff98c5be94d9665b", "index": 75, "guid": "a4d1224a-08a0-4201-863a-3f091961cf56", "isActive": false, "balance": "$3,686.82", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Verna Harris", "gender": "female", "company": "XYMONK", "email": "vernaharris@xymonk.com", "phone": "+1 (833) 442-3435", "address": "815 Dorchester Road, Waterloo, North Dakota, 2568", "about": "Laborum irure ullamco deserunt nisi irure Lorem excepteur reprehenderit incididunt amet. Velit pariatur esse adipisicing id dolor consectetur. Incididunt sit consequat minim consectetur non do anim aliquip duis minim reprehenderit sint. Mollit magna proident ad aute ex id cupidatat qui aliquip fugiat. Reprehenderit eiusmod veniam et incididunt aute anim aliqua aliquip mollit aliquip non non.\r\n", "registered": "2014-07-09T02:36:29 -02:00", "latitude": 22.451677, "longitude": 164.468714, "tags": [ "ut", "ut", "dolore", "do", "sint", "proident", "sunt", "ipsum", "anim", "esse" ], "friends": [ { "id": 0, "name": "Andrews Perez" }, { "id": 1, "name": "Lillie Oconnor" }, { "id": 2, "name": "James Cooley" }, { "id": 3, "name": "Owen Clarke" }, { "id": 4, "name": "Dominique Castro" } ], "greeting": "Hello, Verna Harris! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826411490487ec0e568", "index": 76, "guid": "c062cb08-7c27-4283-b99c-e73d35512d71", "isActive": false, "balance": "$2,527.74", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Lucille Diaz", "gender": "female", "company": "ZOMBOID", "email": "lucillediaz@zomboid.com", "phone": "+1 (967) 543-3845", "address": "611 Coffey Street, Ladera, Kentucky, 6808", "about": "Magna sunt labore adipisicing tempor nulla nostrud irure. Eiusmod cillum velit occaecat ea aliqua in pariatur excepteur minim culpa. Deserunt duis duis enim aliqua Lorem voluptate anim magna mollit reprehenderit nostrud et ullamco laborum. Pariatur ipsum quis veniam nisi anim officia et duis commodo velit laborum reprehenderit. Eu veniam anim ut do sint officia fugiat non. Eu fugiat sunt nisi sint laboris eu. Occaecat exercitation culpa qui ullamco est veniam irure amet proident proident non.\r\n", "registered": "2017-03-21T03:10:48 -01:00", "latitude": 23.119215, "longitude": 83.486475, "tags": [ "proident", "exercitation", "amet", "in", "aliquip", "voluptate", "nisi", "exercitation", "dolor", "elit" ], "friends": [ { "id": 0, "name": "Penelope Garrison" }, { "id": 1, "name": "Kirk Cantrell" }, { "id": 2, "name": "Knight Farrell" }, { "id": 3, "name": "Rhodes Franco" }, { "id": 4, "name": "Rosa Hopper" } ], "greeting": "Hello, Lucille Diaz! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ba9c18a3fba7055f", "index": 77, "guid": "d99d17a8-16a8-410c-8dfc-eb8ae994877b", "isActive": false, "balance": "$2,745.63", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Mable Dillon", "gender": "female", "company": "NIQUENT", "email": "mabledillon@niquent.com", "phone": "+1 (861) 535-2708", "address": "263 Oceanview Avenue, Ripley, Colorado, 8586", "about": "Magna tempor amet et consectetur cillum fugiat sit occaecat. Veniam ullamco ullamco cillum culpa anim commodo nisi aliqua aliquip incididunt esse. Aute cupidatat ex culpa aliqua occaecat adipisicing veniam.\r\n", "registered": "2014-07-26T01:55:52 -02:00", "latitude": 59.309807, "longitude": -55.47535, "tags": [ "officia", "laboris", "minim", "sunt", "velit", "sunt", "reprehenderit", "incididunt", "duis", "excepteur" ], "friends": [ { "id": 0, "name": "Frederick York" }, { "id": 1, "name": "Collins Rodriguez" }, { "id": 2, "name": "Salas Larson" }, { "id": 3, "name": "Lowery Koch" }, { "id": 4, "name": "Valeria Gregory" } ], "greeting": "Hello, Mable Dillon! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826eeba7fd0f519c47c", "index": 78, "guid": "e5714aec-d162-499e-93b4-655a43554012", "isActive": false, "balance": "$1,442.43", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Cherry Salazar", "gender": "male", "company": "KLUGGER", "email": "cherrysalazar@klugger.com", "phone": "+1 (999) 517-3074", "address": "210 Railroad Avenue, Marienthal, New Hampshire, 100", "about": "Labore elit dolore eiusmod ut cillum esse labore aliquip ad ad velit irure. Et in excepteur ex duis magna nostrud culpa adipisicing pariatur dolor ut excepteur aliqua occaecat. Nulla exercitation non dolor amet est ea adipisicing laboris. Aliquip eiusmod sint tempor nisi.\r\n", "registered": "2016-03-28T02:19:44 -02:00", "latitude": -62.91592, "longitude": -35.664809, "tags": [ "amet", "dolore", "esse", "irure", "est", "ad", "dolore", "aute", "reprehenderit", "ullamco" ], "friends": [ { "id": 0, "name": "Marisa Becker" }, { "id": 1, "name": "Stuart Byrd" }, { "id": 2, "name": "Mckinney Boone" }, { "id": 3, "name": "Dana Barnett" }, { "id": 4, "name": "Roberts Huff" } ], "greeting": "Hello, Cherry Salazar! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826d43b2953a1ab3729", "index": 79, "guid": "ed7c3e8b-b1f9-4697-a57d-2c204f597c2f", "isActive": true, "balance": "$2,646.94", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Wiley Brady", "gender": "male", "company": "QNEKT", "email": "wileybrady@qnekt.com", "phone": "+1 (804) 558-3220", "address": "602 Saratoga Avenue, Wolcott, Wisconsin, 2460", "about": "Ut officia amet fugiat mollit quis occaecat id excepteur consequat occaecat enim exercitation cupidatat. Reprehenderit id minim et quis veniam do in eiusmod proident nisi. Est laborum incididunt reprehenderit cupidatat veniam velit. Excepteur laborum sunt dolore anim duis nisi do ea pariatur.\r\n", "registered": "2015-08-13T06:14:16 -02:00", "latitude": 64.084083, "longitude": 151.783912, "tags": [ "Lorem", "deserunt", "labore", "eu", "do", "excepteur", "nulla", "eiusmod", "reprehenderit", "eiusmod" ], "friends": [ { "id": 0, "name": "Dolly Hoover" }, { "id": 1, "name": "Elva Clay" }, { "id": 2, "name": "Louisa Chaney" }, { "id": 3, "name": "Kayla Larsen" }, { "id": 4, "name": "Laurie Nicholson" } ], "greeting": "Hello, Wiley Brady! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826377450b39ce94ce8", "index": 80, "guid": "8002fa01-d891-4365-b5c6-515517f2afe7", "isActive": false, "balance": "$1,895.78", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Lottie Mcmahon", "gender": "female", "company": "PRINTSPAN", "email": "lottiemcmahon@printspan.com", "phone": "+1 (886) 457-3282", "address": "211 Grace Court, Trail, Idaho, 4215", "about": "Voluptate dolor amet eu ad. Proident do quis pariatur incididunt voluptate ullamco. Aliquip excepteur excepteur occaecat id sit cillum quis eiusmod. Officia nostrud ipsum aute ea elit. Ut velit et laboris fugiat magna.\r\n", "registered": "2015-10-28T12:49:25 -01:00", "latitude": -7.445032, "longitude": -130.213701, "tags": [ "Lorem", "qui", "velit", "labore", "voluptate", "ipsum", "duis", "esse", "pariatur", "sit" ], "friends": [ { "id": 0, "name": "Coleman Wilson" }, { "id": 1, "name": "Kerry Galloway" }, { "id": 2, "name": "Vickie Everett" }, { "id": 3, "name": "Petty Meadows" }, { "id": 4, "name": "Sheree Hinton" } ], "greeting": "Hello, Lottie Mcmahon! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482691c2c4e8e7eaa6bd", "index": 81, "guid": "b1675e49-5614-45fa-9baa-4b9eeff47c55", "isActive": false, "balance": "$3,809.64", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "blue", "name": "Doyle Sharpe", "gender": "male", "company": "SYNKGEN", "email": "doylesharpe@synkgen.com", "phone": "+1 (992) 439-2210", "address": "616 Herkimer Place, Caledonia, Georgia, 3786", "about": "Labore nostrud excepteur consectetur elit enim velit voluptate consequat occaecat sit excepteur laboris occaecat. Dolor laboris cupidatat mollit occaecat et eiusmod. Ut aliquip adipisicing anim consequat tempor ut anim mollit ex.\r\n", "registered": "2017-04-20T09:44:53 -02:00", "latitude": -30.879245, "longitude": -7.670559, "tags": [ "ullamco", "fugiat", "occaecat", "et", "occaecat", "et", "irure", "id", "et", "id" ], "friends": [ { "id": 0, "name": "Jayne Buckner" }, { "id": 1, "name": "Chase Morris" }, { "id": 2, "name": "Sherrie Wilder" }, { "id": 3, "name": "Eloise Olsen" }, { "id": 4, "name": "Perry Garner" } ], "greeting": "Hello, Doyle Sharpe! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e5d04aef5b7d0213", "index": 82, "guid": "8a210dee-1522-460e-acdc-07e8617da558", "isActive": true, "balance": "$3,021.13", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Graham Walker", "gender": "male", "company": "ACCUPHARM", "email": "grahamwalker@accupharm.com", "phone": "+1 (866) 414-3965", "address": "121 Hampton Place, Homeworth, Virgin Islands, 3466", "about": "Commodo irure aute excepteur sit pariatur eu aliqua sint ex non. Commodo sit incididunt veniam amet aliqua cillum ipsum velit reprehenderit nisi. Exercitation nulla tempor aute et.\r\n", "registered": "2016-06-28T09:58:31 -02:00", "latitude": -17.771131, "longitude": 18.541356, "tags": [ "veniam", "ea", "non", "amet", "deserunt", "veniam", "nisi", "id", "do", "dolor" ], "friends": [ { "id": 0, "name": "Riley Neal" }, { "id": 1, "name": "Blevins Colon" }, { "id": 2, "name": "Hodge Mercer" }, { "id": 3, "name": "Tanner Hicks" }, { "id": 4, "name": "Burnett Nguyen" } ], "greeting": "Hello, Graham Walker! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826a93d5000653d75c8", "index": 83, "guid": "b29cd26f-c0df-4f38-a646-0d8066491c86", "isActive": true, "balance": "$1,317.17", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Newton Bell", "gender": "male", "company": "GEEKOSIS", "email": "newtonbell@geekosis.com", "phone": "+1 (940) 545-2522", "address": "871 Johnson Street, Byrnedale, Minnesota, 8967", "about": "Irure aliquip culpa pariatur laborum dolore minim. Laboris nulla reprehenderit eu nulla amet qui. Occaecat quis sit sit esse cillum culpa irure non et est deserunt. Nisi pariatur et anim et ipsum ullamco ullamco consequat. Et pariatur ipsum sit veniam Lorem irure sit exercitation exercitation mollit in. Sunt ad ut aliquip fugiat occaecat voluptate.\r\n", "registered": "2017-09-20T05:38:29 -02:00", "latitude": 82.995596, "longitude": 84.824808, "tags": [ "exercitation", "ut", "ad", "id", "adipisicing", "in", "ullamco", "do", "labore", "incididunt" ], "friends": [ { "id": 0, "name": "Sellers Leonard" }, { "id": 1, "name": "Dee Hart" }, { "id": 2, "name": "Cook Carr" }, { "id": 3, "name": "Horton Mcgee" }, { "id": 4, "name": "Humphrey Smith" } ], "greeting": "Hello, Newton Bell! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826d3f97682f8fbe2f8", "index": 84, "guid": "dd9d7a80-68f0-4b6a-aab8-47d5dcf78411", "isActive": true, "balance": "$1,448.48", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Ingram Riggs", "gender": "male", "company": "MULTIFLEX", "email": "ingramriggs@multiflex.com", "phone": "+1 (943) 425-3529", "address": "514 Ferris Street, Noxen, South Carolina, 9280", "about": "Fugiat culpa mollit veniam excepteur commodo eiusmod est veniam consectetur quis sint voluptate laborum non. Ex elit laboris magna pariatur laborum ex labore ea ullamco commodo ut. Mollit eu incididunt duis ex magna excepteur laborum sit adipisicing occaecat proident nulla. Consequat id consequat dolore culpa ipsum incididunt ea nisi. In aute quis enim elit. Et fugiat nostrud et dolore esse est do dolore pariatur eu. Enim dolor dolore anim laboris labore excepteur ea.\r\n", "registered": "2017-01-03T09:16:58 -01:00", "latitude": 66.793886, "longitude": 162.011323, "tags": [ "id", "ipsum", "laboris", "consequat", "est", "veniam", "velit", "ut", "labore", "minim" ], "friends": [ { "id": 0, "name": "Georgina Oneil" }, { "id": 1, "name": "Nolan Cobb" }, { "id": 2, "name": "Franks Velez" }, { "id": 3, "name": "Hendricks Wiley" }, { "id": 4, "name": "Barron Doyle" } ], "greeting": "Hello, Ingram Riggs! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48267ab8e7f5d6e94f8f", "index": 85, "guid": "75987cd9-e206-47b2-ae61-a149dbd659df", "isActive": false, "balance": "$1,893.26", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Mendez Rogers", "gender": "male", "company": "EXOVENT", "email": "mendezrogers@exovent.com", "phone": "+1 (974) 483-2114", "address": "776 Frost Street, Sutton, Northern Mariana Islands, 6194", "about": "Quis aute irure consequat Lorem ullamco mollit enim cupidatat tempor. Ullamco mollit dolor exercitation et sint magna pariatur excepteur irure eu eiusmod sint laboris excepteur. Excepteur mollit non proident Lorem tempor laborum consectetur tempor aliquip commodo magna laborum.\r\n", "registered": "2017-03-16T07:27:26 -01:00", "latitude": 80.393395, "longitude": -116.958777, "tags": [ "do", "ea", "duis", "dolor", "nisi", "fugiat", "est", "pariatur", "cupidatat", "minim" ], "friends": [ { "id": 0, "name": "Cooke Lamb" }, { "id": 1, "name": "Conley Juarez" }, { "id": 2, "name": "Kelley Duran" }, { "id": 3, "name": "Wendy Rowe" }, { "id": 4, "name": "Adele Roberson" } ], "greeting": "Hello, Mendez Rogers! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482628dc09af73bf6acc", "index": 86, "guid": "d9d85299-d8af-424f-92d3-6722bae14757", "isActive": true, "balance": "$1,853.11", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "England Beach", "gender": "male", "company": "OULU", "email": "englandbeach@oulu.com", "phone": "+1 (888) 431-3710", "address": "676 Beaver Street, Holtville, Pennsylvania, 5117", "about": "Voluptate elit irure aute exercitation magna. Lorem consequat aliqua sunt incididunt labore. Voluptate enim aliquip sunt reprehenderit. Ullamco sunt commodo consectetur esse. Voluptate nostrud fugiat id adipisicing.\r\n", "registered": "2015-06-13T08:29:12 -02:00", "latitude": -8.873743, "longitude": -107.861211, "tags": [ "occaecat", "cupidatat", "consequat", "esse", "reprehenderit", "Lorem", "eu", "proident", "cupidatat", "nisi" ], "friends": [ { "id": 0, "name": "Townsend Schneider" }, { "id": 1, "name": "Jodie Sharp" }, { "id": 2, "name": "John Rocha" }, { "id": 3, "name": "Herminia Key" }, { "id": 4, "name": "Gwen Barr" } ], "greeting": "Hello, England Beach! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826646ed132ebb719f0", "index": 87, "guid": "2b987545-c3b8-4db4-aa2e-0c5bc3744388", "isActive": false, "balance": "$1,483.20", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "green", "name": "Dalton Valdez", "gender": "male", "company": "WARETEL", "email": "daltonvaldez@waretel.com", "phone": "+1 (906) 528-3561", "address": "361 Beayer Place, Ruckersville, Arkansas, 687", "about": "Excepteur cupidatat deserunt commodo incididunt do culpa aute id aute qui. Aliquip amet esse officia cupidatat ea velit nisi cupidatat veniam exercitation velit. Laborum dolor qui mollit sunt consequat eu occaecat occaecat dolore dolore pariatur pariatur commodo quis. Aute do minim voluptate sit commodo.\r\n", "registered": "2015-07-01T01:19:03 -02:00", "latitude": 86.53727, "longitude": 36.429077, "tags": [ "velit", "sit", "quis", "Lorem", "in", "commodo", "laboris", "exercitation", "dolore", "ipsum" ], "friends": [ { "id": 0, "name": "Lynette Kennedy" }, { "id": 1, "name": "Glenna Marsh" }, { "id": 2, "name": "Alford Talley" }, { "id": 3, "name": "Stout King" }, { "id": 4, "name": "Laura Manning" } ], "greeting": "Hello, Dalton Valdez! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826bbbf4c6870e0e97b", "index": 88, "guid": "f1b5f827-585d-44cc-9c22-b35849998895", "isActive": false, "balance": "$1,107.49", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Liza Pittman", "gender": "female", "company": "FORTEAN", "email": "lizapittman@fortean.com", "phone": "+1 (938) 569-3291", "address": "305 Just Court, Trona, Palau, 266", "about": "Sit enim anim proident adipisicing excepteur duis elit ea. Quis elit proident sit ad excepteur nulla aliqua do. Reprehenderit pariatur id excepteur consectetur. Sit proident pariatur enim cupidatat.\r\n", "registered": "2017-06-20T09:14:05 -02:00", "latitude": 5.634369, "longitude": -32.326698, "tags": [ "nulla", "eu", "excepteur", "minim", "duis", "minim", "enim", "duis", "occaecat", "sunt" ], "friends": [ { "id": 0, "name": "Charles Bradford" }, { "id": 1, "name": "Stanley Kane" }, { "id": 2, "name": "Mcguire Mendoza" }, { "id": 3, "name": "Melody Hall" }, { "id": 4, "name": "Key Le" } ], "greeting": "Hello, Liza Pittman! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826947f684c2387d72c", "index": 89, "guid": "f78ac877-7546-483f-998e-bfa30a3bc0ed", "isActive": true, "balance": "$2,270.63", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "blue", "name": "Clemons Anthony", "gender": "male", "company": "DAISU", "email": "clemonsanthony@daisu.com", "phone": "+1 (910) 493-2612", "address": "622 Court Square, Leroy, Connecticut, 9325", "about": "Anim qui sint magna dolore eiusmod mollit non laborum irure dolore adipisicing amet veniam cupidatat. Deserunt ullamco minim sunt eu dolor laboris officia sint ea. Eiusmod esse ea exercitation non sunt amet tempor.\r\n", "registered": "2015-08-11T09:50:56 -02:00", "latitude": 89.248413, "longitude": 146.894447, "tags": [ "culpa", "tempor", "commodo", "fugiat", "mollit", "veniam", "fugiat", "laboris", "nisi", "anim" ], "friends": [ { "id": 0, "name": "Milagros French" }, { "id": 1, "name": "Best Goodman" }, { "id": 2, "name": "Oconnor Ashley" }, { "id": 3, "name": "Ann Skinner" }, { "id": 4, "name": "Estes Woodward" } ], "greeting": "Hello, Clemons Anthony! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48262e24875caa7f0ec5", "index": 90, "guid": "97b0ddb9-9796-4629-bd09-ce0f43f39392", "isActive": false, "balance": "$2,412.93", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "brown", "name": "Kerri Barry", "gender": "female", "company": "NETAGY", "email": "kerribarry@netagy.com", "phone": "+1 (849) 414-3854", "address": "445 Commerce Street, Esmont, North Carolina, 5902", "about": "Fugiat enim duis elit qui occaecat aute quis aliqua. Ipsum ut non dolor pariatur. Ea adipisicing anim anim esse adipisicing laboris mollit dolor esse officia occaecat elit. Sint duis esse elit aliqua fugiat cupidatat ex esse reprehenderit ex Lorem amet consequat nostrud. Ea pariatur minim qui ullamco proident nostrud exercitation culpa ullamco veniam voluptate cupidatat. Anim non commodo adipisicing ex do exercitation commodo ullamco non.\r\n", "registered": "2015-12-26T12:23:18 -01:00", "latitude": 24.641541, "longitude": 69.903365, "tags": [ "sint", "ipsum", "cillum", "excepteur", "commodo", "consequat", "do", "est", "minim", "incididunt" ], "friends": [ { "id": 0, "name": "Barrera Mack" }, { "id": 1, "name": "Melton Woods" }, { "id": 2, "name": "Henry Bishop" }, { "id": 3, "name": "Solomon Sanders" }, { "id": 4, "name": "Austin Mcpherson" } ], "greeting": "Hello, Kerri Barry! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826d66a9079aa92d4b0", "index": 91, "guid": "d7247a37-dc14-4a0d-8bdd-67342fd9e491", "isActive": false, "balance": "$3,990.14", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Patti Oneill", "gender": "female", "company": "ZENTURY", "email": "pattioneill@zentury.com", "phone": "+1 (966) 427-3774", "address": "451 Ditmars Street, Canterwood, Missouri, 2724", "about": "Excepteur anim quis ut elit do laboris magna. Aute magna ipsum sit dolor elit consequat occaecat id. Quis magna duis aliquip incididunt duis adipisicing eiusmod veniam minim. Consequat deserunt voluptate amet eu cupidatat fugiat laborum commodo. Sit tempor consequat eiusmod excepteur enim ipsum reprehenderit ut labore voluptate. In culpa exercitation incididunt dolor anim eiusmod cupidatat consectetur occaecat deserunt officia et duis. Eiusmod in fugiat tempor officia veniam et sunt nostrud pariatur sint dolore amet ullamco proident.\r\n", "registered": "2017-06-15T11:18:02 -02:00", "latitude": -61.033504, "longitude": -14.790598, "tags": [ "proident", "exercitation", "ex", "dolore", "veniam", "amet", "in", "reprehenderit", "eiusmod", "nisi" ], "friends": [ { "id": 0, "name": "Audrey Rhodes" }, { "id": 1, "name": "Heath Ball" }, { "id": 2, "name": "Deborah Acosta" }, { "id": 3, "name": "Casey Cox" }, { "id": 4, "name": "Tommie Cleveland" } ], "greeting": "Hello, Patti Oneill! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826516633157ee57931", "index": 92, "guid": "fd595b56-ec1d-4016-ab0c-1a7b1632c14c", "isActive": false, "balance": "$2,757.43", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Salazar Flynn", "gender": "male", "company": "MOTOVATE", "email": "salazarflynn@motovate.com", "phone": "+1 (884) 546-3453", "address": "652 Temple Court, Joes, Ohio, 7420", "about": "Ullamco exercitation commodo ullamco tempor esse consequat cillum. Sint qui magna ipsum ut irure aute ea ullamco adipisicing eiusmod. Cupidatat deserunt anim eiusmod enim Lorem laboris deserunt veniam.\r\n", "registered": "2016-07-19T06:19:25 -02:00", "latitude": 59.184972, "longitude": -151.107047, "tags": [ "enim", "minim", "incididunt", "proident", "duis", "culpa", "exercitation", "elit", "aliquip", "aliqua" ], "friends": [ { "id": 0, "name": "Curtis Martinez" }, { "id": 1, "name": "Sharpe Sutton" }, { "id": 2, "name": "Priscilla Jennings" }, { "id": 3, "name": "Coleen Bender" }, { "id": 4, "name": "Tate Norton" } ], "greeting": "Hello, Salazar Flynn! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48260d45d9c9d45d1c51", "index": 93, "guid": "1ceadc24-d6df-473f-b9ab-95c6b09cc703", "isActive": false, "balance": "$1,301.34", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Rose Mosley", "gender": "male", "company": "XINWARE", "email": "rosemosley@xinware.com", "phone": "+1 (909) 598-2627", "address": "139 Langham Street, Sterling, Arizona, 6260", "about": "Consequat minim ipsum mollit nisi aute anim consequat aute deserunt aute qui adipisicing excepteur pariatur. Voluptate et labore do elit aliqua velit cillum reprehenderit pariatur. Proident incididunt aute est labore commodo laborum occaecat est fugiat laborum id. Mollit duis laborum qui consectetur elit officia proident voluptate dolore velit ad. Ex aliqua tempor sit voluptate velit non labore veniam quis sunt eiusmod elit dolor ad.\r\n", "registered": "2016-11-26T11:09:25 -01:00", "latitude": 51.070461, "longitude": 156.133239, "tags": [ "cupidatat", "esse", "elit", "aute", "qui", "nulla", "eu", "et", "commodo", "ipsum" ], "friends": [ { "id": 0, "name": "Elena Ray" }, { "id": 1, "name": "Cherie Banks" }, { "id": 2, "name": "Rosario Bennett" }, { "id": 3, "name": "Casandra Orr" }, { "id": 4, "name": "Mai Stanton" } ], "greeting": "Hello, Rose Mosley! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48263c0c3b58d1fccab1", "index": 94, "guid": "a10ac249-beef-44c9-9528-8f4c78c7f914", "isActive": false, "balance": "$2,353.67", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Andrea Bryant", "gender": "female", "company": "ACCUFARM", "email": "andreabryant@accufarm.com", "phone": "+1 (851) 565-3287", "address": "832 Prince Street, Beason, Montana, 8083", "about": "Aliqua proident magna proident proident ullamco fugiat qui aute adipisicing sit. Quis aliquip exercitation fugiat aliquip nulla proident est esse laborum officia adipisicing in. Et veniam voluptate nulla nostrud eu velit aute.\r\n", "registered": "2016-11-02T07:35:21 -01:00", "latitude": -53.690929, "longitude": -77.013106, "tags": [ "sint", "ea", "nostrud", "duis", "velit", "elit", "esse", "minim", "nostrud", "non" ], "friends": [ { "id": 0, "name": "Grimes Petty" }, { "id": 1, "name": "Julianne Weber" }, { "id": 2, "name": "Lindsay Romero" }, { "id": 3, "name": "Madden Price" }, { "id": 4, "name": "Terry Steele" } ], "greeting": "Hello, Andrea Bryant! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e4147e27e31950e3", "index": 95, "guid": "cfd190bc-91c7-4582-8952-f8d2d327ab2e", "isActive": true, "balance": "$3,888.10", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "green", "name": "Floyd Stark", "gender": "male", "company": "KOG", "email": "floydstark@kog.com", "phone": "+1 (855) 478-3755", "address": "841 Abbey Court, Woodburn, Texas, 2287", "about": "Cillum nulla nostrud ad eu id do commodo. Commodo laboris reprehenderit labore et velit velit esse esse ipsum exercitation deserunt esse minim. Fugiat est dolor enim aliqua ullamco proident consectetur pariatur quis ex ex anim.\r\n", "registered": "2017-11-27T05:21:36 -01:00", "latitude": 20.052972, "longitude": 109.688135, "tags": [ "tempor", "elit", "consectetur", "eu", "consequat", "tempor", "ullamco", "consectetur", "velit", "et" ], "friends": [ { "id": 0, "name": "Holmes Alston" }, { "id": 1, "name": "Shaw Norman" }, { "id": 2, "name": "Rosanna Morrow" }, { "id": 3, "name": "Abby Bowers" }, { "id": 4, "name": "Fannie Crawford" } ], "greeting": "Hello, Floyd Stark! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826ecbd5078de14d21a", "index": 96, "guid": "704eac8f-cc1d-432c-925a-c8e414799e1d", "isActive": true, "balance": "$1,764.28", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "blue", "name": "Lara Robbins", "gender": "male", "company": "MAZUDA", "email": "lararobbins@mazuda.com", "phone": "+1 (890) 410-2848", "address": "515 Branton Street, Dennard, Washington, 7093", "about": "Elit est excepteur velit adipisicing esse excepteur Lorem duis ea fugiat laborum aute. Sint aliqua velit nostrud cupidatat sit deserunt laborum ad. Dolor est qui enim mollit dolor ad ea consectetur labore ut ex id duis. Reprehenderit fugiat enim anim voluptate.\r\n", "registered": "2016-02-08T06:36:47 -01:00", "latitude": 1.186394, "longitude": -176.249886, "tags": [ "velit", "sit", "elit", "commodo", "velit", "fugiat", "ad", "incididunt", "exercitation", "tempor" ], "friends": [ { "id": 0, "name": "Petersen Silva" }, { "id": 1, "name": "Camille Kaufman" }, { "id": 2, "name": "Rowland Crane" }, { "id": 3, "name": "Shelley Robertson" }, { "id": 4, "name": "Allyson Rosa" } ], "greeting": "Hello, Lara Robbins! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48269168e1eaf72ec086", "index": 97, "guid": "49400e53-980c-4aa6-85b4-bcf56e184109", "isActive": false, "balance": "$1,456.53", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "green", "name": "Bernadette Mccarthy", "gender": "female", "company": "KIOSK", "email": "bernadettemccarthy@kiosk.com", "phone": "+1 (922) 407-3858", "address": "114 Jodie Court, Templeton, Wyoming, 969", "about": "Amet est sunt irure nulla elit magna aliqua ullamco mollit veniam fugiat ullamco excepteur do. Cupidatat laborum aute exercitation ad. Nisi sit duis sint sint. Non consectetur Lorem voluptate in magna ipsum elit sit irure tempor. Excepteur officia do in aliquip excepteur quis ut excepteur consectetur eiusmod. Dolor ipsum exercitation Lorem laborum reprehenderit irure.\r\n", "registered": "2014-01-24T02:27:52 -01:00", "latitude": -55.782734, "longitude": 64.32626, "tags": [ "mollit", "enim", "quis", "enim", "ut", "velit", "culpa", "elit", "pariatur", "incididunt" ], "friends": [ { "id": 0, "name": "Mcdaniel Pace" }, { "id": 1, "name": "Nikki Parker" }, { "id": 2, "name": "Stewart Francis" }, { "id": 3, "name": "Tammy Tyler" }, { "id": 4, "name": "Neva Dejesus" } ], "greeting": "Hello, Bernadette Mccarthy! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f6ccece597ef6f2f", "index": 98, "guid": "bc946392-c4c5-4382-820d-63b04733751a", "isActive": true, "balance": "$2,578.33", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Roseann Bonner", "gender": "female", "company": "SIGNITY", "email": "roseannbonner@signity.com", "phone": "+1 (915) 476-2978", "address": "862 Ivan Court, Limestone, Indiana, 2058", "about": "Quis et adipisicing laborum ex labore ipsum fugiat cupidatat consequat pariatur proident ipsum veniam. Quis voluptate aliqua tempor aute aute esse esse culpa ea nostrud. Proident duis proident dolor laboris ea eiusmod id sunt anim sit voluptate dolore cillum. Sit ullamco irure consectetur excepteur veniam et occaecat elit esse qui nulla velit proident consectetur. Labore enim duis labore non ad irure aute laboris ad id. Elit nisi deserunt enim pariatur voluptate ex aliqua voluptate ullamco dolor exercitation mollit tempor.\r\n", "registered": "2015-12-26T08:22:16 -01:00", "latitude": -88.581251, "longitude": 48.136505, "tags": [ "non", "cillum", "incididunt", "do", "culpa", "elit", "officia", "eu", "proident", "labore" ], "friends": [ { "id": 0, "name": "Maggie Macias" }, { "id": 1, "name": "Harmon Ayala" }, { "id": 2, "name": "Bowen Cherry" }, { "id": 3, "name": "Angelica Long" }, { "id": 4, "name": "Serena Burgess" } ], "greeting": "Hello, Roseann Bonner! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e3297b204ad82148", "index": 99, "guid": "396804f2-c187-4936-a595-d4d6d2bc07c5", "isActive": false, "balance": "$2,235.00", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Boone Jefferson", "gender": "male", "company": "ZENSOR", "email": "boonejefferson@zensor.com", "phone": "+1 (952) 408-3563", "address": "304 Macon Street, Tyro, Alabama, 9993", "about": "Consequat laboris occaecat non reprehenderit ex do cillum consequat laborum. Deserunt tempor dolore voluptate cillum. Sunt non labore ullamco reprehenderit id aute.\r\n", "registered": "2014-06-12T07:30:03 -02:00", "latitude": -67.963849, "longitude": 69.39328, "tags": [ "incididunt", "eu", "voluptate", "nulla", "amet", "enim", "exercitation", "minim", "aute", "velit" ], "friends": [ { "id": 0, "name": "Fran Oliver" }, { "id": 1, "name": "Sawyer Barton" }, { "id": 2, "name": "Aida Olson" }, { "id": 3, "name": "Weiss Stephens" }, { "id": 4, "name": "Watkins Miller" } ], "greeting": "Hello, Boone Jefferson! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48262233303034aa24fa", "index": 100, "guid": "03443018-80f4-40ab-93d7-db7b37cd920c", "isActive": true, "balance": "$2,828.09", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "brown", "name": "Genevieve Zimmerman", "gender": "female", "company": "FLEETMIX", "email": "genevievezimmerman@fleetmix.com", "phone": "+1 (828) 565-2982", "address": "874 Debevoise Avenue, Lacomb, Virginia, 3245", "about": "Adipisicing enim ea do reprehenderit minim adipisicing duis sunt sunt in nostrud minim. Fugiat ea laboris cillum nisi eiusmod labore. Sunt voluptate Lorem amet nostrud ullamco in non consequat consequat officia ullamco non labore irure. Aliqua adipisicing qui et aliqua officia culpa enim dolor amet duis dolore. Adipisicing minim et est dolore ipsum ullamco. Anim amet exercitation deserunt amet do sunt dolore sint. Sit reprehenderit nulla eu officia excepteur aliquip fugiat ut eu ea consequat id.\r\n", "registered": "2015-09-11T05:11:53 -02:00", "latitude": 77.750824, "longitude": -132.77587, "tags": [ "elit", "proident", "esse", "Lorem", "nulla", "dolor", "magna", "nostrud", "do", "non" ], "friends": [ { "id": 0, "name": "Janet Fry" }, { "id": 1, "name": "Dillard Waters" }, { "id": 2, "name": "Richard Hayden" }, { "id": 3, "name": "Raquel Pennington" }, { "id": 4, "name": "Jenna Donovan" } ], "greeting": "Hello, Genevieve Zimmerman! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482675095088e7a867ba", "index": 101, "guid": "735d3290-e723-4cc9-ab64-c727da54467f", "isActive": false, "balance": "$2,577.48", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "blue", "name": "Jessica Carey", "gender": "female", "company": "ZENTIA", "email": "jessicacarey@zentia.com", "phone": "+1 (987) 540-3727", "address": "490 Orange Street, Roland, New Mexico, 4199", "about": "Irure excepteur cupidatat duis et incididunt irure ex Lorem dolore id commodo. Irure anim amet adipisicing ut incididunt ut reprehenderit irure irure proident eu enim aute deserunt. Irure exercitation tempor esse consectetur consectetur labore reprehenderit incididunt esse laboris commodo irure cillum. Velit anim anim irure culpa occaecat. Officia nulla consequat irure qui. Eiusmod amet occaecat ullamco incididunt laboris mollit qui. Ea in occaecat in aliqua occaecat sit minim ad officia incididunt est irure.\r\n", "registered": "2016-09-12T05:33:30 -02:00", "latitude": -86.33413, "longitude": 172.067447, "tags": [ "fugiat", "eiusmod", "dolor", "sint", "laboris", "qui", "ut", "labore", "nulla", "reprehenderit" ], "friends": [ { "id": 0, "name": "Dena Love" }, { "id": 1, "name": "Rosemarie Frye" }, { "id": 2, "name": "Brooke Callahan" }, { "id": 3, "name": "Janell Winters" }, { "id": 4, "name": "Monroe Gilliam" } ], "greeting": "Hello, Jessica Carey! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48260bd7657c2b196487", "index": 102, "guid": "4bd2f0fc-7cc2-4de7-80db-306062f3132d", "isActive": true, "balance": "$3,791.00", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Reva Melton", "gender": "female", "company": "LUNCHPOD", "email": "revamelton@lunchpod.com", "phone": "+1 (996) 409-3683", "address": "686 Adler Place, Darrtown, Hawaii, 9106", "about": "Sunt voluptate reprehenderit laboris consectetur consequat aliqua incididunt culpa dolore sunt ea. Dolore cupidatat dolore id mollit elit irure adipisicing cupidatat anim ut. Ea labore aliqua deserunt ex. Consectetur do voluptate qui est excepteur eiusmod dolor sit eu.\r\n", "registered": "2014-01-21T09:37:04 -01:00", "latitude": 30.236991, "longitude": 165.672044, "tags": [ "do", "ullamco", "voluptate", "occaecat", "consectetur", "aute", "voluptate", "qui", "duis", "incididunt" ], "friends": [ { "id": 0, "name": "Julie Carrillo" }, { "id": 1, "name": "Rich Warner" }, { "id": 2, "name": "Viola Alford" }, { "id": 3, "name": "Earline Cline" }, { "id": 4, "name": "Inez Velasquez" } ], "greeting": "Hello, Reva Melton! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826111e27424b1bfaab", "index": 103, "guid": "df47b4a8-363a-4886-9bb2-ba76be73c816", "isActive": false, "balance": "$1,445.61", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Samantha Mckee", "gender": "female", "company": "PIVITOL", "email": "samanthamckee@pivitol.com", "phone": "+1 (950) 534-3412", "address": "681 Halsey Street, Homeland, Nebraska, 5112", "about": "Exercitation veniam eu laboris amet nisi pariatur. Irure ut in ut reprehenderit consectetur id qui aliquip ullamco officia id. Amet voluptate cillum sunt in Lorem officia reprehenderit. Consectetur dolore nulla ad non ullamco.\r\n", "registered": "2017-01-25T10:01:02 -01:00", "latitude": -40.155061, "longitude": -178.966279, "tags": [ "laborum", "mollit", "incididunt", "id", "aliqua", "sit", "ea", "qui", "esse", "adipisicing" ], "friends": [ { "id": 0, "name": "Bruce Hebert" }, { "id": 1, "name": "Mcgowan Sykes" }, { "id": 2, "name": "Gilliam Blair" }, { "id": 3, "name": "Richmond Roach" }, { "id": 4, "name": "Jackie Mitchell" } ], "greeting": "Hello, Samantha Mckee! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482634f240cd045cb4c1", "index": 104, "guid": "dad08616-8b79-4ff5-8ba8-a22e48a6c2d9", "isActive": true, "balance": "$2,636.11", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "brown", "name": "Pugh Vincent", "gender": "male", "company": "GOLOGY", "email": "pughvincent@gology.com", "phone": "+1 (891) 524-3570", "address": "671 Knickerbocker Avenue, Rutherford, New York, 8532", "about": "Officia dolor anim ut nisi Lorem non. Commodo sunt cillum pariatur sunt cupidatat magna dolor aliqua eu exercitation voluptate eu in dolore. Nostrud mollit mollit ea est aute laboris tempor aute ad minim ad. Nulla laboris ipsum commodo mollit cupidatat duis cillum amet occaecat et Lorem. Deserunt ad aliquip anim aliquip. Et irure reprehenderit proident commodo commodo laboris quis reprehenderit deserunt veniam consequat nulla sunt. Fugiat cillum reprehenderit laborum dolore quis aliqua velit in.\r\n", "registered": "2017-07-01T07:55:13 -02:00", "latitude": -45.020186, "longitude": -143.348334, "tags": [ "laboris", "elit", "labore", "sint", "ullamco", "tempor", "fugiat", "culpa", "cillum", "elit" ], "friends": [ { "id": 0, "name": "Ortiz Austin" }, { "id": 1, "name": "Atkinson Glover" }, { "id": 2, "name": "Jeannette Goodwin" }, { "id": 3, "name": "Mathews Compton" }, { "id": 4, "name": "Selena Wooten" } ], "greeting": "Hello, Pugh Vincent! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826aa5e6079224dfa7b", "index": 105, "guid": "58dcf108-6120-44ee-bc5c-d7342381743b", "isActive": false, "balance": "$1,675.24", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "green", "name": "Roxanne Harding", "gender": "female", "company": "AQUAZURE", "email": "roxanneharding@aquazure.com", "phone": "+1 (982) 417-2320", "address": "381 Sullivan Street, Clay, Marshall Islands, 4948", "about": "Cillum anim exercitation enim do elit id cupidatat non laboris consequat. Dolor amet consequat amet commodo nisi laborum in consectetur exercitation fugiat. Anim incididunt officia sit laboris nisi.\r\n", "registered": "2017-12-10T01:21:33 -01:00", "latitude": -57.309905, "longitude": -14.007794, "tags": [ "cillum", "ex", "enim", "exercitation", "nulla", "enim", "minim", "aute", "pariatur", "deserunt" ], "friends": [ { "id": 0, "name": "Kristen Spears" }, { "id": 1, "name": "Herman Giles" }, { "id": 2, "name": "Valentine Branch" }, { "id": 3, "name": "Padilla Mathis" }, { "id": 4, "name": "Ella Carpenter" } ], "greeting": "Hello, Roxanne Harding! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826ef37c196bb981dd5", "index": 106, "guid": "a94ef9d5-4ca7-41c0-ab5b-6e83663baa07", "isActive": false, "balance": "$2,037.59", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Travis Blanchard", "gender": "male", "company": "DIGIGENE", "email": "travisblanchard@digigene.com", "phone": "+1 (846) 475-2118", "address": "406 Gotham Avenue, Spokane, Oregon, 3433", "about": "Sint duis ea aliquip deserunt officia deserunt aliqua proident cupidatat ipsum. Ad voluptate veniam aliquip cillum occaecat aute ut aliqua eu nulla irure. Ad eu mollit consequat esse ea magna esse sint officia est ut. Ut pariatur culpa nostrud dolore qui reprehenderit in velit eiusmod do incididunt dolor quis. Aliquip Lorem reprehenderit laboris velit aute amet id aliquip Lorem cupidatat.\r\n", "registered": "2016-12-16T11:09:28 -01:00", "latitude": 34.207216, "longitude": -166.363652, "tags": [ "aliquip", "velit", "et", "excepteur", "quis", "ex", "dolor", "nisi", "eu", "pariatur" ], "friends": [ { "id": 0, "name": "Leola Mullen" }, { "id": 1, "name": "Jannie Howe" }, { "id": 2, "name": "Chrystal Decker" }, { "id": 3, "name": "Green Flowers" }, { "id": 4, "name": "Gregory Britt" } ], "greeting": "Hello, Travis Blanchard! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482637091e10da54df9b", "index": 107, "guid": "0b79dbbe-0ef0-4190-b353-de7486e429e9", "isActive": true, "balance": "$3,807.36", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "blue", "name": "Caroline Slater", "gender": "female", "company": "PLASMOSIS", "email": "carolineslater@plasmosis.com", "phone": "+1 (813) 577-2546", "address": "741 Balfour Place, Hobucken, Tennessee, 2413", "about": "Aliqua ut elit commodo veniam amet dolor quis fugiat. Ea ut enim mollit est quis. Nostrud do minim sunt commodo est mollit ipsum. Amet mollit est proident eiusmod velit commodo qui velit commodo.\r\n", "registered": "2017-12-12T11:16:32 -01:00", "latitude": 31.633625, "longitude": 53.422385, "tags": [ "eu", "ipsum", "ex", "cillum", "ipsum", "qui", "velit", "officia", "minim", "magna" ], "friends": [ { "id": 0, "name": "Kim Whitaker" }, { "id": 1, "name": "Espinoza Weeks" }, { "id": 2, "name": "Jennie Faulkner" }, { "id": 3, "name": "Brianna Morales" }, { "id": 4, "name": "Meredith Schmidt" } ], "greeting": "Hello, Caroline Slater! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261f8f63ca58d814c0", "index": 108, "guid": "49d1ac6d-e516-48dd-aa37-8ee3e83e2c8f", "isActive": false, "balance": "$2,322.79", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "blue", "name": "Clara Mathews", "gender": "female", "company": "BIOLIVE", "email": "claramathews@biolive.com", "phone": "+1 (935) 594-2538", "address": "537 Beard Street, Lewis, Nevada, 754", "about": "Qui labore incididunt aute velit tempor excepteur qui qui laborum consectetur. Occaecat aliquip adipisicing nisi magna. Est ipsum incididunt in dolore Lorem incididunt excepteur labore occaecat enim. Cupidatat commodo ullamco non Lorem et elit nostrud sint pariatur pariatur. Eu occaecat duis elit consequat cupidatat consequat veniam fugiat incididunt dolor excepteur dolore. Qui anim enim ullamco eiusmod quis laboris voluptate cupidatat nisi ullamco deserunt anim voluptate nostrud. Dolore ut eu incididunt cupidatat officia ullamco commodo consectetur laboris dolor Lorem incididunt elit quis.\r\n", "registered": "2015-04-06T05:58:15 -02:00", "latitude": 41.637845, "longitude": 64.418302, "tags": [ "id", "veniam", "dolor", "labore", "veniam", "et", "duis", "do", "et", "in" ], "friends": [ { "id": 0, "name": "Earlene Hodge" }, { "id": 1, "name": "Dixon Sheppard" }, { "id": 2, "name": "Price Alvarado" }, { "id": 3, "name": "Ruthie Mckay" }, { "id": 4, "name": "Greta Bradshaw" } ], "greeting": "Hello, Clara Mathews! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482647202d6ae64888cd", "index": 109, "guid": "13afc33e-0bf6-465b-96f4-860f7aab2713", "isActive": true, "balance": "$1,593.43", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Cleveland Owens", "gender": "male", "company": "COMCUBINE", "email": "clevelandowens@comcubine.com", "phone": "+1 (968) 538-2742", "address": "854 Butler Place, Innsbrook, Alaska, 3003", "about": "Ea do deserunt velit eiusmod. Anim ut fugiat ullamco nisi excepteur veniam labore aute exercitation sint ea. Ut aliquip laboris aute ea ad est labore non dolor dolor exercitation amet sit. Veniam velit dolore occaecat aliquip elit irure labore nisi ad ut voluptate qui eiusmod ipsum.\r\n", "registered": "2017-11-09T07:47:59 -01:00", "latitude": 83.911441, "longitude": 16.727266, "tags": [ "culpa", "velit", "qui", "fugiat", "adipisicing", "do", "labore", "dolore", "ipsum", "amet" ], "friends": [ { "id": 0, "name": "Elliott Woodard" }, { "id": 1, "name": "Tamra Miranda" }, { "id": 2, "name": "Romero Hamilton" }, { "id": 3, "name": "Lula Matthews" }, { "id": 4, "name": "Gracie Cohen" } ], "greeting": "Hello, Cleveland Owens! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482699e3f5a7aadcfa13", "index": 110, "guid": "d338ee9f-12e1-4da1-9d60-c48a212963cf", "isActive": true, "balance": "$1,938.13", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Fry Trujillo", "gender": "male", "company": "ACCIDENCY", "email": "frytrujillo@accidency.com", "phone": "+1 (924) 471-3820", "address": "523 Everett Avenue, Holcombe, Illinois, 1325", "about": "Mollit exercitation ut sint dolor in velit laborum Lorem eiusmod laborum officia duis nostrud. Aliqua consectetur Lorem nulla minim ullamco et eiusmod Lorem irure tempor non. Magna consequat in labore ullamco ex et laboris sit ad cupidatat. Et eu aliqua quis deserunt laborum non officia eiusmod excepteur do quis occaecat deserunt commodo. Culpa id mollit mollit deserunt laborum deserunt in nostrud.\r\n", "registered": "2015-06-19T03:04:03 -02:00", "latitude": 11.061865, "longitude": -163.631912, "tags": [ "consectetur", "laborum", "ipsum", "et", "velit", "est", "incididunt", "irure", "consequat", "ullamco" ], "friends": [ { "id": 0, "name": "Castillo Calhoun" }, { "id": 1, "name": "Colleen Duffy" }, { "id": 2, "name": "Wilkins Mcfarland" }, { "id": 3, "name": "Lessie Strong" }, { "id": 4, "name": "Velez May" } ], "greeting": "Hello, Fry Trujillo! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261a5fa299e7a22bdf", "index": 111, "guid": "1862c5ec-0305-4a3c-accb-960caef7c4d5", "isActive": false, "balance": "$1,697.29", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Jill Lynch", "gender": "female", "company": "BIZMATIC", "email": "jilllynch@bizmatic.com", "phone": "+1 (915) 431-2381", "address": "130 Ocean Parkway, Cressey, Oklahoma, 3382", "about": "In excepteur eu do eu labore officia culpa excepteur. Est id magna velit nisi sit deserunt tempor. Occaecat minim ad aute sunt elit eu esse eiusmod labore ut amet.\r\n", "registered": "2017-10-12T03:54:52 -02:00", "latitude": 26.390924, "longitude": -67.061381, "tags": [ "ea", "enim", "tempor", "cupidatat", "veniam", "enim", "laborum", "commodo", "nisi", "nostrud" ], "friends": [ { "id": 0, "name": "Virginia Reese" }, { "id": 1, "name": "Carol Forbes" }, { "id": 2, "name": "Madeline Summers" }, { "id": 3, "name": "Mccray Lloyd" }, { "id": 4, "name": "Neal Potter" } ], "greeting": "Hello, Jill Lynch! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48265cb4a1f28d89c61d", "index": 112, "guid": "ed15c532-8ef1-45c4-81bc-c08902b5ca82", "isActive": true, "balance": "$3,031.96", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Marissa Aguirre", "gender": "female", "company": "ROOFORIA", "email": "marissaaguirre@rooforia.com", "phone": "+1 (917) 439-2673", "address": "224 Louise Terrace, Muse, Delaware, 6879", "about": "Eiusmod dolor exercitation anim nulla duis consequat id ad consectetur esse et Lorem cupidatat qui. Commodo magna cupidatat esse elit anim. Commodo non consequat aliquip sunt aliquip cupidatat mollit quis reprehenderit voluptate eu esse exercitation anim. Lorem non sit cillum occaecat id sint ut magna labore esse. Velit consectetur in est duis veniam dolore consectetur commodo consequat. Ea officia voluptate deserunt ea. Do adipisicing culpa consectetur officia do mollit mollit et est commodo ea.\r\n", "registered": "2015-07-14T06:42:15 -02:00", "latitude": 64.042863, "longitude": -91.705037, "tags": [ "adipisicing", "commodo", "in", "amet", "Lorem", "ex", "fugiat", "enim", "eiusmod", "excepteur" ], "friends": [ { "id": 0, "name": "Wilkinson Gallagher" }, { "id": 1, "name": "Garrett Rivers" }, { "id": 2, "name": "Watts Nash" }, { "id": 3, "name": "Nash Hahn" }, { "id": 4, "name": "Rosetta Kramer" } ], "greeting": "Hello, Marissa Aguirre! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482659cda155ea827f5e", "index": 113, "guid": "fc50af33-7141-4446-983c-4ea6842f80d1", "isActive": false, "balance": "$2,738.64", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Geneva Estes", "gender": "female", "company": "HOMELUX", "email": "genevaestes@homelux.com", "phone": "+1 (890) 553-3691", "address": "311 Neptune Avenue, Healy, Federated States Of Micronesia, 6632", "about": "Sunt deserunt mollit eiusmod in reprehenderit consequat deserunt ut proident ex culpa aute. Et amet et cillum fugiat. Ex non consectetur esse aliquip aliquip occaecat. Nisi nostrud sint quis aute adipisicing ea cillum velit sint consequat id duis excepteur. Fugiat duis id velit sunt nostrud magna. Fugiat laboris reprehenderit aliquip cupidatat irure eu velit eiusmod ex.\r\n", "registered": "2017-03-19T01:52:53 -01:00", "latitude": -9.614343, "longitude": -63.688547, "tags": [ "quis", "veniam", "laborum", "labore", "enim", "qui", "culpa", "fugiat", "aute", "mollit" ], "friends": [ { "id": 0, "name": "Mcneil Hensley" }, { "id": 1, "name": "Mccarty Barrera" }, { "id": 2, "name": "Mercado Franklin" }, { "id": 3, "name": "Cooper Tran" }, { "id": 4, "name": "Molina Gonzalez" } ], "greeting": "Hello, Geneva Estes! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48263fda8084dea31f28", "index": 114, "guid": "0d12a4ca-7553-4ecc-88f9-b20c5937819a", "isActive": false, "balance": "$2,016.23", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "blue", "name": "Hartman Knowles", "gender": "male", "company": "ACCUPRINT", "email": "hartmanknowles@accuprint.com", "phone": "+1 (893) 417-3231", "address": "158 Bragg Court, Slovan, Florida, 9784", "about": "Consequat ullamco aute mollit mollit ea laborum aliqua id non aute amet in. Reprehenderit deserunt ad consequat et duis ex ea sit ut. In in in dolor officia enim. Quis laborum do fugiat mollit elit officia Lorem ullamco incididunt fugiat.\r\n", "registered": "2017-01-02T10:32:21 -01:00", "latitude": 75.116179, "longitude": -162.157781, "tags": [ "incididunt", "occaecat", "tempor", "officia", "adipisicing", "eu", "eiusmod", "laboris", "ad", "sit" ], "friends": [ { "id": 0, "name": "Cathleen Cannon" }, { "id": 1, "name": "Katelyn Sampson" }, { "id": 2, "name": "Rene Case" }, { "id": 3, "name": "Baldwin Dean" }, { "id": 4, "name": "Deloris Bond" } ], "greeting": "Hello, Hartman Knowles! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48268646d2eee26c0849", "index": 115, "guid": "3d0af9c1-a1e7-465f-8844-60093179ad66", "isActive": false, "balance": "$1,440.49", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "green", "name": "Browning Keith", "gender": "male", "company": "ZANYMAX", "email": "browningkeith@zanymax.com", "phone": "+1 (850) 525-3945", "address": "513 Cypress Avenue, Succasunna, Massachusetts, 334", "about": "Consequat commodo pariatur deserunt ad nulla anim pariatur laborum. Ex voluptate exercitation culpa Lorem commodo pariatur consectetur anim ullamco. Exercitation amet ullamco sunt ullamco ut. Quis fugiat cupidatat adipisicing nostrud id consequat ullamco cupidatat.\r\n", "registered": "2016-09-25T03:39:21 -02:00", "latitude": -34.152879, "longitude": -64.963331, "tags": [ "do", "occaecat", "sit", "esse", "adipisicing", "fugiat", "sit", "ex", "anim", "labore" ], "friends": [ { "id": 0, "name": "Blackwell Vaughan" }, { "id": 1, "name": "Grant Ryan" }, { "id": 2, "name": "Aimee Kelley" }, { "id": 3, "name": "Faulkner Swanson" }, { "id": 4, "name": "Edwina Roth" } ], "greeting": "Hello, Browning Keith! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826f6a7bcd58ecb15b3", "index": 116, "guid": "961c648c-c256-4bfc-9b34-b46f5b15db6e", "isActive": false, "balance": "$3,810.67", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "blue", "name": "Manuela Powers", "gender": "female", "company": "ZOUNDS", "email": "manuelapowers@zounds.com", "phone": "+1 (969) 486-3115", "address": "921 Kosciusko Street, Albrightsville, Mississippi, 4218", "about": "Proident aliquip fugiat eu tempor sunt veniam proident. Nostrud consequat nisi quis esse enim nisi id mollit eiusmod quis ea. Reprehenderit id eiusmod minim ut exercitation eiusmod. Adipisicing velit anim fugiat non elit nulla pariatur. Cillum enim fugiat fugiat consectetur veniam occaecat ipsum incididunt esse. Ullamco eiusmod mollit sit nisi Lorem occaecat enim nostrud.\r\n", "registered": "2014-07-30T04:39:57 -02:00", "latitude": -43.08205, "longitude": -119.062725, "tags": [ "exercitation", "esse", "qui", "ipsum", "in", "labore", "dolor", "nulla", "occaecat", "magna" ], "friends": [ { "id": 0, "name": "Puckett Gould" }, { "id": 1, "name": "Bowers Dotson" }, { "id": 2, "name": "Gladys Rice" }, { "id": 3, "name": "Avis Clark" }, { "id": 4, "name": "Welch Stein" } ], "greeting": "Hello, Manuela Powers! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48269c9a2ee3a666a037", "index": 117, "guid": "c470db3f-d779-40f7-806b-a1f7a10df1b4", "isActive": true, "balance": "$2,101.95", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Lynda Mooney", "gender": "female", "company": "STUCCO", "email": "lyndamooney@stucco.com", "phone": "+1 (927) 586-2008", "address": "825 Harrison Avenue, Duryea, Guam, 4278", "about": "Dolore magna Lorem velit ex minim aliquip eiusmod quis. Labore voluptate aute ea incididunt labore irure aliqua consequat ipsum excepteur labore. Ullamco est laborum do magna.\r\n", "registered": "2015-10-08T06:31:04 -02:00", "latitude": -81.730724, "longitude": -11.293376, "tags": [ "veniam", "ex", "excepteur", "exercitation", "ipsum", "aliqua", "incididunt", "pariatur", "cillum", "culpa" ], "friends": [ { "id": 0, "name": "Copeland Fisher" }, { "id": 1, "name": "Nanette Hester" }, { "id": 2, "name": "Macdonald Potts" }, { "id": 3, "name": "Duke Hardy" }, { "id": 4, "name": "Suzanne Ellis" } ], "greeting": "Hello, Lynda Mooney! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826d1ee9fde11fa6d33", "index": 118, "guid": "80c3e187-b31b-4d62-9e81-0462fcaae1c6", "isActive": true, "balance": "$3,550.47", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Kaitlin Wilkerson", "gender": "female", "company": "RODEMCO", "email": "kaitlinwilkerson@rodemco.com", "phone": "+1 (861) 501-3828", "address": "965 Lake Street, Bluetown, Louisiana, 7910", "about": "Et sint minim est in deserunt. Veniam quis do exercitation dolore ad occaecat nulla ipsum. Dolor consequat aliqua culpa laboris anim officia voluptate et exercitation sint proident et elit eiusmod. Cupidatat exercitation sunt eu reprehenderit nulla ipsum aute elit nisi labore occaecat et esse. Consectetur aute adipisicing ad reprehenderit magna reprehenderit tempor sit nisi. Aliquip eu amet enim nulla est amet.\r\n", "registered": "2014-12-17T06:37:45 -01:00", "latitude": -8.701103, "longitude": 80.654905, "tags": [ "incididunt", "sit", "adipisicing", "duis", "incididunt", "officia", "ullamco", "officia", "consequat", "quis" ], "friends": [ { "id": 0, "name": "Lowe Meyer" }, { "id": 1, "name": "Freeman Mcfadden" }, { "id": 2, "name": "Felecia Garrett" }, { "id": 3, "name": "Weber Erickson" }, { "id": 4, "name": "Dotson Small" } ], "greeting": "Hello, Kaitlin Wilkerson! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48269bae3c15258373d4", "index": 119, "guid": "0575fbe6-9fe0-4921-9786-2ca5be31947b", "isActive": false, "balance": "$3,785.08", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "green", "name": "Bright Fitzgerald", "gender": "male", "company": "FUTURIZE", "email": "brightfitzgerald@futurize.com", "phone": "+1 (885) 587-2862", "address": "513 Imlay Street, Bartonsville, South Dakota, 4450", "about": "Cillum in non laboris nulla cillum elit enim elit tempor est sit qui ipsum. Ut enim ea adipisicing incididunt exercitation enim nostrud nostrud. Consequat ad in deserunt aliquip irure duis eu sint mollit anim. Cupidatat voluptate magna reprehenderit non. Deserunt consectetur aliquip ex culpa id esse elit consequat Lorem laborum amet amet aute. Voluptate irure pariatur non dolor.\r\n", "registered": "2014-12-31T02:35:41 -01:00", "latitude": -76.356582, "longitude": -94.050806, "tags": [ "dolore", "sunt", "anim", "sit", "non", "exercitation", "consectetur", "eiusmod", "ex", "proident" ], "friends": [ { "id": 0, "name": "Terry Hodges" }, { "id": 1, "name": "Chandler Lara" }, { "id": 2, "name": "Terrie Blankenship" }, { "id": 3, "name": "Valarie Church" }, { "id": 4, "name": "Lindsay Moses" } ], "greeting": "Hello, Bright Fitzgerald! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c5be3f4e60ab116b", "index": 120, "guid": "5f469bbc-3ee7-47fb-bfca-133fb2e1c814", "isActive": false, "balance": "$3,389.30", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "brown", "name": "Elise Benjamin", "gender": "female", "company": "OCEANICA", "email": "elisebenjamin@oceanica.com", "phone": "+1 (861) 585-3087", "address": "282 Norfolk Street, Williamson, District Of Columbia, 5839", "about": "Eiusmod mollit id dolore pariatur minim. Sunt excepteur amet aliquip Lorem exercitation dolore deserunt qui consequat esse ipsum anim. Sint amet quis fugiat cillum aute excepteur Lorem laboris consectetur ad fugiat enim et. Nostrud velit magna incididunt commodo esse laborum consequat.\r\n", "registered": "2015-01-07T09:24:00 -01:00", "latitude": -69.824704, "longitude": 18.825892, "tags": [ "aliquip", "laboris", "nulla", "occaecat", "magna", "in", "mollit", "duis", "minim", "commodo" ], "friends": [ { "id": 0, "name": "Wilder Mcintosh" }, { "id": 1, "name": "Rasmussen Townsend" }, { "id": 2, "name": "Virgie Chen" }, { "id": 3, "name": "Hunter Freeman" }, { "id": 4, "name": "Rose Willis" } ], "greeting": "Hello, Elise Benjamin! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826a3581b43300bc608", "index": 121, "guid": "17bddc02-8afe-4237-aed2-a5a600e10768", "isActive": true, "balance": "$2,744.50", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Merritt Baldwin", "gender": "male", "company": "ZOLAREX", "email": "merrittbaldwin@zolarex.com", "phone": "+1 (913) 408-2781", "address": "430 Centre Street, Dunbar, Puerto Rico, 6947", "about": "Ex in sunt duis veniam ullamco anim quis occaecat mollit ullamco sit duis. Velit cillum aliqua do ullamco adipisicing incididunt proident occaecat anim velit commodo laboris. Reprehenderit dolore velit sit eu consectetur proident nisi quis minim aliqua eu laborum irure. Irure sunt ad irure veniam exercitation in commodo amet cupidatat.\r\n", "registered": "2016-01-28T09:18:30 -01:00", "latitude": 27.881298, "longitude": -117.861245, "tags": [ "mollit", "cupidatat", "eiusmod", "fugiat", "enim", "in", "et", "minim", "officia", "ex" ], "friends": [ { "id": 0, "name": "Deleon Blackwell" }, { "id": 1, "name": "Ayala Fletcher" }, { "id": 2, "name": "Tammie Camacho" }, { "id": 3, "name": "Hattie Curtis" }, { "id": 4, "name": "Manning Mckinney" } ], "greeting": "Hello, Merritt Baldwin! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48269adba9bdd77bdbac", "index": 122, "guid": "bcfc4303-c30e-4e96-a720-9ab336d0a04d", "isActive": true, "balance": "$1,124.92", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "green", "name": "Jolene Mays", "gender": "female", "company": "HAWKSTER", "email": "jolenemays@hawkster.com", "phone": "+1 (878) 515-2277", "address": "789 Martense Street, Hickory, Maine, 3983", "about": "Officia aute eiusmod reprehenderit mollit elit ipsum nulla proident qui irure cupidatat fugiat. Laboris deserunt anim adipisicing do do laborum laboris est aliquip sit aute excepteur est voluptate. Aute sunt id et aute consequat commodo dolore consectetur ipsum ea irure velit quis.\r\n", "registered": "2014-10-09T12:14:56 -02:00", "latitude": 8.021589, "longitude": -87.230973, "tags": [ "mollit", "incididunt", "ad", "eu", "ullamco", "ex", "reprehenderit", "laboris", "consectetur", "ex" ], "friends": [ { "id": 0, "name": "Marisol Baxter" }, { "id": 1, "name": "Avila Blevins" }, { "id": 2, "name": "King Daniel" }, { "id": 3, "name": "Amber Battle" }, { "id": 4, "name": "Maureen Ellison" } ], "greeting": "Hello, Jolene Mays! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48266fd788fcab1c5609", "index": 123, "guid": "f7184c75-3d83-4bd6-8421-e1be8d3bbdb6", "isActive": false, "balance": "$2,444.95", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Blackburn Bright", "gender": "male", "company": "ORBEAN", "email": "blackburnbright@orbean.com", "phone": "+1 (954) 482-2423", "address": "698 Horace Court, Freelandville, New Jersey, 4351", "about": "Mollit occaecat fugiat amet proident adipisicing excepteur Lorem id Lorem irure anim voluptate. Et duis velit anim do ex ex. Ad est culpa commodo Lorem tempor pariatur est excepteur eiusmod aliquip officia pariatur dolor esse.\r\n", "registered": "2014-04-17T10:05:02 -02:00", "latitude": -42.845601, "longitude": 57.180685, "tags": [ "in", "ipsum", "commodo", "occaecat", "proident", "et", "qui", "id", "pariatur", "officia" ], "friends": [ { "id": 0, "name": "Shelia Valentine" }, { "id": 1, "name": "Juanita Levine" }, { "id": 2, "name": "Ramos Hill" }, { "id": 3, "name": "Teri Gentry" }, { "id": 4, "name": "Reilly Anderson" } ], "greeting": "Hello, Blackburn Bright! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826f5595b31983fef1b", "index": 124, "guid": "c10866c6-b35f-4f99-9df9-07e85b64063d", "isActive": false, "balance": "$2,614.36", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "blue", "name": "Annmarie Horne", "gender": "female", "company": "WATERBABY", "email": "annmariehorne@waterbaby.com", "phone": "+1 (896) 403-3565", "address": "914 Lefferts Place, Mulino, Michigan, 9386", "about": "Commodo esse est non cillum veniam adipisicing. Mollit consectetur veniam sit labore sunt amet pariatur velit exercitation qui id Lorem ullamco quis. Adipisicing enim veniam amet non dolor qui sint reprehenderit velit ex. Eu deserunt deserunt reprehenderit cillum nulla dolore duis dolore non sit proident et excepteur.\r\n", "registered": "2016-04-01T02:39:39 -02:00", "latitude": -6.864872, "longitude": -140.223905, "tags": [ "aute", "est", "cupidatat", "duis", "nulla", "irure", "duis", "deserunt", "irure", "minim" ], "friends": [ { "id": 0, "name": "Vonda Edwards" }, { "id": 1, "name": "Nieves Macdonald" }, { "id": 2, "name": "Meghan Aguilar" }, { "id": 3, "name": "Olivia Rosales" }, { "id": 4, "name": "Helene Saunders" } ], "greeting": "Hello, Annmarie Horne! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48262e60206420d0cfd1", "index": 125, "guid": "713037f2-c39e-4e32-bee8-4890d2bd3a7f", "isActive": true, "balance": "$2,398.98", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Augusta Gaines", "gender": "female", "company": "EXOTERIC", "email": "augustagaines@exoteric.com", "phone": "+1 (850) 581-2642", "address": "114 Moore Street, Lavalette, Rhode Island, 1057", "about": "Incididunt cillum qui excepteur eiusmod exercitation ullamco duis anim nulla. Deserunt sint amet exercitation voluptate consectetur nostrud. Mollit ea adipisicing aute officia. Tempor do minim duis sunt laborum esse sunt sint aute. Deserunt anim ipsum proident pariatur. Enim labore sint labore Lorem anim labore. Incididunt magna esse duis aute.\r\n", "registered": "2016-07-01T12:26:53 -02:00", "latitude": 45.299501, "longitude": 72.217358, "tags": [ "occaecat", "anim", "mollit", "quis", "consectetur", "irure", "ipsum", "elit", "exercitation", "exercitation" ], "friends": [ { "id": 0, "name": "Crane Richardson" }, { "id": 1, "name": "Darla Mueller" }, { "id": 2, "name": "Sandy Chavez" }, { "id": 3, "name": "Stokes Pruitt" }, { "id": 4, "name": "Campos Monroe" } ], "greeting": "Hello, Augusta Gaines! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482601605a0d8a353876", "index": 126, "guid": "0a094f86-4854-4929-acff-4434fd93a4bb", "isActive": true, "balance": "$2,048.80", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Lori Rodgers", "gender": "female", "company": "FURNITECH", "email": "lorirodgers@furnitech.com", "phone": "+1 (882) 410-2169", "address": "479 Richards Street, Concho, Kansas, 7744", "about": "Sit eiusmod occaecat enim tempor pariatur proident quis aute sunt cillum magna ea. Tempor culpa duis veniam mollit occaecat consequat proident minim magna. Aliqua aute elit aute officia dolore. Cupidatat ad dolore exercitation occaecat ad incididunt excepteur. Eiusmod nostrud sit officia eiusmod occaecat proident excepteur velit veniam. Sint duis irure labore nulla sunt eu exercitation ea commodo non et laborum elit sit. Pariatur deserunt sit eu elit ullamco tempor fugiat mollit minim adipisicing culpa laboris officia.\r\n", "registered": "2017-10-28T11:09:17 -02:00", "latitude": 82.916634, "longitude": 92.809937, "tags": [ "magna", "occaecat", "enim", "Lorem", "minim", "irure", "fugiat", "proident", "occaecat", "eu" ], "friends": [ { "id": 0, "name": "Cristina Solomon" }, { "id": 1, "name": "Jacobs Herrera" }, { "id": 2, "name": "Bobbie Valencia" }, { "id": 3, "name": "Sherry Booth" }, { "id": 4, "name": "Anastasia Blackburn" } ], "greeting": "Hello, Lori Rodgers! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826b32bc006364394c2", "index": 127, "guid": "87743d3f-6e56-4429-a8d9-88d160036127", "isActive": false, "balance": "$2,430.57", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Adams House", "gender": "male", "company": "MICROLUXE", "email": "adamshouse@microluxe.com", "phone": "+1 (976) 411-3309", "address": "674 Pacific Street, Hampstead, West Virginia, 9314", "about": "Elit quis non veniam eiusmod id nulla proident anim tempor. Do dolore nostrud nulla aute. Veniam amet cillum qui irure elit tempor laborum cupidatat officia tempor sint incididunt. Cupidatat ullamco consectetur Lorem minim labore elit pariatur nostrud esse veniam est culpa. Eiusmod proident ex eiusmod elit culpa tempor elit exercitation id laborum elit do cillum qui.\r\n", "registered": "2015-06-02T07:38:10 -02:00", "latitude": 59.721475, "longitude": -174.140526, "tags": [ "aliquip", "aliqua", "velit", "ex", "non", "exercitation", "occaecat", "pariatur", "occaecat", "et" ], "friends": [ { "id": 0, "name": "Bender Kirkland" }, { "id": 1, "name": "Kathy Ford" }, { "id": 2, "name": "Carey Justice" }, { "id": 3, "name": "Elizabeth Watkins" }, { "id": 4, "name": "Luella Valenzuela" } ], "greeting": "Hello, Adams House! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261f47524f5b1c7564", "index": 128, "guid": "ae1ae6cb-d827-4272-a9ad-db6c5a1934af", "isActive": true, "balance": "$3,501.77", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Fox Dennis", "gender": "male", "company": "NORSUL", "email": "foxdennis@norsul.com", "phone": "+1 (866) 479-3017", "address": "698 Main Street, Edgewater, American Samoa, 8973", "about": "Laboris aliqua labore esse officia Lorem. Ad occaecat ullamco est quis cillum Lorem ipsum eu laboris velit enim aute. Velit qui irure veniam consectetur amet do pariatur culpa.\r\n", "registered": "2014-04-03T11:34:29 -02:00", "latitude": -22.147719, "longitude": 118.125107, "tags": [ "est", "qui", "dolore", "labore", "labore", "laborum", "ullamco", "ea", "ipsum", "incididunt" ], "friends": [ { "id": 0, "name": "Britt Alexander" }, { "id": 1, "name": "Rochelle Hutchinson" }, { "id": 2, "name": "Hester Simmons" }, { "id": 3, "name": "Hewitt Obrien" }, { "id": 4, "name": "Carole Contreras" } ], "greeting": "Hello, Fox Dennis! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482688d9e132a12bd703", "index": 129, "guid": "e514497a-c0dd-4cbd-bc81-989f6c3aec0b", "isActive": true, "balance": "$1,005.02", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "blue", "name": "Sallie Lambert", "gender": "female", "company": "ZENSUS", "email": "sallielambert@zensus.com", "phone": "+1 (993) 565-2713", "address": "312 Bowne Street, Fowlerville, Maryland, 3364", "about": "Dolor ut pariatur pariatur culpa et laborum. Mollit mollit eu fugiat ut ullamco Lorem elit pariatur adipisicing ipsum deserunt tempor officia. Ad officia voluptate consectetur ut aliquip mollit amet in culpa. Consequat nisi esse voluptate et ipsum aliqua ea. Tempor consectetur mollit adipisicing commodo proident cupidatat adipisicing magna amet. Elit anim ipsum ex exercitation mollit in nisi laboris ullamco nulla non. Ipsum adipisicing labore esse anim cupidatat.\r\n", "registered": "2015-06-25T09:48:49 -02:00", "latitude": 6.782475, "longitude": -118.756672, "tags": [ "nulla", "consectetur", "cillum", "deserunt", "officia", "culpa", "non", "ad", "cupidatat", "irure" ], "friends": [ { "id": 0, "name": "Mavis Lynn" }, { "id": 1, "name": "Lea Mcintyre" }, { "id": 2, "name": "Leonor Sherman" }, { "id": 3, "name": "Buchanan Phillips" }, { "id": 4, "name": "Morrison Boyer" } ], "greeting": "Hello, Sallie Lambert! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826dca9a4487045d45b", "index": 130, "guid": "0103e334-1e7f-4212-b74e-3cfd1ffb01a1", "isActive": true, "balance": "$2,528.71", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Burris Burke", "gender": "male", "company": "ROBOID", "email": "burrisburke@roboid.com", "phone": "+1 (990) 517-3549", "address": "878 Wallabout Street, Choctaw, California, 4827", "about": "Laborum aute in veniam mollit id. Nostrud velit ut amet labore fugiat et officia anim aliquip proident dolor. Lorem elit amet tempor velit dolore ut duis dolor laborum commodo nostrud non exercitation. Occaecat enim laborum laborum occaecat minim deserunt incididunt. Voluptate esse in nisi do laboris veniam duis amet laboris anim. Eiusmod Lorem aute nulla amet incididunt consectetur tempor.\r\n", "registered": "2015-07-27T10:43:07 -02:00", "latitude": -65.858154, "longitude": 112.537462, "tags": [ "excepteur", "Lorem", "occaecat", "minim", "ea", "reprehenderit", "pariatur", "occaecat", "exercitation", "eu" ], "friends": [ { "id": 0, "name": "Susie Daniels" }, { "id": 1, "name": "Mathis Graham" }, { "id": 2, "name": "Brennan Wright" }, { "id": 3, "name": "Angie Holland" }, { "id": 4, "name": "Parsons Campbell" } ], "greeting": "Hello, Burris Burke! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826182e5e1791ceedfb", "index": 131, "guid": "0db33d82-d6a3-49eb-920e-3f018c7dfdac", "isActive": false, "balance": "$3,923.99", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "blue", "name": "Arline Gilbert", "gender": "female", "company": "EARTHPURE", "email": "arlinegilbert@earthpure.com", "phone": "+1 (802) 420-2259", "address": "907 Sackman Street, Wattsville, Utah, 7892", "about": "Sunt magna laboris tempor cupidatat consectetur magna culpa Lorem sit pariatur id. Occaecat est aute aute voluptate ad qui anim incididunt. Minim proident nostrud culpa adipisicing sit Lorem nostrud. Duis dolore commodo in ullamco consectetur eu. Ipsum incididunt ex ad aute est minim culpa incididunt cupidatat nostrud nisi consectetur eu. Fugiat adipisicing elit non culpa enim eiusmod do nostrud pariatur velit cillum tempor sunt.\r\n", "registered": "2017-02-10T12:59:44 -01:00", "latitude": 58.66858, "longitude": 102.604312, "tags": [ "nulla", "cillum", "est", "eu", "dolor", "est", "qui", "sunt", "qui", "proident" ], "friends": [ { "id": 0, "name": "Justice Bryan" }, { "id": 1, "name": "Joan Snow" }, { "id": 2, "name": "Roman Ewing" }, { "id": 3, "name": "Chen Pacheco" }, { "id": 4, "name": "Spears James" } ], "greeting": "Hello, Arline Gilbert! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48265a4a4c2650777894", "index": 132, "guid": "9b16193f-5cb1-4c62-b2de-563eb2f1545c", "isActive": false, "balance": "$1,779.16", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Randi Cooper", "gender": "female", "company": "STEELTAB", "email": "randicooper@steeltab.com", "phone": "+1 (942) 600-3912", "address": "422 Perry Place, Cornucopia, Iowa, 2556", "about": "Mollit eiusmod dolore dolore irure ut aliquip Lorem. Quis nisi eiusmod ex sint aliquip nulla. Aliquip excepteur ut occaecat nisi do eu adipisicing nisi reprehenderit excepteur cupidatat laborum laboris. Ipsum ad velit nostrud ullamco consectetur dolor ipsum eiusmod pariatur veniam sit occaecat ipsum. Commodo velit ad amet elit aute anim.\r\n", "registered": "2015-05-30T04:51:47 -02:00", "latitude": 43.266317, "longitude": 24.597115, "tags": [ "ullamco", "ad", "qui", "qui", "reprehenderit", "adipisicing", "sit", "occaecat", "in", "fugiat" ], "friends": [ { "id": 0, "name": "Bertha Peters" }, { "id": 1, "name": "Maricela Drake" }, { "id": 2, "name": "Hogan Salinas" }, { "id": 3, "name": "Gibbs Carroll" }, { "id": 4, "name": "Haley Bradley" } ], "greeting": "Hello, Randi Cooper! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826681c71daf6b8a565", "index": 133, "guid": "7f66eeac-bd47-4398-aeb6-8732b5738f2b", "isActive": false, "balance": "$1,182.14", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "blue", "name": "Norton Castaneda", "gender": "male", "company": "ISOSWITCH", "email": "nortoncastaneda@isoswitch.com", "phone": "+1 (901) 483-3188", "address": "784 Danforth Street, Saddlebrooke, North Dakota, 7529", "about": "Qui mollit ipsum proident veniam adipisicing id. Laboris deserunt voluptate deserunt laborum quis. Dolore cupidatat tempor dolor aute ipsum esse. In amet sint voluptate incididunt laborum magna voluptate cupidatat.\r\n", "registered": "2016-06-24T06:07:29 -02:00", "latitude": -68.816413, "longitude": 64.898784, "tags": [ "officia", "in", "esse", "sit", "proident", "id", "nostrud", "labore", "duis", "anim" ], "friends": [ { "id": 0, "name": "Garza Morrison" }, { "id": 1, "name": "Wolf Pratt" }, { "id": 2, "name": "Cynthia Hammond" }, { "id": 3, "name": "Chapman Nixon" }, { "id": 4, "name": "Justine Maldonado" } ], "greeting": "Hello, Norton Castaneda! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48263fbdf16bbcd1f11f", "index": 134, "guid": "23617df9-befe-418f-bd79-0498576129eb", "isActive": false, "balance": "$3,469.13", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "brown", "name": "Clare Fleming", "gender": "female", "company": "ENERFORCE", "email": "clarefleming@enerforce.com", "phone": "+1 (948) 471-2485", "address": "516 Henry Street, Welch, Kentucky, 4195", "about": "Magna dolor id eu eu excepteur voluptate consectetur cupidatat eiusmod ut tempor id. Nulla sint ea reprehenderit sint anim enim excepteur minim occaecat. Non laboris non officia ad consequat eu sunt non velit adipisicing quis sint ut eu. Id sunt in ullamco non officia quis minim est consectetur et aliquip sit dolore incididunt. Sint duis ex sunt eiusmod.\r\n", "registered": "2014-09-26T12:27:50 -02:00", "latitude": 17.847025, "longitude": -36.55967, "tags": [ "dolore", "nulla", "incididunt", "cupidatat", "consectetur", "ea", "minim", "ad", "nulla", "commodo" ], "friends": [ { "id": 0, "name": "Yolanda Wheeler" }, { "id": 1, "name": "Doris Durham" }, { "id": 2, "name": "Gomez Frank" }, { "id": 3, "name": "Cara Wilkins" }, { "id": 4, "name": "Henderson Gibson" } ], "greeting": "Hello, Clare Fleming! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482619bce35fe28a9d79", "index": 135, "guid": "a1e8d7c4-b3de-45e9-839e-b45259f7c58d", "isActive": false, "balance": "$2,094.71", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "green", "name": "Jana Parsons", "gender": "female", "company": "GLUKGLUK", "email": "janaparsons@glukgluk.com", "phone": "+1 (890) 488-2281", "address": "924 Laurel Avenue, Hachita, Colorado, 1450", "about": "Anim elit nisi officia culpa labore commodo. Sint laborum voluptate eiusmod fugiat. Ad pariatur eiusmod tempor labore ullamco sunt culpa duis labore exercitation amet. Occaecat ad est anim elit aute laboris amet duis eu. In ipsum laboris laboris enim occaecat officia non culpa est nisi. Qui culpa quis amet nisi mollit dolore velit ex ipsum aute sit qui. Fugiat minim consequat nulla adipisicing.\r\n", "registered": "2015-06-19T03:13:20 -02:00", "latitude": -43.407641, "longitude": -13.753749, "tags": [ "cupidatat", "esse", "dolore", "ea", "sit", "mollit", "ipsum", "quis", "proident", "minim" ], "friends": [ { "id": 0, "name": "Gutierrez Tucker" }, { "id": 1, "name": "Jewell Tillman" }, { "id": 2, "name": "Hammond Henson" }, { "id": 3, "name": "Paula Lawrence" }, { "id": 4, "name": "Clarice Puckett" } ], "greeting": "Hello, Jana Parsons! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826c112b0938bf19a62", "index": 136, "guid": "c64f2c9f-4807-4f63-b8ce-844f341c3405", "isActive": true, "balance": "$1,328.71", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Phelps Bolton", "gender": "male", "company": "EXOPLODE", "email": "phelpsbolton@exoplode.com", "phone": "+1 (895) 557-3684", "address": "368 Foster Avenue, Cumberland, New Hampshire, 6254", "about": "Fugiat enim enim eiusmod fugiat amet. Anim culpa voluptate officia tempor ullamco dolore veniam. Eiusmod consequat anim irure elit fugiat sunt exercitation.\r\n", "registered": "2016-05-22T02:24:53 -02:00", "latitude": -5.845385, "longitude": 27.860263, "tags": [ "elit", "nulla", "duis", "nulla", "exercitation", "incididunt", "occaecat", "labore", "minim", "ullamco" ], "friends": [ { "id": 0, "name": "Eaton Nunez" }, { "id": 1, "name": "Shepard Hartman" }, { "id": 2, "name": "Roth Velazquez" }, { "id": 3, "name": "Cassie Petersen" }, { "id": 4, "name": "Carmen Fitzpatrick" } ], "greeting": "Hello, Phelps Bolton! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826ae7c86162db0eb7d", "index": 137, "guid": "c35c7043-c1d4-4f2b-9404-9ddb1a15b76a", "isActive": true, "balance": "$1,080.54", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Finch Johns", "gender": "male", "company": "FARMEX", "email": "finchjohns@farmex.com", "phone": "+1 (809) 566-3478", "address": "354 Canton Court, Westboro, Wisconsin, 6677", "about": "Sint ex nulla excepteur occaecat irure cupidatat aute officia et labore ea laborum consectetur. Id est qui mollit aliquip excepteur nisi. Cillum eu consectetur est irure esse tempor. Tempor laborum ea enim qui dolore. Pariatur in dolore elit laboris esse.\r\n", "registered": "2016-03-24T11:04:30 -01:00", "latitude": -65.065136, "longitude": -29.195485, "tags": [ "irure", "magna", "quis", "dolore", "Lorem", "minim", "eu", "deserunt", "sunt", "sunt" ], "friends": [ { "id": 0, "name": "Melisa Ware" }, { "id": 1, "name": "Candice David" }, { "id": 2, "name": "Morris Rios" }, { "id": 3, "name": "Christie Evans" }, { "id": 4, "name": "Florine Huber" } ], "greeting": "Hello, Finch Johns! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826170a417648b00961", "index": 138, "guid": "24870ad0-3008-4137-88df-5dbb1282e0dc", "isActive": false, "balance": "$1,639.50", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "blue", "name": "Cain Donaldson", "gender": "male", "company": "MEMORA", "email": "caindonaldson@memora.com", "phone": "+1 (989) 443-3650", "address": "938 Strauss Street, Chicopee, Idaho, 9886", "about": "Aute consequat nisi magna dolore mollit proident. In laborum et dolore elit sit ut sit laborum ut et duis deserunt. Pariatur commodo in cillum consequat dolor dolor excepteur ex laboris elit irure. Minim culpa nisi laboris est eiusmod excepteur consectetur officia commodo duis aute ipsum. Id culpa adipisicing est pariatur anim. Dolor labore velit nostrud exercitation. Adipisicing amet excepteur anim nisi sint.\r\n", "registered": "2017-01-11T11:14:25 -01:00", "latitude": -69.760282, "longitude": -140.63117, "tags": [ "et", "eiusmod", "cillum", "sint", "est", "magna", "labore", "enim", "esse", "commodo" ], "friends": [ { "id": 0, "name": "Witt Moore" }, { "id": 1, "name": "Cline Rollins" }, { "id": 2, "name": "Barbara Grimes" }, { "id": 3, "name": "Compton Stevens" }, { "id": 4, "name": "Berta Blake" } ], "greeting": "Hello, Cain Donaldson! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261d103b85376611d0", "index": 139, "guid": "05d87f22-ec2c-4a97-b5b5-2fa21f11ecd5", "isActive": true, "balance": "$3,901.64", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Leigh Cunningham", "gender": "female", "company": "SNACKTION", "email": "leighcunningham@snacktion.com", "phone": "+1 (852) 546-3350", "address": "459 Crosby Avenue, Condon, Georgia, 7424", "about": "Commodo elit occaecat velit tempor sunt consequat laborum veniam laboris excepteur et irure quis fugiat. Dolor labore dolor mollit non sint qui nulla fugiat cupidatat cupidatat veniam aute aliqua excepteur. Nulla adipisicing enim ut laborum sint velit qui eiusmod in labore. Nisi laboris eu aliqua officia qui id qui excepteur irure. Ad qui magna laboris ad aliqua sint mollit pariatur culpa adipisicing enim cupidatat ex cupidatat. Nulla adipisicing do fugiat deserunt.\r\n", "registered": "2017-02-27T10:59:00 -01:00", "latitude": -39.930071, "longitude": -129.932497, "tags": [ "do", "sunt", "exercitation", "aliquip", "magna", "veniam", "est", "occaecat", "occaecat", "cillum" ], "friends": [ { "id": 0, "name": "Rojas Gallegos" }, { "id": 1, "name": "Earnestine Zamora" }, { "id": 2, "name": "Melba Kerr" }, { "id": 3, "name": "Noel Hickman" }, { "id": 4, "name": "Goodman Johnston" } ], "greeting": "Hello, Leigh Cunningham! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826a089895c4b32d247", "index": 140, "guid": "8638fad0-4458-4383-a2d6-f00f020c6177", "isActive": false, "balance": "$3,462.10", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "green", "name": "Jan Delgado", "gender": "female", "company": "ZOGAK", "email": "jandelgado@zogak.com", "phone": "+1 (900) 543-3330", "address": "740 Elton Street, Clarktown, Virgin Islands, 1898", "about": "Veniam aute aute exercitation sunt est consequat magna ad ea sint adipisicing esse. Duis tempor aute officia qui ullamco quis occaecat consequat ea. Sint aute qui ea laboris non nulla elit dolor dolore do ipsum adipisicing irure amet. Ea deserunt consequat ex est veniam cupidatat sunt anim. Dolore adipisicing occaecat ex reprehenderit nostrud anim consectetur ullamco do ad nulla elit quis. Consectetur ullamco et exercitation dolor ipsum officia sint. Amet nulla ipsum laborum quis ipsum incididunt aute.\r\n", "registered": "2016-06-22T06:54:03 -02:00", "latitude": -66.872507, "longitude": -3.375644, "tags": [ "dolore", "ea", "amet", "occaecat", "aute", "consectetur", "nulla", "et", "qui", "in" ], "friends": [ { "id": 0, "name": "Marietta Dunlap" }, { "id": 1, "name": "Fanny Bush" }, { "id": 2, "name": "Minnie Rowland" }, { "id": 3, "name": "Alisa Walter" }, { "id": 4, "name": "Burt Dawson" } ], "greeting": "Hello, Jan Delgado! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482689314c3a1be8ff1e", "index": 141, "guid": "3ee51a0b-1244-4402-a590-507613d02060", "isActive": false, "balance": "$2,710.07", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Hollie Bass", "gender": "female", "company": "PEARLESEX", "email": "holliebass@pearlesex.com", "phone": "+1 (844) 571-3501", "address": "397 Stewart Street, Wadsworth, Minnesota, 6679", "about": "Reprehenderit aliqua amet eiusmod reprehenderit anim velit elit cupidatat magna minim. In esse proident reprehenderit velit duis non duis incididunt et in duis in. Excepteur mollit laboris nisi eu enim laboris aliquip dolor amet adipisicing esse ipsum Lorem. Aliqua et eiusmod exercitation pariatur dolor et consequat anim Lorem elit labore ex.\r\n", "registered": "2017-06-21T07:31:37 -02:00", "latitude": -77.643116, "longitude": -90.986506, "tags": [ "sit", "duis", "id", "sunt", "eiusmod", "aliqua", "est", "fugiat", "deserunt", "in" ], "friends": [ { "id": 0, "name": "Roslyn Brewer" }, { "id": 1, "name": "Lela Wallace" }, { "id": 2, "name": "Eileen Mcconnell" }, { "id": 3, "name": "Sykes Bates" }, { "id": 4, "name": "Turner Johnson" } ], "greeting": "Hello, Hollie Bass! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482666b85a174e205431", "index": 142, "guid": "db7a85c8-7584-4802-8d3a-50b359e1e59e", "isActive": true, "balance": "$1,560.60", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Meyer Acevedo", "gender": "male", "company": "ZAYA", "email": "meyeracevedo@zaya.com", "phone": "+1 (800) 413-2686", "address": "968 Irvington Place, Masthope, South Carolina, 7454", "about": "Aliqua occaecat dolor officia cupidatat pariatur ex fugiat excepteur quis. Ad eu Lorem et id ad tempor veniam labore ad velit eiusmod elit elit proident. Non deserunt mollit ut nisi.\r\n", "registered": "2017-07-30T07:23:24 -02:00", "latitude": 72.043774, "longitude": -14.095053, "tags": [ "minim", "ad", "esse", "magna", "proident", "minim", "Lorem", "aliqua", "incididunt", "cupidatat" ], "friends": [ { "id": 0, "name": "Madge Foreman" }, { "id": 1, "name": "Irwin Crosby" }, { "id": 2, "name": "Deanne Day" }, { "id": 3, "name": "Holder Reilly" }, { "id": 4, "name": "Joni Horton" } ], "greeting": "Hello, Meyer Acevedo! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482692408ffafec0472b", "index": 143, "guid": "174f665a-3d05-45e9-9f67-fdebdd8f265e", "isActive": true, "balance": "$3,121.97", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Webb Chang", "gender": "male", "company": "VORTEXACO", "email": "webbchang@vortexaco.com", "phone": "+1 (889) 541-3464", "address": "356 Bay Parkway, Laurelton, Northern Mariana Islands, 6948", "about": "Deserunt nulla nostrud ipsum laboris aliqua officia eu fugiat aute consequat. Eu elit deserunt cupidatat ullamco quis. Id laboris cupidatat ex exercitation incididunt. Non elit proident consectetur ipsum proident adipisicing est dolore deserunt laborum excepteur duis quis eiusmod. Incididunt voluptate proident amet commodo eiusmod qui. Dolore sint sint duis fugiat ipsum Lorem proident pariatur non veniam nulla mollit culpa.\r\n", "registered": "2014-12-25T07:27:28 -01:00", "latitude": -73.210587, "longitude": 102.382882, "tags": [ "anim", "non", "sunt", "occaecat", "ipsum", "excepteur", "quis", "aliqua", "sunt", "veniam" ], "friends": [ { "id": 0, "name": "Singleton Gonzales" }, { "id": 1, "name": "Pitts Rivera" }, { "id": 2, "name": "Tonia Noble" }, { "id": 3, "name": "Charmaine Underwood" }, { "id": 4, "name": "Cecelia Sandoval" } ], "greeting": "Hello, Webb Chang! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826881eebc4bc9907eb", "index": 144, "guid": "d495ca57-4b09-4959-bf90-be5b2d20a2fc", "isActive": false, "balance": "$1,493.09", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "blue", "name": "Gretchen Allen", "gender": "female", "company": "INSURITY", "email": "gretchenallen@insurity.com", "phone": "+1 (810) 482-2939", "address": "360 Lincoln Place, Munjor, Pennsylvania, 2414", "about": "Esse incididunt consequat officia proident voluptate et dolor nostrud dolore. Cillum et veniam amet ad cillum dolor do elit ea duis dolore consequat quis non. Ullamco dolor cupidatat tempor cillum consequat cupidatat duis nostrud Lorem commodo non Lorem cupidatat. Labore ex enim et excepteur tempor duis.\r\n", "registered": "2017-10-28T03:03:15 -02:00", "latitude": -77.664186, "longitude": 60.203106, "tags": [ "officia", "labore", "cupidatat", "sit", "minim", "esse", "Lorem", "in", "eu", "officia" ], "friends": [ { "id": 0, "name": "Martin Frost" }, { "id": 1, "name": "Corine George" }, { "id": 2, "name": "Dudley Douglas" }, { "id": 3, "name": "Hickman Ramirez" }, { "id": 4, "name": "Sheryl Burris" } ], "greeting": "Hello, Gretchen Allen! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b8454728730fab54", "index": 145, "guid": "a0e29a1e-a39c-4718-9c7f-eb1df2d7e332", "isActive": true, "balance": "$2,409.68", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "green", "name": "Joanna Hayes", "gender": "female", "company": "ENTOGROK", "email": "joannahayes@entogrok.com", "phone": "+1 (988) 453-2173", "address": "399 Plymouth Street, Morgandale, Arkansas, 846", "about": "Occaecat est amet anim voluptate quis. Duis Lorem deserunt tempor nulla occaecat eiusmod eu voluptate esse. Deserunt occaecat ullamco Lorem deserunt pariatur dolor eu nostrud consectetur aliquip. Labore cillum voluptate culpa consequat nisi esse.\r\n", "registered": "2017-08-26T07:20:05 -02:00", "latitude": 8.608539, "longitude": 178.679481, "tags": [ "nulla", "nisi", "sit", "nulla", "exercitation", "magna", "ea", "deserunt", "ad", "ex" ], "friends": [ { "id": 0, "name": "Carver Pope" }, { "id": 1, "name": "Bowman Gutierrez" }, { "id": 2, "name": "Camacho Jensen" }, { "id": 3, "name": "Gilbert Stewart" }, { "id": 4, "name": "George Landry" } ], "greeting": "Hello, Joanna Hayes! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826535a105a7b586510", "index": 146, "guid": "ade660e0-71d9-4cb3-b39a-1d7b8f708680", "isActive": false, "balance": "$1,956.53", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "brown", "name": "Ward Guerra", "gender": "male", "company": "ISODRIVE", "email": "wardguerra@isodrive.com", "phone": "+1 (994) 528-2303", "address": "423 Tiffany Place, Tampico, Palau, 4845", "about": "Quis aliquip eiusmod ullamco dolore anim exercitation. Adipisicing incididunt est et Lorem deserunt sit mollit id nisi enim est ullamco laborum sunt. Voluptate dolore eiusmod ad laboris id deserunt sint laborum.\r\n", "registered": "2017-08-20T05:56:14 -02:00", "latitude": 58.258082, "longitude": -176.948321, "tags": [ "enim", "excepteur", "laborum", "amet", "cupidatat", "non", "consequat", "dolor", "anim", "id" ], "friends": [ { "id": 0, "name": "Charlotte Knight" }, { "id": 1, "name": "Santos Goff" }, { "id": 2, "name": "Gwendolyn Fox" }, { "id": 3, "name": "Cora Foley" }, { "id": 4, "name": "Hall Carney" } ], "greeting": "Hello, Ward Guerra! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826ced3b01b5ee326b1", "index": 147, "guid": "3a617cf7-e39b-48ad-881d-f83b389fe581", "isActive": false, "balance": "$2,891.19", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "brown", "name": "Hamilton Richards", "gender": "male", "company": "RODEOCEAN", "email": "hamiltonrichards@rodeocean.com", "phone": "+1 (995) 573-2083", "address": "358 Doone Court, Siglerville, Connecticut, 6088", "about": "Do eu cillum do culpa irure minim ex. Do ipsum quis esse elit nisi cillum aliquip magna cillum. Ut dolore aliquip incididunt qui anim pariatur consectetur excepteur dolor magna.\r\n", "registered": "2016-04-20T10:49:06 -02:00", "latitude": 79.357832, "longitude": -42.501126, "tags": [ "pariatur", "id", "exercitation", "officia", "deserunt", "ea", "elit", "eiusmod", "ad", "qui" ], "friends": [ { "id": 0, "name": "Hernandez Mills" }, { "id": 1, "name": "Colette Adams" }, { "id": 2, "name": "Harper Mccormick" }, { "id": 3, "name": "Maryanne Estrada" }, { "id": 4, "name": "Nell Craig" } ], "greeting": "Hello, Hamilton Richards! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826391d8a7a9c8f4560", "index": 148, "guid": "f600086c-ebfb-47ee-92a1-5f7b1d8e741e", "isActive": true, "balance": "$2,075.51", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Twila Coffey", "gender": "female", "company": "AMTAS", "email": "twilacoffey@amtas.com", "phone": "+1 (874) 560-3386", "address": "866 Tudor Terrace, Allendale, North Carolina, 1081", "about": "Mollit do commodo adipisicing pariatur excepteur sint laborum ullamco ut quis voluptate. Adipisicing tempor non non esse proident sit reprehenderit fugiat non. Anim cillum sint sit eu eiusmod quis. Lorem laboris duis officia non nulla est labore excepteur quis enim. Mollit labore mollit ad ad minim ipsum anim ut et est quis. Incididunt ipsum culpa esse duis.\r\n", "registered": "2014-02-10T01:18:23 -01:00", "latitude": -86.602677, "longitude": -167.518329, "tags": [ "tempor", "sunt", "eiusmod", "ex", "nisi", "consectetur", "proident", "eu", "incididunt", "in" ], "friends": [ { "id": 0, "name": "Ferrell Wiggins" }, { "id": 1, "name": "Saundra Daugherty" }, { "id": 2, "name": "Ochoa Hines" }, { "id": 3, "name": "Chandra Brennan" }, { "id": 4, "name": "Mcgee Yates" } ], "greeting": "Hello, Twila Coffey! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826eeeb9c56fcf77534", "index": 149, "guid": "0dc0121f-ab0f-4797-9666-a9be4e4e3dbe", "isActive": false, "balance": "$2,679.16", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Hurley Jacobs", "gender": "male", "company": "ISOPLEX", "email": "hurleyjacobs@isoplex.com", "phone": "+1 (968) 432-3459", "address": "661 Lynch Street, Titanic, Missouri, 6419", "about": "Exercitation aliqua magna irure aute consequat pariatur velit tempor proident eu cillum velit tempor cillum. Irure do sunt eu dolore sunt pariatur consectetur consequat culpa reprehenderit est duis labore ut. Eiusmod in aliquip magna cillum est est est elit esse. Exercitation sit excepteur in elit veniam nulla commodo nostrud id nostrud incididunt ipsum ullamco. Nostrud nisi duis ipsum deserunt velit cillum dolore elit minim duis tempor velit voluptate aute. Sint labore aute est incididunt sint excepteur id mollit dolor.\r\n", "registered": "2016-07-25T12:32:50 -02:00", "latitude": 67.277602, "longitude": -158.473323, "tags": [ "qui", "minim", "eiusmod", "ipsum", "quis", "tempor", "nostrud", "non", "mollit", "eiusmod" ], "friends": [ { "id": 0, "name": "Sharlene Best" }, { "id": 1, "name": "Flowers Morin" }, { "id": 2, "name": "Latoya Higgins" }, { "id": 3, "name": "Osborn Robinson" }, { "id": 4, "name": "Cheryl Greer" } ], "greeting": "Hello, Hurley Jacobs! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826d3a4a6318ad9f1ab", "index": 150, "guid": "471bd0d4-a9f9-4503-9e59-0113c74890bc", "isActive": false, "balance": "$2,136.80", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "green", "name": "Lilian Mcknight", "gender": "female", "company": "ACCEL", "email": "lilianmcknight@accel.com", "phone": "+1 (867) 471-2639", "address": "952 Rewe Street, Hendersonville, Ohio, 3613", "about": "Ex fugiat ut velit irure reprehenderit sit sint in pariatur ad cillum ea aliquip. Veniam fugiat pariatur adipisicing adipisicing aliqua occaecat fugiat voluptate enim deserunt. Ipsum velit sit minim ad exercitation consectetur elit excepteur.\r\n", "registered": "2015-05-21T10:04:44 -02:00", "latitude": -83.161182, "longitude": -172.901693, "tags": [ "adipisicing", "consectetur", "do", "dolore", "in", "velit", "aute", "sunt", "reprehenderit", "aliqua" ], "friends": [ { "id": 0, "name": "Farmer Harper" }, { "id": 1, "name": "Lacy Whitehead" }, { "id": 2, "name": "Blanchard Chase" }, { "id": 3, "name": "Nita Wood" }, { "id": 4, "name": "Forbes Eaton" } ], "greeting": "Hello, Lilian Mcknight! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c275fd6dd99e0256", "index": 151, "guid": "c314a205-ad2b-4783-bae1-8f5b75ff5dc7", "isActive": true, "balance": "$1,897.45", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "brown", "name": "Claudine Payne", "gender": "female", "company": "HINWAY", "email": "claudinepayne@hinway.com", "phone": "+1 (855) 528-2887", "address": "235 Fillmore Avenue, Dana, Arizona, 2184", "about": "Qui ea incididunt dolore adipisicing aute. Tempor ea est esse quis aliquip in eiusmod veniam qui nisi duis pariatur eiusmod. Laboris ex dolor amet magna laborum consectetur adipisicing consequat deserunt. Occaecat nulla non sint reprehenderit commodo.\r\n", "registered": "2016-12-27T07:23:30 -01:00", "latitude": -71.964066, "longitude": -62.14369, "tags": [ "nulla", "cillum", "dolore", "reprehenderit", "anim", "enim", "non", "Lorem", "cupidatat", "officia" ], "friends": [ { "id": 0, "name": "Terri Barrett" }, { "id": 1, "name": "Wilcox Pierce" }, { "id": 2, "name": "Cohen Lester" }, { "id": 3, "name": "Kristy Farley" }, { "id": 4, "name": "Dionne Trevino" } ], "greeting": "Hello, Claudine Payne! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482620e092549496e813", "index": 152, "guid": "7217ea94-ac6e-4ca3-9a03-8c5f6d01a367", "isActive": false, "balance": "$2,039.58", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "brown", "name": "Odessa Cummings", "gender": "female", "company": "QABOOS", "email": "odessacummings@qaboos.com", "phone": "+1 (996) 463-3107", "address": "110 Oliver Street, Kilbourne, Montana, 6132", "about": "Mollit reprehenderit duis aliqua ad do nisi amet elit fugiat. Voluptate est tempor nostrud aute dolor Lorem fugiat id nisi sint laborum proident irure dolore. Qui consectetur laboris eiusmod aliquip ut cupidatat. Non cillum velit non quis cupidatat amet proident adipisicing enim consectetur deserunt irure velit. Labore esse quis est ipsum. Duis proident in cupidatat dolore occaecat consectetur magna ex cupidatat cupidatat tempor mollit sint exercitation.\r\n", "registered": "2014-12-25T02:34:34 -01:00", "latitude": -18.001145, "longitude": 77.138423, "tags": [ "officia", "sunt", "dolor", "officia", "esse", "elit", "voluptate", "occaecat", "tempor", "magna" ], "friends": [ { "id": 0, "name": "Hope Buckley" }, { "id": 1, "name": "Latisha Gilmore" }, { "id": 2, "name": "Clark Curry" }, { "id": 3, "name": "Beverley Terrell" }, { "id": 4, "name": "Erin Weiss" } ], "greeting": "Hello, Odessa Cummings! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826d0e11a0ff09792d4", "index": 153, "guid": "b870f2a7-b4db-4bef-8a55-98e72b9971b3", "isActive": true, "balance": "$3,790.29", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Mccall Huffman", "gender": "male", "company": "ZENCO", "email": "mccallhuffman@zenco.com", "phone": "+1 (979) 500-3151", "address": "455 Cleveland Street, Herbster, Texas, 6194", "about": "Aliqua sit est velit aute irure cupidatat consectetur reprehenderit excepteur duis tempor aute irure sit. Do enim labore quis labore magna est duis labore ut duis anim. Quis quis ipsum et elit ex. Quis do eiusmod duis consectetur reprehenderit veniam fugiat deserunt est Lorem sunt consequat exercitation.\r\n", "registered": "2014-11-23T04:06:07 -01:00", "latitude": -22.303838, "longitude": -89.980426, "tags": [ "exercitation", "ipsum", "aliqua", "incididunt", "proident", "excepteur", "esse", "consequat", "velit", "ut" ], "friends": [ { "id": 0, "name": "Bette Rose" }, { "id": 1, "name": "Huffman Cooke" }, { "id": 2, "name": "Francesca Berg" }, { "id": 3, "name": "Carpenter Wyatt" }, { "id": 4, "name": "Mccoy Barron" } ], "greeting": "Hello, Mccall Huffman! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826ecb4ef8110df6074", "index": 154, "guid": "1e89e10e-bdfb-43ad-af63-b865f8e3889e", "isActive": true, "balance": "$2,893.76", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Trisha Little", "gender": "female", "company": "ASSITIA", "email": "trishalittle@assitia.com", "phone": "+1 (840) 543-3214", "address": "833 Fountain Avenue, Topanga, Washington, 8004", "about": "In cillum laborum nisi eu consequat non excepteur duis Lorem officia eiusmod in pariatur. Non officia fugiat minim ad eu aliqua eu. Aute nulla ullamco dolore non pariatur adipisicing pariatur minim. Aliqua magna ipsum aliquip nulla ut nisi dolore reprehenderit voluptate magna ex. Velit et culpa id Lorem officia irure ut exercitation exercitation. Deserunt exercitation eu Lorem elit. Amet in aute occaecat esse nostrud eiusmod nulla.\r\n", "registered": "2015-10-25T12:30:59 -01:00", "latitude": 36.250825, "longitude": 129.298407, "tags": [ "mollit", "adipisicing", "cillum", "non", "laborum", "cillum", "sit", "consequat", "amet", "esse" ], "friends": [ { "id": 0, "name": "Dyer Villarreal" }, { "id": 1, "name": "Ronda Franks" }, { "id": 2, "name": "Montgomery Whitley" }, { "id": 3, "name": "Aline Reed" }, { "id": 4, "name": "Corina Shaw" } ], "greeting": "Hello, Trisha Little! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482633ee2e49d0908d11", "index": 155, "guid": "eaab4ad2-76fc-4736-8503-daa37950cd8b", "isActive": false, "balance": "$3,027.41", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "brown", "name": "Winters Brock", "gender": "male", "company": "POLARIUM", "email": "wintersbrock@polarium.com", "phone": "+1 (818) 523-3471", "address": "508 Dooley Street, Sabillasville, Wyoming, 486", "about": "Voluptate in commodo minim occaecat eiusmod veniam qui elit eiusmod laboris. Nostrud sunt ullamco cillum ut. Laborum reprehenderit commodo commodo incididunt quis aliqua dolor ut aliqua non aliqua voluptate dolore non. Adipisicing elit culpa ullamco do enim cillum aliquip occaecat exercitation fugiat minim aliqua sit sit. Commodo et irure do duis.\r\n", "registered": "2017-07-18T04:22:49 -02:00", "latitude": -82.716719, "longitude": 65.217479, "tags": [ "minim", "amet", "dolore", "veniam", "elit", "consequat", "magna", "elit", "pariatur", "aliquip" ], "friends": [ { "id": 0, "name": "Lee Randall" }, { "id": 1, "name": "Ellis Lindsay" }, { "id": 2, "name": "Katherine Waller" }, { "id": 3, "name": "Cornelia Fischer" }, { "id": 4, "name": "Ayers Sears" } ], "greeting": "Hello, Winters Brock! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48268eff726a29483be7", "index": 156, "guid": "fcc1b66b-42d4-47bc-b59d-8a77ae8a1910", "isActive": true, "balance": "$2,970.40", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Clarissa Mcclure", "gender": "female", "company": "KIDSTOCK", "email": "clarissamcclure@kidstock.com", "phone": "+1 (958) 417-2247", "address": "663 Vandervoort Avenue, Nanafalia, Indiana, 132", "about": "Dolor ut adipisicing dolor cupidatat reprehenderit eiusmod tempor incididunt laboris veniam sint velit commodo cupidatat. Anim cillum officia do pariatur dolore esse dolore id cillum proident exercitation ut cillum anim. Id cillum et dolore quis incididunt tempor sit cupidatat aliquip. Non amet consequat anim magna ea. Aliqua ea qui ut dolore dolore culpa cillum.\r\n", "registered": "2015-01-05T03:27:06 -01:00", "latitude": -51.56868, "longitude": -80.087879, "tags": [ "non", "eu", "ipsum", "dolor", "do", "ad", "aute", "velit", "veniam", "veniam" ], "friends": [ { "id": 0, "name": "Nellie Hansen" }, { "id": 1, "name": "Louella Vega" }, { "id": 2, "name": "Edna Joyce" }, { "id": 3, "name": "Tasha Ratliff" }, { "id": 4, "name": "Olga Heath" } ], "greeting": "Hello, Clarissa Mcclure! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48267b9c28cc8952fe31", "index": 157, "guid": "8e15bdee-6768-46e8-b326-7984d615324b", "isActive": true, "balance": "$3,577.98", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Mooney Reyes", "gender": "male", "company": "DIGITALUS", "email": "mooneyreyes@digitalus.com", "phone": "+1 (864) 522-3741", "address": "495 Liberty Avenue, Gardiner, Alabama, 3489", "about": "Excepteur incididunt anim voluptate consequat esse dolore in. Laboris veniam anim irure aute id reprehenderit sit consectetur occaecat officia consequat. Occaecat laborum duis voluptate id ut tempor pariatur in aliqua labore consequat aliqua. Aute veniam duis eu consectetur. Quis dolor sit veniam consequat aliqua eu nostrud Lorem id cupidatat veniam sunt culpa. Voluptate dolore veniam deserunt duis. Eu labore eu excepteur voluptate anim ipsum officia.\r\n", "registered": "2014-06-17T10:21:59 -02:00", "latitude": -52.456609, "longitude": 32.715246, "tags": [ "veniam", "anim", "id", "aliquip", "aute", "consequat", "labore", "labore", "ad", "eiusmod" ], "friends": [ { "id": 0, "name": "Juliette Christian" }, { "id": 1, "name": "Socorro Shannon" }, { "id": 2, "name": "Combs Soto" }, { "id": 3, "name": "Kelly Short" }, { "id": 4, "name": "Obrien Downs" } ], "greeting": "Hello, Mooney Reyes! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48266c6784258b7bdbc4", "index": 158, "guid": "c87dc58d-124f-4ee3-80ab-49c085db9ec9", "isActive": true, "balance": "$3,878.50", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Jane Hendricks", "gender": "female", "company": "EVEREST", "email": "janehendricks@everest.com", "phone": "+1 (934) 513-2643", "address": "716 Sheffield Avenue, Chamizal, Virginia, 8967", "about": "Excepteur ullamco pariatur dolor elit tempor occaecat proident exercitation est ullamco velit. Sint Lorem ut minim exercitation. Mollit quis dolor cillum proident eiusmod veniam laborum anim. Ad deserunt nulla proident tempor velit magna ut anim enim esse tempor et nisi. Tempor do occaecat dolore dolor ex voluptate quis ipsum sint id aliqua. Consequat nostrud elit nostrud sit cupidatat nisi incididunt velit cupidatat nisi ad.\r\n", "registered": "2014-12-19T08:35:14 -01:00", "latitude": -81.883361, "longitude": 69.74053, "tags": [ "labore", "id", "consectetur", "eiusmod", "eiusmod", "eu", "id", "dolor", "aliqua", "in" ], "friends": [ { "id": 0, "name": "Savannah Henry" }, { "id": 1, "name": "Bernice Mckenzie" }, { "id": 2, "name": "Simmons Mason" }, { "id": 3, "name": "Harrington Head" }, { "id": 4, "name": "Pate Williamson" } ], "greeting": "Hello, Jane Hendricks! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826af0cfc8219110b78", "index": 159, "guid": "8d759040-bd1c-4a7f-878b-71a326eed1be", "isActive": false, "balance": "$2,741.51", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Mclean Coleman", "gender": "male", "company": "IDEALIS", "email": "mcleancoleman@idealis.com", "phone": "+1 (829) 551-2976", "address": "812 Devon Avenue, Taft, New Mexico, 4861", "about": "Dolore sint deserunt et qui. Nulla qui adipisicing culpa culpa consequat eu adipisicing deserunt. Eiusmod deserunt laborum id ex et.\r\n", "registered": "2017-08-15T02:53:57 -02:00", "latitude": -55.937442, "longitude": -160.021889, "tags": [ "velit", "adipisicing", "et", "voluptate", "nostrud", "sint", "aliqua", "ea", "velit", "ea" ], "friends": [ { "id": 0, "name": "Josie Nielsen" }, { "id": 1, "name": "Miles Rosario" }, { "id": 2, "name": "Mcdowell Livingston" }, { "id": 3, "name": "Sims Beck" }, { "id": 4, "name": "Erma Williams" } ], "greeting": "Hello, Mclean Coleman! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826b5f3c94f6a864d96", "index": 160, "guid": "707968db-13f0-4c40-959b-50fafe3357c0", "isActive": true, "balance": "$2,340.01", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "blue", "name": "Glenn Buck", "gender": "male", "company": "INTERFIND", "email": "glennbuck@interfind.com", "phone": "+1 (922) 513-3658", "address": "763 Greenpoint Avenue, Bowden, Hawaii, 7068", "about": "Labore deserunt est in est labore anim velit ipsum. Exercitation consequat reprehenderit culpa ipsum sunt ipsum consectetur adipisicing cupidatat. Incididunt minim Lorem commodo incididunt consectetur quis ex ad cillum aute aute voluptate nulla eu. Ut laborum veniam occaecat sit amet aliqua pariatur in reprehenderit.\r\n", "registered": "2016-03-14T01:50:47 -01:00", "latitude": 4.095995, "longitude": -41.552541, "tags": [ "dolor", "Lorem", "et", "commodo", "culpa", "do", "occaecat", "dolore", "laboris", "occaecat" ], "friends": [ { "id": 0, "name": "Juana Murphy" }, { "id": 1, "name": "Lucinda Bauer" }, { "id": 2, "name": "Lancaster Whitfield" }, { "id": 3, "name": "Hallie Dudley" }, { "id": 4, "name": "Laurel Klein" } ], "greeting": "Hello, Glenn Buck! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826ea4dc7d9311953f4", "index": 161, "guid": "e8320162-c008-4f07-a85f-5c357a6a7359", "isActive": true, "balance": "$2,728.68", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Annie Simon", "gender": "female", "company": "ENERSOL", "email": "anniesimon@enersol.com", "phone": "+1 (932) 486-3846", "address": "714 Nova Court, Flintville, Nebraska, 3063", "about": "Tempor laboris ex proident velit qui fugiat. Nostrud fugiat nostrud elit mollit officia est pariatur ipsum pariatur. Ad anim reprehenderit occaecat nostrud.\r\n", "registered": "2014-10-01T09:24:31 -02:00", "latitude": 45.208209, "longitude": -65.721343, "tags": [ "anim", "irure", "exercitation", "pariatur", "do", "incididunt", "nisi", "dolore", "in", "officia" ], "friends": [ { "id": 0, "name": "Walker Finley" }, { "id": 1, "name": "Connie Fowler" }, { "id": 2, "name": "Mitzi Stanley" }, { "id": 3, "name": "Gena Henderson" }, { "id": 4, "name": "Bray Avila" } ], "greeting": "Hello, Annie Simon! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48260d0df4d7bbf42abf", "index": 162, "guid": "af873db7-4c20-4c0f-9213-0301afc3cf1b", "isActive": true, "balance": "$1,870.42", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Maldonado Reynolds", "gender": "male", "company": "ENAUT", "email": "maldonadoreynolds@enaut.com", "phone": "+1 (809) 582-3514", "address": "444 Rochester Avenue, Thomasville, New York, 6369", "about": "Laboris dolore sit reprehenderit eu. Duis Lorem cillum fugiat in. Laboris nostrud exercitation id magna dolor consectetur aliquip laboris minim eiusmod labore officia quis ea. Cillum aute enim ea minim enim in. Voluptate nostrud cupidatat Lorem tempor aute.\r\n", "registered": "2017-12-30T08:43:41 -01:00", "latitude": -57.901883, "longitude": -41.963121, "tags": [ "eiusmod", "ex", "mollit", "ad", "dolore", "elit", "Lorem", "duis", "dolor", "eiusmod" ], "friends": [ { "id": 0, "name": "Farley Frederick" }, { "id": 1, "name": "Valerie Walsh" }, { "id": 2, "name": "Esther Bowman" }, { "id": 3, "name": "Marie Vargas" }, { "id": 4, "name": "Branch Stokes" } ], "greeting": "Hello, Maldonado Reynolds! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ae630e6f3d6c21d4", "index": 163, "guid": "f8053edb-73d7-4d8b-8859-3d0c9a65bef6", "isActive": true, "balance": "$2,178.44", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Celia Lewis", "gender": "female", "company": "MYOPIUM", "email": "celialewis@myopium.com", "phone": "+1 (975) 509-3402", "address": "882 Livingston Street, Macdona, Marshall Islands, 963", "about": "Occaecat ad cupidatat sint consectetur sunt reprehenderit ad consectetur qui minim eu in irure non. Esse voluptate aute duis velit exercitation non proident. Elit incididunt dolor voluptate eiusmod. Non laborum do enim ullamco qui ut irure aliquip est do amet deserunt aliqua reprehenderit.\r\n", "registered": "2017-04-02T12:23:24 -02:00", "latitude": 3.879628, "longitude": -83.27094, "tags": [ "fugiat", "pariatur", "culpa", "id", "occaecat", "aute", "officia", "do", "veniam", "proident" ], "friends": [ { "id": 0, "name": "Cabrera Vazquez" }, { "id": 1, "name": "Flores Gates" }, { "id": 2, "name": "Jillian Espinoza" }, { "id": 3, "name": "Irma Collier" }, { "id": 4, "name": "Mona Riley" } ], "greeting": "Hello, Celia Lewis! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261725e7bbff7dfe58", "index": 164, "guid": "62fb01be-ac11-4e00-be56-9d40d6abe0aa", "isActive": true, "balance": "$3,432.49", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "blue", "name": "Lane Sexton", "gender": "male", "company": "ORBIXTAR", "email": "lanesexton@orbixtar.com", "phone": "+1 (913) 415-2313", "address": "698 Gates Avenue, Martinsville, Oregon, 8662", "about": "Sit eiusmod sit deserunt pariatur sunt est culpa elit aliqua nulla tempor proident incididunt pariatur. Et qui sint occaecat id culpa. Do est minim veniam reprehenderit cupidatat excepteur nisi nulla sit quis minim. Lorem laboris nostrud non excepteur magna aliqua. Ullamco ut ad nulla nostrud cillum amet enim.\r\n", "registered": "2015-04-22T09:32:32 -02:00", "latitude": 68.089976, "longitude": 4.847333, "tags": [ "voluptate", "adipisicing", "aute", "est", "adipisicing", "tempor", "deserunt", "Lorem", "proident", "enim" ], "friends": [ { "id": 0, "name": "Cardenas Davis" }, { "id": 1, "name": "Dorthy Park" }, { "id": 2, "name": "Janelle Kirk" }, { "id": 3, "name": "Frost Mccullough" }, { "id": 4, "name": "Torres Savage" } ], "greeting": "Hello, Lane Sexton! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48264a2b3e91121f2bfa", "index": 165, "guid": "b3b12613-9db6-4398-b10c-05be13373b56", "isActive": false, "balance": "$1,391.88", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Petra Spencer", "gender": "female", "company": "SURELOGIC", "email": "petraspencer@surelogic.com", "phone": "+1 (802) 600-3436", "address": "325 Vermont Street, Brambleton, Tennessee, 7395", "about": "Non consectetur ea fugiat mollit consequat mollit pariatur culpa Lorem aliquip. Ea aliqua magna Lorem exercitation. Cupidatat eu officia veniam ea. Amet ullamco dolore cupidatat aliquip consectetur ut esse.\r\n", "registered": "2014-05-10T07:28:51 -02:00", "latitude": -17.046735, "longitude": 98.440352, "tags": [ "id", "do", "non", "dolore", "labore", "in", "proident", "consectetur", "pariatur", "eu" ], "friends": [ { "id": 0, "name": "Tyler White" }, { "id": 1, "name": "Kim Holloway" }, { "id": 2, "name": "Rosario Randolph" }, { "id": 3, "name": "Cooley Caldwell" }, { "id": 4, "name": "Hampton Paul" } ], "greeting": "Hello, Petra Spencer! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826cec9337b87b43549", "index": 166, "guid": "311c0aae-1a3c-4c36-8086-62ff4800075d", "isActive": true, "balance": "$3,765.82", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Chan Mann", "gender": "male", "company": "SPHERIX", "email": "chanmann@spherix.com", "phone": "+1 (874) 495-3748", "address": "898 Agate Court, Crucible, Nevada, 183", "about": "Qui sint eu ea qui ea qui labore incididunt exercitation adipisicing dolor velit quis. Eu occaecat aute sint adipisicing. Laboris et Lorem labore magna mollit consectetur fugiat ad. Est eu anim pariatur aliqua id laborum culpa deserunt cupidatat eu ut amet. Irure laborum deserunt pariatur incididunt labore reprehenderit dolor incididunt laboris consequat mollit dolor ad elit. Ad irure culpa eu voluptate ullamco.\r\n", "registered": "2017-04-25T11:02:05 -02:00", "latitude": 30.316037, "longitude": -149.208811, "tags": [ "amet", "pariatur", "id", "qui", "proident", "dolore", "occaecat", "ea", "velit", "culpa" ], "friends": [ { "id": 0, "name": "Cruz Burton" }, { "id": 1, "name": "Martha Haney" }, { "id": 2, "name": "Barlow Hudson" }, { "id": 3, "name": "Valenzuela Montgomery" }, { "id": 4, "name": "Iva Nelson" } ], "greeting": "Hello, Chan Mann! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482634c93c7e633acf33", "index": 167, "guid": "886a9ce4-b424-4043-bb42-46800fc9d10d", "isActive": false, "balance": "$2,858.19", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "blue", "name": "Peterson Patrick", "gender": "male", "company": "STELAECOR", "email": "petersonpatrick@stelaecor.com", "phone": "+1 (984) 400-3860", "address": "532 Herkimer Court, Kersey, Alaska, 2278", "about": "Sint aute dolore cupidatat eiusmod excepteur culpa aliquip aliquip dolore. Et enim deserunt excepteur Lorem nisi deserunt tempor magna enim. Ea ea in nostrud deserunt adipisicing incididunt sunt quis nulla excepteur nisi non elit consectetur.\r\n", "registered": "2015-07-17T09:43:57 -02:00", "latitude": -41.161863, "longitude": -53.367442, "tags": [ "pariatur", "laborum", "ullamco", "dolor", "qui", "id", "excepteur", "in", "sit", "labore" ], "friends": [ { "id": 0, "name": "Rhonda Burks" }, { "id": 1, "name": "Calderon Dickerson" }, { "id": 2, "name": "Weaver Ortega" }, { "id": 3, "name": "Nettie Dominguez" }, { "id": 4, "name": "Dominguez Mercado" } ], "greeting": "Hello, Peterson Patrick! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48263d45125d89a63ff4", "index": 168, "guid": "732cb4a3-477a-4b01-8a68-d3f3afe7ad63", "isActive": false, "balance": "$2,101.99", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Alba Conway", "gender": "female", "company": "ZIGGLES", "email": "albaconway@ziggles.com", "phone": "+1 (918) 538-3066", "address": "710 Glen Street, Bedias, Illinois, 4484", "about": "Ut labore consequat occaecat deserunt qui in. Lorem ipsum commodo culpa minim proident amet voluptate eiusmod non nisi. Qui Lorem quis sunt proident enim laborum ea ea dolor labore.\r\n", "registered": "2014-04-28T01:07:22 -02:00", "latitude": 64.837166, "longitude": 71.607687, "tags": [ "sunt", "nostrud", "culpa", "ut", "ea", "et", "do", "aliquip", "commodo", "aliqua" ], "friends": [ { "id": 0, "name": "Tillman Bean" }, { "id": 1, "name": "Jimenez Montoya" }, { "id": 2, "name": "Helen Sellers" }, { "id": 3, "name": "Francisca Holman" }, { "id": 4, "name": "Gilda Floyd" } ], "greeting": "Hello, Alba Conway! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f383ee76a90aeb10", "index": 169, "guid": "58193ef9-a7c5-4dcf-84bc-0873402161cd", "isActive": false, "balance": "$1,765.56", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Rivers Santana", "gender": "male", "company": "LUDAK", "email": "riverssantana@ludak.com", "phone": "+1 (929) 581-3262", "address": "225 Winthrop Street, Zarephath, Oklahoma, 4627", "about": "Anim ea sit in fugiat aliqua cupidatat Lorem elit. Nostrud quis labore officia sit labore nulla adipisicing in velit adipisicing officia. Voluptate est nostrud irure tempor ut Lorem pariatur dolor ut elit sunt esse nisi velit. Fugiat fugiat aute ad deserunt.\r\n", "registered": "2014-04-19T07:00:44 -02:00", "latitude": -43.696652, "longitude": -77.316568, "tags": [ "mollit", "sint", "anim", "fugiat", "incididunt", "qui", "culpa", "sit", "ipsum", "tempor" ], "friends": [ { "id": 0, "name": "Rita Tate" }, { "id": 1, "name": "Jimmie Barber" }, { "id": 2, "name": "Jami Sawyer" }, { "id": 3, "name": "Lindsey Harrington" }, { "id": 4, "name": "Polly Davenport" } ], "greeting": "Hello, Rivers Santana! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826e17f7e667e8d244b", "index": 170, "guid": "80d91859-8912-4a03-a129-d927cc69bfbd", "isActive": true, "balance": "$1,911.34", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "brown", "name": "Georgia Ferguson", "gender": "female", "company": "BUZZNESS", "email": "georgiaferguson@buzzness.com", "phone": "+1 (948) 558-3644", "address": "890 Olive Street, Martinez, Delaware, 3430", "about": "Aliquip quis ut enim aliqua consequat. Nulla et elit veniam anim qui minim non officia ullamco. Tempor esse minim esse nulla magna eiusmod sunt ad culpa adipisicing cupidatat ad eu. Adipisicing consectetur officia nisi eiusmod dolor adipisicing amet. Laboris dolore reprehenderit duis voluptate ullamco amet quis ullamco enim commodo. Proident ad reprehenderit aute mollit Lorem id adipisicing tempor esse ex ullamco sunt velit.\r\n", "registered": "2014-01-03T10:40:15 -01:00", "latitude": -27.627318, "longitude": 95.666127, "tags": [ "nostrud", "consequat", "nostrud", "cillum", "ipsum", "in", "et", "sint", "esse", "duis" ], "friends": [ { "id": 0, "name": "Evangeline Burch" }, { "id": 1, "name": "Amy Maynard" }, { "id": 2, "name": "Pruitt Andrews" }, { "id": 3, "name": "Ericka Lott" }, { "id": 4, "name": "Allie Rojas" } ], "greeting": "Hello, Georgia Ferguson! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48269c5bfd6a2e8b0ce5", "index": 171, "guid": "7f1c489b-b3b0-484f-89a6-c1d782516e5e", "isActive": false, "balance": "$2,610.20", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "green", "name": "Theresa Lane", "gender": "female", "company": "AQUAMATE", "email": "theresalane@aquamate.com", "phone": "+1 (889) 547-2674", "address": "528 Oak Street, Chautauqua, Federated States Of Micronesia, 5693", "about": "Qui nisi excepteur irure consequat sit eu adipisicing esse magna id pariatur laboris labore. Cillum consequat dolor occaecat nulla voluptate. Dolore officia consequat reprehenderit sunt. Commodo dolor aliquip non officia eu eiusmod tempor. Cupidatat enim incididunt ex anim consectetur. Tempor veniam labore do eiusmod Lorem. Officia voluptate anim sit nostrud enim consequat laborum cillum ipsum commodo et eu aute.\r\n", "registered": "2016-06-21T01:14:08 -02:00", "latitude": -37.464925, "longitude": -134.701977, "tags": [ "cupidatat", "ipsum", "culpa", "sit", "consequat", "dolore", "id", "laborum", "qui", "voluptate" ], "friends": [ { "id": 0, "name": "Swanson Wells" }, { "id": 1, "name": "Deana Mullins" }, { "id": 2, "name": "Sanford Schroeder" }, { "id": 3, "name": "Park Frazier" }, { "id": 4, "name": "Bartlett Robles" } ], "greeting": "Hello, Theresa Lane! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826837c5f500fb468d5", "index": 172, "guid": "29258b38-dd70-4df0-967b-77a35568935e", "isActive": false, "balance": "$3,190.89", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Hawkins Beard", "gender": "male", "company": "NETILITY", "email": "hawkinsbeard@netility.com", "phone": "+1 (923) 444-3119", "address": "171 Friel Place, Haring, Florida, 6610", "about": "Voluptate incididunt elit irure ut sunt amet cillum ex fugiat exercitation. Anim culpa nostrud culpa sunt. Adipisicing mollit pariatur minim sunt adipisicing velit nisi culpa irure.\r\n", "registered": "2017-09-19T07:48:07 -02:00", "latitude": 4.320262, "longitude": 63.32352, "tags": [ "sunt", "veniam", "laboris", "voluptate", "dolor", "consequat", "ad", "enim", "cupidatat", "pariatur" ], "friends": [ { "id": 0, "name": "Munoz Stout" }, { "id": 1, "name": "Jodi Cameron" }, { "id": 2, "name": "Estela Briggs" }, { "id": 3, "name": "Mullen Dodson" }, { "id": 4, "name": "Robertson Gross" } ], "greeting": "Hello, Hawkins Beard! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826db613c3cfced267f", "index": 173, "guid": "0ff8dfa5-25fa-4bb1-9482-fffd5539c2f6", "isActive": false, "balance": "$2,344.61", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "blue", "name": "Lynn Bridges", "gender": "female", "company": "FANGOLD", "email": "lynnbridges@fangold.com", "phone": "+1 (904) 406-2685", "address": "890 Box Street, Ona, Massachusetts, 4232", "about": "Occaecat fugiat sint sit nisi. Non labore ut elit pariatur laborum aliqua elit in nisi irure velit. Eu esse sit reprehenderit deserunt est commodo eiusmod.\r\n", "registered": "2017-03-15T09:02:51 -01:00", "latitude": 89.649518, "longitude": -73.772769, "tags": [ "exercitation", "ullamco", "aute", "esse", "aute", "laborum", "ullamco", "est", "veniam", "sint" ], "friends": [ { "id": 0, "name": "Debbie Todd" }, { "id": 1, "name": "Guy Simpson" }, { "id": 2, "name": "Kaufman Peck" }, { "id": 3, "name": "Cassandra Marquez" }, { "id": 4, "name": "Ellison Medina" } ], "greeting": "Hello, Lynn Bridges! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482647668477f49d6adc", "index": 174, "guid": "4eb911e2-76c3-484b-a16b-6afea5e7da2e", "isActive": false, "balance": "$1,138.72", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "blue", "name": "Krystal Snider", "gender": "female", "company": "GRUPOLI", "email": "krystalsnider@grupoli.com", "phone": "+1 (904) 489-2817", "address": "540 Moffat Street, Windsor, Mississippi, 3054", "about": "Velit amet nisi labore irure aliqua quis ullamco sint voluptate veniam mollit velit nisi aute. Deserunt sunt sit aliqua est voluptate Lorem quis et veniam elit. Fugiat fugiat id cupidatat elit consectetur deserunt deserunt veniam tempor ullamco esse ullamco adipisicing aliqua. Excepteur velit do ea esse do laborum. Elit tempor minim sint mollit eiusmod nisi et fugiat magna aliqua labore nulla.\r\n", "registered": "2018-01-01T12:03:51 -01:00", "latitude": 4.900774, "longitude": 136.668155, "tags": [ "reprehenderit", "irure", "ea", "pariatur", "et", "tempor", "aliquip", "sunt", "anim", "duis" ], "friends": [ { "id": 0, "name": "Jones Nieves" }, { "id": 1, "name": "Lena Pugh" }, { "id": 2, "name": "Lucile Young" }, { "id": 3, "name": "Yvette Garza" }, { "id": 4, "name": "Adeline Tyson" } ], "greeting": "Hello, Krystal Snider! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48269bdc22fe1036c7ba", "index": 175, "guid": "2e5e5733-2eb5-49c4-9148-e73c93793ff6", "isActive": true, "balance": "$3,152.37", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "brown", "name": "Pittman Dalton", "gender": "male", "company": "ACRUEX", "email": "pittmandalton@acruex.com", "phone": "+1 (819) 544-2364", "address": "944 Boardwalk , Hardyville, Guam, 8289", "about": "Elit amet voluptate minim commodo sit voluptate esse. Nulla qui cupidatat ut nisi cupidatat nulla mollit dolore consectetur id dolor aliqua. Cillum amet id veniam voluptate in mollit non laborum et ad cillum sit. Ea irure aliquip proident eiusmod do sunt.\r\n", "registered": "2015-06-21T06:04:14 -02:00", "latitude": -73.845644, "longitude": -74.492829, "tags": [ "anim", "duis", "eiusmod", "excepteur", "mollit", "anim", "dolor", "proident", "aute", "est" ], "friends": [ { "id": 0, "name": "Della Pearson" }, { "id": 1, "name": "Lindsey Sloan" }, { "id": 2, "name": "Mollie Wade" }, { "id": 3, "name": "Misty Burt" }, { "id": 4, "name": "Bernadine Shelton" } ], "greeting": "Hello, Pittman Dalton! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e3a2c67ac4df02c9", "index": 176, "guid": "cc326ab3-172d-4c2d-9214-cc541fc95a35", "isActive": true, "balance": "$3,554.33", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "green", "name": "Holcomb Combs", "gender": "male", "company": "DOGNOSIS", "email": "holcombcombs@dognosis.com", "phone": "+1 (989) 402-3236", "address": "655 Clara Street, Chalfant, Louisiana, 4719", "about": "Occaecat qui sunt occaecat labore reprehenderit Lorem magna anim anim aute excepteur ipsum est. Consectetur nostrud magna laborum sint deserunt consequat enim occaecat exercitation mollit duis. Laboris labore nisi proident officia occaecat. Non nisi anim irure id amet. Qui magna consequat est nostrud enim. Quis reprehenderit ut Lorem ad dolor quis in minim amet pariatur consectetur. Anim sunt ut laborum ipsum commodo labore laboris officia ad pariatur eu quis irure et.\r\n", "registered": "2014-11-26T05:31:50 -01:00", "latitude": 46.644989, "longitude": 97.760221, "tags": [ "non", "sint", "ullamco", "enim", "sit", "non", "Lorem", "officia", "quis", "exercitation" ], "friends": [ { "id": 0, "name": "Everett Duncan" }, { "id": 1, "name": "Nichols Holmes" }, { "id": 2, "name": "Jeanie Moss" }, { "id": 3, "name": "Young Gill" }, { "id": 4, "name": "Chambers Roy" } ], "greeting": "Hello, Holcomb Combs! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48264c08dd4a3df0b115", "index": 177, "guid": "3f14a81b-8519-497f-accb-156813b8fa7b", "isActive": false, "balance": "$1,103.55", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "brown", "name": "Madelyn Duke", "gender": "female", "company": "OPPORTECH", "email": "madelynduke@opportech.com", "phone": "+1 (957) 409-2437", "address": "560 Nevins Street, Ronco, South Dakota, 1520", "about": "Ad reprehenderit reprehenderit nostrud est dolore. Esse irure labore irure dolore Lorem. Cupidatat nisi nostrud reprehenderit excepteur amet anim. Consequat et elit nisi consequat. Fugiat aliqua officia laborum sit do ea.\r\n", "registered": "2016-06-18T11:36:46 -02:00", "latitude": 20.79569, "longitude": 134.332748, "tags": [ "laboris", "dolore", "ullamco", "consectetur", "amet", "quis", "eiusmod", "amet", "occaecat", "cillum" ], "friends": [ { "id": 0, "name": "Marion Rush" }, { "id": 1, "name": "Rice Wall" }, { "id": 2, "name": "Dora Cervantes" }, { "id": 3, "name": "Kemp Chan" }, { "id": 4, "name": "Mullins Hewitt" } ], "greeting": "Hello, Madelyn Duke! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c1cce087d7009af7", "index": 178, "guid": "38da9408-8a7d-408a-81f9-6681c83bcb34", "isActive": true, "balance": "$1,332.84", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Amelia Witt", "gender": "female", "company": "FUTURITY", "email": "ameliawitt@futurity.com", "phone": "+1 (921) 423-3997", "address": "236 Bridgewater Street, Hilltop, District Of Columbia, 8543", "about": "Est qui et sit esse quis consectetur. Fugiat fugiat eiusmod reprehenderit et esse consequat ad est. Magna aute ipsum et do laborum et irure ut ullamco id eiusmod velit officia.\r\n", "registered": "2016-06-11T04:44:54 -02:00", "latitude": -28.622229, "longitude": -84.950517, "tags": [ "incididunt", "dolore", "qui", "sit", "deserunt", "mollit", "occaecat", "incididunt", "reprehenderit", "aliquip" ], "friends": [ { "id": 0, "name": "Malone Marshall" }, { "id": 1, "name": "Sparks Ruiz" }, { "id": 2, "name": "Simone Richard" }, { "id": 3, "name": "Elisa Cook" }, { "id": 4, "name": "Huber Alvarez" } ], "greeting": "Hello, Amelia Witt! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826d8737f91e63027ee", "index": 179, "guid": "2d37a2e5-d12b-4b6f-a1f4-78c69f09256b", "isActive": false, "balance": "$2,841.30", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Mccarthy Gardner", "gender": "male", "company": "ZIDOX", "email": "mccarthygardner@zidox.com", "phone": "+1 (816) 535-3243", "address": "646 Pilling Street, Osmond, Puerto Rico, 1640", "about": "Cupidatat do mollit dolore nulla pariatur magna eu adipisicing occaecat id. Eu culpa culpa consectetur voluptate nisi commodo velit in excepteur sit. Amet anim elit anim nisi aute id cillum sunt nulla proident eu minim. Tempor cupidatat do labore ex laboris sit culpa tempor esse incididunt culpa. Elit ullamco sint Lorem anim deserunt cupidatat non magna Lorem mollit id aliqua deserunt. Amet ex minim reprehenderit adipisicing amet ut labore qui aliqua cillum Lorem elit eu ea. Aliqua exercitation do reprehenderit sit adipisicing in fugiat excepteur ad esse exercitation est reprehenderit minim.\r\n", "registered": "2014-08-27T05:45:27 -02:00", "latitude": 23.042597, "longitude": -77.507818, "tags": [ "minim", "eiusmod", "aliquip", "ex", "qui", "elit", "deserunt", "reprehenderit", "cupidatat", "consequat" ], "friends": [ { "id": 0, "name": "Velazquez West" }, { "id": 1, "name": "Randolph Carter" }, { "id": 2, "name": "Ferguson Farmer" }, { "id": 3, "name": "Whitehead Michael" }, { "id": 4, "name": "Schultz Joseph" } ], "greeting": "Hello, Mccarthy Gardner! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826cb8d3beeb32a0096", "index": 180, "guid": "cbae5cc4-1b07-406e-a60b-ddf140c50d6d", "isActive": true, "balance": "$3,085.83", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "brown", "name": "Leanne Bird", "gender": "female", "company": "COLAIRE", "email": "leannebird@colaire.com", "phone": "+1 (989) 445-3871", "address": "520 Midwood Street, Foxworth, Maine, 9857", "about": "Dolor ea labore ex sunt incididunt id enim ad. Dolore officia commodo occaecat ad laboris occaecat. Enim occaecat nisi ex esse consectetur elit cupidatat occaecat quis id pariatur consectetur. Officia cupidatat amet proident elit. Quis incididunt reprehenderit sunt excepteur magna anim ad laborum Lorem ex quis. Irure ipsum nisi laborum sit aliquip adipisicing qui nostrud tempor ullamco. Enim exercitation duis commodo sit id culpa voluptate elit ea deserunt pariatur proident aliquip.\r\n", "registered": "2016-03-31T08:37:27 -02:00", "latitude": 28.411504, "longitude": 68.951207, "tags": [ "exercitation", "ullamco", "nostrud", "in", "cupidatat", "velit", "commodo", "esse", "aute", "non" ], "friends": [ { "id": 0, "name": "Greer Humphrey" }, { "id": 1, "name": "Jacquelyn Bray" }, { "id": 2, "name": "Zelma Moody" }, { "id": 3, "name": "Flora Hatfield" }, { "id": 4, "name": "Hinton Clayton" } ], "greeting": "Hello, Leanne Bird! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826581a07980062b828", "index": 181, "guid": "059334b9-b6cb-4942-a473-016025b90d56", "isActive": false, "balance": "$2,672.78", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "brown", "name": "Alisha Mcbride", "gender": "female", "company": "ZILLACOM", "email": "alishamcbride@zillacom.com", "phone": "+1 (824) 444-3469", "address": "577 Rockwell Place, Harviell, New Jersey, 2972", "about": "Minim aute adipisicing nulla do do laborum do amet est nisi eu laboris proident nostrud. Proident deserunt cillum ullamco laborum ex. Ullamco anim est aliquip laborum.\r\n", "registered": "2014-05-04T07:20:50 -02:00", "latitude": -32.557688, "longitude": 40.416914, "tags": [ "excepteur", "ullamco", "eu", "nulla", "dolore", "officia", "officia", "irure", "magna", "pariatur" ], "friends": [ { "id": 0, "name": "Edith Barlow" }, { "id": 1, "name": "Michelle Mcgowan" }, { "id": 2, "name": "Wynn Hancock" }, { "id": 3, "name": "Dawn Preston" }, { "id": 4, "name": "Rhea Marks" } ], "greeting": "Hello, Alisha Mcbride! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482661978ebd4d1d4952", "index": 182, "guid": "2bd1147b-8797-4f27-9479-f1f86fde7299", "isActive": true, "balance": "$3,122.47", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Bryan Carson", "gender": "male", "company": "PROTODYNE", "email": "bryancarson@protodyne.com", "phone": "+1 (833) 537-2307", "address": "890 Suydam Street, Axis, Michigan, 9356", "about": "Voluptate excepteur eu veniam eiusmod do eu mollit aliqua. Consectetur proident esse in ad dolore cupidatat anim irure. Nisi laboris cillum sit dolore in non exercitation excepteur consequat veniam cupidatat enim esse laboris. Consequat cupidatat magna excepteur incididunt ea laboris irure mollit et dolore deserunt. Adipisicing deserunt non culpa eiusmod. Eiusmod culpa incididunt eiusmod qui dolore ullamco non reprehenderit.\r\n", "registered": "2017-10-05T08:23:44 -02:00", "latitude": 50.313643, "longitude": 86.558818, "tags": [ "eu", "excepteur", "deserunt", "officia", "velit", "ut", "et", "mollit", "eiusmod", "dolor" ], "friends": [ { "id": 0, "name": "Summers Quinn" }, { "id": 1, "name": "Melinda Warren" }, { "id": 2, "name": "Noble Copeland" }, { "id": 3, "name": "Beulah Buchanan" }, { "id": 4, "name": "Bentley Roberts" } ], "greeting": "Hello, Bryan Carson! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48266c027b45dc8bd5cd", "index": 183, "guid": "75d53c99-4188-436b-b5bd-5693e70dbc4b", "isActive": false, "balance": "$1,187.78", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "blue", "name": "Donaldson Clements", "gender": "male", "company": "ANOCHA", "email": "donaldsonclements@anocha.com", "phone": "+1 (811) 444-2106", "address": "134 Monroe Place, Aurora, Rhode Island, 1211", "about": "Et magna magna dolore consectetur id et et. Qui minim ex dolor sit pariatur sint est ad id qui ipsum voluptate cillum. Nostrud nisi consectetur Lorem occaecat dolor minim adipisicing irure proident do occaecat. Proident ut velit culpa Lorem ad ut ullamco ad ipsum proident consectetur sit sunt. Commodo ut pariatur commodo consequat adipisicing id officia minim laborum.\r\n", "registered": "2014-03-28T06:55:00 -01:00", "latitude": 86.689543, "longitude": -167.623081, "tags": [ "amet", "voluptate", "pariatur", "velit", "minim", "laboris", "ipsum", "magna", "enim", "dolore" ], "friends": [ { "id": 0, "name": "Stark Figueroa" }, { "id": 1, "name": "Reyes Weaver" }, { "id": 2, "name": "Kathleen Rasmussen" }, { "id": 3, "name": "Dunn Hoffman" }, { "id": 4, "name": "Howell Scott" } ], "greeting": "Hello, Donaldson Clements! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826640069703f35790b", "index": 184, "guid": "3c5a29cf-ab16-4847-a03b-85d1aa99122e", "isActive": false, "balance": "$1,318.97", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Fletcher Raymond", "gender": "male", "company": "JOVIOLD", "email": "fletcherraymond@joviold.com", "phone": "+1 (827) 564-3527", "address": "940 Farragut Place, Sunnyside, Kansas, 7773", "about": "Minim id fugiat exercitation pariatur sit incididunt fugiat. Quis nisi officia nulla culpa consequat cillum ad et aliqua qui tempor laboris labore. Est ad et eiusmod velit adipisicing et reprehenderit eiusmod aute mollit. Consectetur ad proident fugiat do duis id irure sit ipsum est irure dolor dolor.\r\n", "registered": "2016-05-26T12:46:42 -02:00", "latitude": -62.104553, "longitude": 167.716359, "tags": [ "sint", "est", "elit", "sint", "excepteur", "magna", "non", "duis", "velit", "cupidatat" ], "friends": [ { "id": 0, "name": "Ellen Atkins" }, { "id": 1, "name": "Willie Dickson" }, { "id": 2, "name": "Hurst Mcguire" }, { "id": 3, "name": "Chasity Osborn" }, { "id": 4, "name": "Hayden Fields" } ], "greeting": "Hello, Fletcher Raymond! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826808cb16bfb9ea80f", "index": 185, "guid": "1e7636dc-56f4-405d-a336-03f5d2772f2f", "isActive": true, "balance": "$1,850.30", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "blue", "name": "Vicky Dillard", "gender": "female", "company": "COMTENT", "email": "vickydillard@comtent.com", "phone": "+1 (895) 429-3179", "address": "497 Sutton Street, Inkerman, West Virginia, 7544", "about": "Lorem magna aliquip duis eiusmod in nisi ex anim nisi sit veniam. Sint duis elit tempor culpa elit sint labore amet. Dolore qui occaecat adipisicing nulla aliqua dolor et consectetur ipsum magna nulla voluptate ut. Ullamco ad nostrud tempor anim duis id do do. Esse incididunt ipsum excepteur culpa pariatur nulla fugiat labore tempor voluptate. Aliquip in veniam reprehenderit elit voluptate.\r\n", "registered": "2017-12-17T10:30:56 -01:00", "latitude": -9.441344, "longitude": -162.024333, "tags": [ "ad", "cillum", "deserunt", "sint", "adipisicing", "minim", "esse", "irure", "in", "voluptate" ], "friends": [ { "id": 0, "name": "Diane Jarvis" }, { "id": 1, "name": "Johnnie Hubbard" }, { "id": 2, "name": "Morrow Elliott" }, { "id": 3, "name": "Beatriz Davidson" }, { "id": 4, "name": "Gail Cole" } ], "greeting": "Hello, Vicky Dillard! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826a73248a20d0369b1", "index": 186, "guid": "f34a1495-1846-46bb-8669-958b21b121cc", "isActive": false, "balance": "$2,354.66", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "blue", "name": "Lourdes William", "gender": "female", "company": "ESCHOIR", "email": "lourdeswilliam@eschoir.com", "phone": "+1 (996) 575-3643", "address": "129 Halleck Street, Roy, American Samoa, 6737", "about": "Incididunt ullamco consectetur aliqua minim velit consequat in officia velit cillum ut. Qui fugiat cupidatat adipisicing ut consectetur sunt occaecat esse do aliqua elit anim. Voluptate velit laboris ad non Lorem reprehenderit culpa nostrud labore nostrud. Irure deserunt do laborum sit pariatur ipsum laborum mollit nisi. Est pariatur exercitation id esse duis aliquip do cupidatat anim id eu laboris cillum. Ad magna ea culpa esse ipsum aliqua commodo exercitation ipsum est et.\r\n", "registered": "2014-10-21T03:43:04 -02:00", "latitude": -66.998229, "longitude": -35.803607, "tags": [ "adipisicing", "sint", "excepteur", "labore", "cupidatat", "ullamco", "fugiat", "nostrud", "exercitation", "laboris" ], "friends": [ { "id": 0, "name": "Sybil Pollard" }, { "id": 1, "name": "Amparo Green" }, { "id": 2, "name": "Johnston Hampton" }, { "id": 3, "name": "Miranda Abbott" }, { "id": 4, "name": "Horn Campos" } ], "greeting": "Hello, Lourdes William! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c931784091c35fb4", "index": 187, "guid": "33158ee1-824f-4951-abd8-8726e6d1f7b7", "isActive": true, "balance": "$2,347.61", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "brown", "name": "Sweet Pickett", "gender": "male", "company": "PARLEYNET", "email": "sweetpickett@parleynet.com", "phone": "+1 (947) 487-2280", "address": "491 Baughman Place, Ahwahnee, Maryland, 3903", "about": "Dolore nisi fugiat et ipsum sit enim ea minim. Est proident pariatur laborum nisi incididunt occaecat cupidatat cupidatat voluptate do nostrud et fugiat. Aute cillum eu aliquip commodo esse sint. Nulla sit duis deserunt reprehenderit ullamco est. Proident tempor laboris id enim aliqua duis minim.\r\n", "registered": "2016-10-27T05:10:10 -02:00", "latitude": 48.936595, "longitude": -94.224361, "tags": [ "id", "enim", "nulla", "anim", "exercitation", "do", "eiusmod", "pariatur", "ex", "ea" ], "friends": [ { "id": 0, "name": "Aurelia Ingram" }, { "id": 1, "name": "Josephine Howell" }, { "id": 2, "name": "Lorene Greene" }, { "id": 3, "name": "Horne Christensen" }, { "id": 4, "name": "Erickson Miles" } ], "greeting": "Hello, Sweet Pickett! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48261b13f00e45f02593", "index": 188, "guid": "60add9d6-ef57-4132-a2b5-7467154b05e8", "isActive": true, "balance": "$3,346.32", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "blue", "name": "Trina Holden", "gender": "female", "company": "FRENEX", "email": "trinaholden@frenex.com", "phone": "+1 (829) 505-3970", "address": "947 Colonial Road, Dorneyville, California, 4261", "about": "Magna dolor occaecat proident culpa sint nulla cupidatat duis non consectetur qui commodo sunt sunt. Ex ut proident qui ipsum magna incididunt. Deserunt non eiusmod ut elit anim culpa incididunt. In laborum aliqua cillum sint aute deserunt Lorem officia et. In eiusmod excepteur dolore pariatur consequat ipsum ex esse ad fugiat. Ut veniam enim ipsum voluptate.\r\n", "registered": "2017-03-22T05:56:58 -01:00", "latitude": 37.07953, "longitude": 146.002507, "tags": [ "consequat", "voluptate", "cillum", "aliqua", "commodo", "sit", "duis", "sint", "magna", "commodo" ], "friends": [ { "id": 0, "name": "Clayton Newton" }, { "id": 1, "name": "Herrera Bowen" }, { "id": 2, "name": "Isabel Griffith" }, { "id": 3, "name": "Morgan Martin" }, { "id": 4, "name": "Hull Glass" } ], "greeting": "Hello, Trina Holden! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826eb91a4c38ca5684c", "index": 189, "guid": "1fbfd5c9-b6e2-4cc3-9d5b-cbbf25a86fa9", "isActive": false, "balance": "$2,382.59", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Erna Barker", "gender": "female", "company": "ORGANICA", "email": "ernabarker@organica.com", "phone": "+1 (932) 558-3490", "address": "320 Rogers Avenue, Gardners, Utah, 557", "about": "Mollit pariatur velit aute ut pariatur magna. Ipsum veniam duis exercitation sunt aliqua et aliquip quis velit magna laboris. Esse est officia consectetur nisi est nostrud enim id elit sint sit ea reprehenderit in. Velit anim sunt excepteur aute eiusmod cillum amet sint consectetur amet labore non velit. Fugiat cupidatat nisi occaecat eiusmod cillum voluptate irure esse. Occaecat nulla deserunt culpa non commodo cillum cillum nulla. Mollit non est anim officia occaecat cupidatat.\r\n", "registered": "2016-07-09T04:15:10 -02:00", "latitude": 8.302319, "longitude": 44.935764, "tags": [ "cillum", "officia", "id", "excepteur", "do", "id", "exercitation", "ut", "anim", "adipisicing" ], "friends": [ { "id": 0, "name": "Christensen Torres" }, { "id": 1, "name": "Randall Beasley" }, { "id": 2, "name": "Sanders Roman" }, { "id": 3, "name": "Elvira Powell" }, { "id": 4, "name": "Kasey Booker" } ], "greeting": "Hello, Erna Barker! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826f4b11aaf3ca482d9", "index": 190, "guid": "11b8b185-3030-490a-9954-3d6dbd3d1a7f", "isActive": false, "balance": "$2,648.49", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Alana Garcia", "gender": "female", "company": "MIXERS", "email": "alanagarcia@mixers.com", "phone": "+1 (897) 410-2471", "address": "549 Autumn Avenue, Wyano, Iowa, 128", "about": "Qui fugiat excepteur nisi amet ad id proident amet. Pariatur cupidatat veniam voluptate aliquip consectetur ipsum. Elit veniam sit incididunt mollit quis esse pariatur.\r\n", "registered": "2016-01-10T12:53:40 -01:00", "latitude": -77.684035, "longitude": 107.193077, "tags": [ "dolor", "voluptate", "magna", "adipisicing", "veniam", "eiusmod", "irure", "voluptate", "et", "anim" ], "friends": [ { "id": 0, "name": "Alison Grant" }, { "id": 1, "name": "Allison Wilkinson" }, { "id": 2, "name": "Williamson Delaney" }, { "id": 3, "name": "Yvonne Logan" }, { "id": 4, "name": "Ortega Reid" } ], "greeting": "Hello, Alana Garcia! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c2a14017a511d4a4", "index": 191, "guid": "165a51a9-46df-4bda-bd53-edff71e55de6", "isActive": true, "balance": "$3,813.97", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Miranda Kinney", "gender": "female", "company": "WRAPTURE", "email": "mirandakinney@wrapture.com", "phone": "+1 (935) 569-3655", "address": "279 Buffalo Avenue, Epworth, North Dakota, 9465", "about": "Aliqua sint consectetur sint sint irure voluptate ad proident officia. Nisi ullamco duis nisi veniam. Culpa aliqua exercitation aliquip exercitation exercitation proident eiusmod consequat amet deserunt excepteur laboris incididunt tempor. Irure proident mollit dolore adipisicing et cillum aute velit do proident ullamco occaecat qui. Dolore id consequat fugiat veniam occaecat pariatur eiusmod ea voluptate aliqua incididunt proident officia. Esse elit ullamco qui officia culpa nulla.\r\n", "registered": "2017-06-15T03:18:12 -02:00", "latitude": 53.817162, "longitude": 90.218012, "tags": [ "ea", "consectetur", "est", "non", "irure", "pariatur", "dolore", "enim", "sunt", "nisi" ], "friends": [ { "id": 0, "name": "Stacy Graves" }, { "id": 1, "name": "Odonnell Berry" }, { "id": 2, "name": "Slater Ramsey" }, { "id": 3, "name": "Harvey Richmond" }, { "id": 4, "name": "Maddox Kline" } ], "greeting": "Hello, Miranda Kinney! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48263b963fc98dacfd6d", "index": 192, "guid": "2e3061fe-93af-4800-add6-5019b9190589", "isActive": false, "balance": "$3,209.13", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Hannah Peterson", "gender": "female", "company": "EZENTIA", "email": "hannahpeterson@ezentia.com", "phone": "+1 (841) 578-2814", "address": "425 Forbell Street, Falconaire, Kentucky, 8074", "about": "Eu est esse Lorem ipsum aute non labore qui id ad exercitation deserunt. Velit nulla nostrud laboris velit laboris excepteur aliqua laborum ea aliquip incididunt minim. Occaecat ad adipisicing nisi commodo labore. Incididunt excepteur duis deserunt officia laborum enim consequat in in.\r\n", "registered": "2016-08-31T03:51:32 -02:00", "latitude": 38.71838, "longitude": 136.115527, "tags": [ "cupidatat", "ex", "id", "cillum", "reprehenderit", "enim", "consectetur", "culpa", "enim", "anim" ], "friends": [ { "id": 0, "name": "Gross Bentley" }, { "id": 1, "name": "Glass Wagner" }, { "id": 2, "name": "Elsie Shepard" }, { "id": 3, "name": "Carlene Merrill" }, { "id": 4, "name": "Kidd Armstrong" } ], "greeting": "Hello, Hannah Peterson! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826a5c7d12e767f5520", "index": 193, "guid": "9fae09ad-ec56-4009-8450-093e5fc5f705", "isActive": true, "balance": "$3,776.17", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Victoria Shepherd", "gender": "female", "company": "ZILLA", "email": "victoriashepherd@zilla.com", "phone": "+1 (837) 544-3744", "address": "976 Dobbin Street, Gracey, Colorado, 9555", "about": "Do veniam labore velit fugiat dolor id elit aliqua id fugiat cupidatat. Ea anim laborum sunt consectetur ea dolore et exercitation Lorem id ut quis anim elit. Est cillum veniam veniam sunt sint cillum est sit incididunt et. Qui officia dolor consequat sunt reprehenderit anim qui laborum adipisicing. Ea tempor pariatur ut consequat do duis laboris do.\r\n", "registered": "2015-02-08T10:26:14 -01:00", "latitude": -52.626951, "longitude": -152.595276, "tags": [ "cillum", "sit", "pariatur", "aliquip", "enim", "elit", "sit", "nulla", "dolor", "duis" ], "friends": [ { "id": 0, "name": "Flynn Spence" }, { "id": 1, "name": "Bradley Conrad" }, { "id": 2, "name": "Fields Wolf" }, { "id": 3, "name": "Edwards Myers" }, { "id": 4, "name": "Phillips Bullock" } ], "greeting": "Hello, Victoria Shepherd! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48264faa4217bc8b5fbf", "index": 194, "guid": "8d817c9c-3937-4670-950e-88dff4643094", "isActive": false, "balance": "$2,063.53", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "green", "name": "Ollie Navarro", "gender": "female", "company": "GEEKUS", "email": "ollienavarro@geekus.com", "phone": "+1 (956) 405-2993", "address": "472 Boynton Place, Taycheedah, New Hampshire, 9330", "about": "Duis proident ullamco eiusmod non in ad magna incididunt. Commodo laborum pariatur elit aliquip elit aute quis mollit. Id commodo amet sit labore voluptate ea deserunt laborum do. Sunt minim officia cupidatat occaecat enim veniam officia laborum irure sunt exercitation. Velit deserunt ullamco tempor do enim qui consectetur exercitation aliquip labore consequat ex in reprehenderit.\r\n", "registered": "2014-05-20T12:13:24 -02:00", "latitude": 22.744389, "longitude": 38.366197, "tags": [ "ullamco", "deserunt", "sunt", "commodo", "irure", "quis", "consectetur", "pariatur", "qui", "velit" ], "friends": [ { "id": 0, "name": "Rachel Haynes" }, { "id": 1, "name": "Luna Benson" }, { "id": 2, "name": "Luz Stuart" }, { "id": 3, "name": "Antonia Sweet" }, { "id": 4, "name": "Shauna Watts" } ], "greeting": "Hello, Ollie Navarro! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48263d1e8744d2bb5f2c", "index": 195, "guid": "3e1ac5f0-2a2e-4742-95b0-41a378ef05b9", "isActive": true, "balance": "$1,263.15", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "blue", "name": "Audra Sims", "gender": "female", "company": "LOCAZONE", "email": "audrasims@locazone.com", "phone": "+1 (856) 549-2026", "address": "906 Herkimer Street, Cowiche, Wisconsin, 5162", "about": "In ullamco nostrud aliquip ullamco nostrud id consequat. Fugiat Lorem culpa ut sit magna do voluptate cupidatat. Aliquip anim elit irure minim labore enim sunt. Duis occaecat aute aliqua duis aliquip nostrud qui ipsum proident magna consectetur est pariatur pariatur. Do commodo aute ullamco et ullamco id duis.\r\n", "registered": "2015-01-07T05:08:41 -01:00", "latitude": -3.678521, "longitude": -39.464142, "tags": [ "nulla", "nulla", "enim", "non", "quis", "laborum", "laborum", "amet", "exercitation", "aute" ], "friends": [ { "id": 0, "name": "Terrell Hernandez" }, { "id": 1, "name": "Antoinette Knox" }, { "id": 2, "name": "Nannie Norris" }, { "id": 3, "name": "Leila Cotton" }, { "id": 4, "name": "Bridgette Guzman" } ], "greeting": "Hello, Audra Sims! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826d2505f0fa18d98fa", "index": 196, "guid": "88849482-8aa9-4a60-abce-57ade1fa71f2", "isActive": false, "balance": "$1,528.35", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "green", "name": "Mcbride Ferrell", "gender": "male", "company": "OPTICON", "email": "mcbrideferrell@opticon.com", "phone": "+1 (841) 595-3826", "address": "951 Falmouth Street, Tioga, Idaho, 447", "about": "Culpa consequat do occaecat incididunt magna Lorem pariatur laborum cupidatat non sit duis pariatur. Fugiat elit sint deserunt amet proident deserunt officia. Aliqua velit enim sunt exercitation esse proident aute tempor irure qui Lorem adipisicing labore. Lorem labore duis quis laboris enim quis laborum ea occaecat deserunt mollit. Sunt sint aliqua culpa aliquip magna Lorem voluptate sunt ut exercitation minim adipisicing. Ad aliquip cillum elit sint. Incididunt id enim irure duis sit commodo qui dolore labore ipsum.\r\n", "registered": "2014-12-08T02:22:12 -01:00", "latitude": 87.661271, "longitude": -0.563684, "tags": [ "eiusmod", "aliqua", "aliquip", "duis", "consequat", "culpa", "enim", "nostrud", "consequat", "proident" ], "friends": [ { "id": 0, "name": "Katharine Nichols" }, { "id": 1, "name": "Stone Flores" }, { "id": 2, "name": "Keller Cabrera" }, { "id": 3, "name": "Smith Hunter" }, { "id": 4, "name": "Amie Hanson" } ], "greeting": "Hello, Mcbride Ferrell! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48261d9a4375b8b74d21", "index": 197, "guid": "eee3d176-2892-4419-b288-a72b16ef822e", "isActive": true, "balance": "$3,539.50", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "blue", "name": "Hart Stevenson", "gender": "male", "company": "BOINK", "email": "hartstevenson@boink.com", "phone": "+1 (902) 579-2226", "address": "500 Herbert Street, Mahtowa, Georgia, 8316", "about": "Non id minim duis voluptate cillum dolor nulla et ex sint laboris sit cillum ullamco. Nisi qui aliquip irure Lorem ex ea nostrud anim. Cillum Lorem sit magna anim veniam anim qui non ex Lorem deserunt elit.\r\n", "registered": "2014-05-07T01:26:23 -02:00", "latitude": 7.818408, "longitude": 44.009419, "tags": [ "anim", "nisi", "eu", "amet", "aliquip", "eiusmod", "ut", "occaecat", "cupidatat", "incididunt" ], "friends": [ { "id": 0, "name": "Larsen Lowe" }, { "id": 1, "name": "West Wise" }, { "id": 2, "name": "Ray Conner" }, { "id": 3, "name": "Charity Mcdowell" }, { "id": 4, "name": "Alberta Middleton" } ], "greeting": "Hello, Hart Stevenson! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48265c25ff740f66896e", "index": 198, "guid": "687d2658-5658-4352-b365-6ac591a660cf", "isActive": false, "balance": "$2,331.31", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "brown", "name": "English Guthrie", "gender": "male", "company": "PHOTOBIN", "email": "englishguthrie@photobin.com", "phone": "+1 (956) 427-2037", "address": "755 Grand Avenue, Urie, Virgin Islands, 9758", "about": "Incididunt ea aliquip velit consequat ullamco cupidatat ipsum qui pariatur sit duis nisi anim. Nisi aliqua excepteur Lorem dolor deserunt minim elit est sunt esse occaecat qui. Cillum cupidatat deserunt minim et voluptate.\r\n", "registered": "2014-09-29T08:05:36 -02:00", "latitude": 10.695649, "longitude": -145.509917, "tags": [ "enim", "exercitation", "elit", "aliquip", "do", "in", "commodo", "consectetur", "Lorem", "sint" ], "friends": [ { "id": 0, "name": "Mccormick Chandler" }, { "id": 1, "name": "Billie Mclaughlin" }, { "id": 2, "name": "Janie Lucas" }, { "id": 3, "name": "Barry Page" }, { "id": 4, "name": "Bryant Butler" } ], "greeting": "Hello, English Guthrie! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482678698e2c3c406999", "index": 199, "guid": "de7214ab-7318-4fe2-ad8b-cda7b20234b6", "isActive": false, "balance": "$1,242.35", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "blue", "name": "Hansen Prince", "gender": "male", "company": "TERAPRENE", "email": "hansenprince@teraprene.com", "phone": "+1 (918) 511-3603", "address": "658 Taylor Street, Morningside, Minnesota, 5432", "about": "Et Lorem dolor fugiat ad occaecat laborum qui mollit reprehenderit labore aliqua ad sit consequat. Anim voluptate eiusmod enim enim commodo mollit ex. Pariatur sit incididunt labore qui officia labore. Labore ullamco velit sunt ut ipsum magna laborum eu ad. Excepteur sint et incididunt est ex aliquip sint et exercitation tempor. Et quis veniam eiusmod ullamco.\r\n", "registered": "2016-10-17T09:03:45 -02:00", "latitude": -10.297501, "longitude": -36.394306, "tags": [ "irure", "consectetur", "do", "ipsum", "eu", "amet", "cupidatat", "Lorem", "voluptate", "Lorem" ], "friends": [ { "id": 0, "name": "Tyson Jordan" }, { "id": 1, "name": "Elma Morton" }, { "id": 2, "name": "Alice Hobbs" }, { "id": 3, "name": "Hess Deleon" }, { "id": 4, "name": "Lucy Perkins" } ], "greeting": "Hello, Hansen Prince! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48263077404d7894475d", "index": 200, "guid": "912c83b0-8e58-45df-b3d2-a386220abd38", "isActive": true, "balance": "$1,061.92", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "blue", "name": "Todd Kemp", "gender": "male", "company": "DOGSPA", "email": "toddkemp@dogspa.com", "phone": "+1 (922) 479-3060", "address": "478 Townsend Street, Nogal, South Carolina, 3894", "about": "Commodo commodo culpa ut labore laborum irure enim magna magna cupidatat. Amet voluptate exercitation consequat eiusmod elit et quis reprehenderit id amet exercitation ullamco ad. In eu officia adipisicing non nostrud aliquip non non Lorem eiusmod velit. Esse dolore enim ad in aute eu pariatur id do culpa ea qui proident ullamco. Eu reprehenderit amet anim enim do laborum cillum labore nisi ipsum eiusmod exercitation non est.\r\n", "registered": "2017-06-11T02:56:23 -02:00", "latitude": -52.359741, "longitude": 136.183844, "tags": [ "exercitation", "voluptate", "ipsum", "ullamco", "adipisicing", "quis", "elit", "ex", "tempor", "anim" ], "friends": [ { "id": 0, "name": "Murray Hogan" }, { "id": 1, "name": "Christa Webster" }, { "id": 2, "name": "Byers Hunt" }, { "id": 3, "name": "Wendi Emerson" }, { "id": 4, "name": "Merrill Mcleod" } ], "greeting": "Hello, Todd Kemp! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261275de475f9300aa", "index": 201, "guid": "2ec0cdd6-4318-4971-84f6-318cd969d0e1", "isActive": false, "balance": "$2,627.03", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Reese Hughes", "gender": "male", "company": "NUTRALAB", "email": "reesehughes@nutralab.com", "phone": "+1 (884) 548-3138", "address": "417 Manhattan Avenue, Snowville, Northern Mariana Islands, 621", "about": "Reprehenderit velit exercitation sint nisi fugiat nostrud velit incididunt veniam ea. Nisi excepteur cupidatat mollit sint nisi fugiat est nisi. Qui Lorem ullamco reprehenderit irure consectetur reprehenderit voluptate voluptate irure sunt deserunt non ea. Laborum irure aliqua non laborum labore amet.\r\n", "registered": "2014-01-23T06:34:52 -01:00", "latitude": 71.05646, "longitude": 30.5427, "tags": [ "consectetur", "veniam", "ipsum", "nostrud", "do", "sit", "esse", "aliquip", "ut", "anim" ], "friends": [ { "id": 0, "name": "Emerson Haley" }, { "id": 1, "name": "Moore Lyons" }, { "id": 2, "name": "Walsh Walton" }, { "id": 3, "name": "Baxter Guy" }, { "id": 4, "name": "Sheena Irwin" } ], "greeting": "Hello, Reese Hughes! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826538f6907a9ae22c7", "index": 202, "guid": "8d293169-fb6e-4d5c-bcc8-79a99cf90d14", "isActive": false, "balance": "$3,696.04", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Johns Herring", "gender": "male", "company": "SLAX", "email": "johnsherring@slax.com", "phone": "+1 (887) 597-3037", "address": "909 Caton Place, Barronett, Pennsylvania, 9535", "about": "Ex minim ullamco commodo enim ut magna irure. Officia do tempor est reprehenderit tempor ut fugiat aliquip minim id. Irure irure nulla deserunt voluptate minim sunt id. Ullamco ipsum aliqua ea occaecat elit ullamco occaecat anim veniam id qui. Aliqua nisi nulla excepteur fugiat aliqua nulla amet duis. Ex enim consectetur tempor anim anim.\r\n", "registered": "2015-12-12T12:40:38 -01:00", "latitude": 20.536577, "longitude": 85.72109, "tags": [ "laboris", "esse", "minim", "aliqua", "eu", "proident", "magna", "minim", "pariatur", "occaecat" ], "friends": [ { "id": 0, "name": "May Solis" }, { "id": 1, "name": "Ruth Fuller" }, { "id": 2, "name": "Teresa Bruce" }, { "id": 3, "name": "Autumn Benton" }, { "id": 4, "name": "Lopez Oneal" } ], "greeting": "Hello, Johns Herring! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482644b6b348c5127d58", "index": 203, "guid": "01ceb17c-df16-4aa3-a7b3-360bf31f3974", "isActive": false, "balance": "$3,796.76", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Nielsen Hess", "gender": "male", "company": "COMTRACT", "email": "nielsenhess@comtract.com", "phone": "+1 (877) 412-2321", "address": "508 Fanchon Place, Bowmansville, Arkansas, 1585", "about": "Excepteur labore consequat ut qui nisi anim mollit. Do proident occaecat eiusmod magna sunt in exercitation ut irure minim laborum. Amet veniam pariatur magna aliquip consequat eiusmod adipisicing proident nulla id anim excepteur ut nisi.\r\n", "registered": "2014-02-20T06:40:12 -01:00", "latitude": 83.306776, "longitude": -41.608546, "tags": [ "exercitation", "nulla", "quis", "id", "sint", "nulla", "mollit", "Lorem", "ut", "duis" ], "friends": [ { "id": 0, "name": "Corrine Leach" }, { "id": 1, "name": "Tran Sargent" }, { "id": 2, "name": "Colon Leblanc" }, { "id": 3, "name": "Dejesus Jenkins" }, { "id": 4, "name": "Angela Gordon" } ], "greeting": "Hello, Nielsen Hess! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c5de0479d8a3d000", "index": 204, "guid": "8a389eca-c200-40a0-9418-67bbac985a0b", "isActive": true, "balance": "$3,162.41", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "brown", "name": "Klein Conley", "gender": "male", "company": "BULLZONE", "email": "kleinconley@bullzone.com", "phone": "+1 (867) 405-2688", "address": "226 Gardner Avenue, Brownsville, Palau, 2231", "about": "Consectetur mollit do minim incididunt eu mollit do. Consequat occaecat ad eu dolor quis nisi voluptate Lorem nulla Lorem nulla nostrud id culpa. Nisi ipsum ut dolor incididunt cillum. Deserunt occaecat ullamco mollit tempor ad ea laborum non dolor id officia sint. Commodo enim Lorem cillum mollit ut ut in duis adipisicing ad proident elit sint consequat. In Lorem aute ut laborum. Fugiat tempor in esse cillum aliquip cupidatat ipsum mollit laborum consequat irure cillum.\r\n", "registered": "2015-04-09T02:55:37 -02:00", "latitude": -65.980264, "longitude": -141.1294, "tags": [ "officia", "dolor", "laboris", "reprehenderit", "tempor", "anim", "duis", "et", "ut", "elit" ], "friends": [ { "id": 0, "name": "Sherri Rutledge" }, { "id": 1, "name": "Moody Baird" }, { "id": 2, "name": "Joy Finch" }, { "id": 3, "name": "Sharon Cruz" }, { "id": 4, "name": "Deena Bailey" } ], "greeting": "Hello, Klein Conley! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482686ddbfc126741457", "index": 205, "guid": "10bef9ba-9d70-4ae1-98c5-68736c9fd472", "isActive": false, "balance": "$2,952.67", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "blue", "name": "Hebert England", "gender": "male", "company": "ISOTERNIA", "email": "hebertengland@isoternia.com", "phone": "+1 (890) 528-3686", "address": "114 Denton Place, Nadine, Connecticut, 9721", "about": "Laborum fugiat sunt voluptate in fugiat do qui. Occaecat qui eiusmod magna proident exercitation ea ex consectetur non. Anim magna est irure sunt dolore est mollit qui non et irure. Incididunt irure laborum minim id nisi duis. Ea eu est aliqua anim ullamco excepteur quis. Est ea aliquip minim officia. Culpa dolore incididunt fugiat ex ad pariatur ad.\r\n", "registered": "2016-11-28T05:08:58 -01:00", "latitude": 79.420139, "longitude": 18.505236, "tags": [ "id", "eu", "pariatur", "nulla", "reprehenderit", "proident", "reprehenderit", "sunt", "enim", "est" ], "friends": [ { "id": 0, "name": "Dina Gamble" }, { "id": 1, "name": "Warner Chambers" }, { "id": 2, "name": "Lorraine Castillo" }, { "id": 3, "name": "Cantrell Lowery" }, { "id": 4, "name": "Eddie Cross" } ], "greeting": "Hello, Hebert England! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48263ca8fe29f7333e36", "index": 206, "guid": "3011598a-f4e4-4792-ba25-1b8f828d1f1e", "isActive": false, "balance": "$1,546.10", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "blue", "name": "Oneill Santos", "gender": "male", "company": "INSURON", "email": "oneillsantos@insuron.com", "phone": "+1 (812) 549-3373", "address": "961 Canal Avenue, Linwood, North Carolina, 6988", "about": "Fugiat ipsum et irure velit irure. Pariatur velit ex aliqua magna labore aliquip laboris occaecat id aliquip incididunt cillum. Sint quis enim commodo veniam qui deserunt duis et ex do occaecat id mollit nisi. Occaecat consectetur ea commodo minim pariatur eu consectetur. Eiusmod mollit veniam mollit irure magna ad amet. Dolor dolore Lorem magna Lorem incididunt est enim commodo incididunt culpa irure commodo laboris proident. Qui laborum nisi reprehenderit commodo officia id eu consectetur veniam.\r\n", "registered": "2017-11-28T09:24:21 -01:00", "latitude": -55.515122, "longitude": -47.686256, "tags": [ "nisi", "ex", "Lorem", "voluptate", "ipsum", "sunt", "ut", "sit", "veniam", "voluptate" ], "friends": [ { "id": 0, "name": "Lesa Langley" }, { "id": 1, "name": "Faye Good" }, { "id": 2, "name": "Deidre Jimenez" }, { "id": 3, "name": "Schneider Fernandez" }, { "id": 4, "name": "Robin Parrish" } ], "greeting": "Hello, Oneill Santos! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48264664ba0d2bc365f6", "index": 207, "guid": "63fbec46-3f91-4d8f-9b42-2e52d5177f7d", "isActive": false, "balance": "$1,520.51", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "brown", "name": "Patton Avery", "gender": "male", "company": "ECRATIC", "email": "pattonavery@ecratic.com", "phone": "+1 (856) 555-2507", "address": "182 Oriental Boulevard, Hemlock, Missouri, 4813", "about": "Eiusmod amet sint dolor laboris dolore in esse. Laboris exercitation pariatur exercitation aliqua. Cillum est adipisicing laborum exercitation voluptate veniam elit ex est fugiat quis aliquip. Nisi fugiat culpa in velit id officia magna et voluptate proident ex aute.\r\n", "registered": "2017-10-21T12:52:01 -02:00", "latitude": 4.959484, "longitude": -36.785947, "tags": [ "labore", "veniam", "ipsum", "nisi", "labore", "non", "veniam", "laborum", "Lorem", "sint" ], "friends": [ { "id": 0, "name": "Shanna Hurst" }, { "id": 1, "name": "Leah Suarez" }, { "id": 2, "name": "Davenport Reeves" }, { "id": 3, "name": "Briggs Mclean" }, { "id": 4, "name": "Jean Guerrero" } ], "greeting": "Hello, Patton Avery! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48264e8fdc992c975339", "index": 208, "guid": "d343ba05-a773-4dd6-b0ce-fc6215691983", "isActive": false, "balance": "$3,574.30", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "blue", "name": "Margie Perry", "gender": "female", "company": "UNIA", "email": "margieperry@unia.com", "phone": "+1 (937) 424-3776", "address": "262 Kingston Avenue, Konterra, Ohio, 9615", "about": "Ut minim proident excepteur irure sunt dolore voluptate cupidatat. Elit labore tempor est tempor ipsum aliqua incididunt esse consequat sunt excepteur est. Non fugiat elit laboris cupidatat ex duis eu minim ea nisi veniam eu fugiat. Quis et velit pariatur tempor anim eiusmod. Adipisicing labore mollit et nostrud mollit nostrud. Anim voluptate commodo tempor reprehenderit adipisicing fugiat irure non exercitation enim mollit duis proident elit. Labore et et amet Lorem cupidatat.\r\n", "registered": "2015-08-25T10:53:33 -02:00", "latitude": 5.492186, "longitude": 55.126628, "tags": [ "sit", "duis", "adipisicing", "in", "exercitation", "dolor", "cupidatat", "nisi", "qui", "labore" ], "friends": [ { "id": 0, "name": "Lara Fulton" }, { "id": 1, "name": "Simon Harrell" }, { "id": 2, "name": "Bailey Odom" }, { "id": 3, "name": "Kramer Newman" }, { "id": 4, "name": "Flossie Cote" } ], "greeting": "Hello, Margie Perry! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ecc975e0e455b2fc", "index": 209, "guid": "bdee457d-6bac-44f6-a621-2e0411cc863c", "isActive": true, "balance": "$2,435.66", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Alyssa Yang", "gender": "female", "company": "PAWNAGRA", "email": "alyssayang@pawnagra.com", "phone": "+1 (901) 475-3224", "address": "209 Pitkin Avenue, Bayview, Arizona, 9377", "about": "Aliqua consectetur reprehenderit sit proident ipsum nisi nisi magna aliqua sit excepteur est. Ullamco qui aute consequat qui magna tempor laborum ut exercitation excepteur incididunt esse amet. Et do exercitation consectetur magna ut sit veniam qui id est laborum. Mollit mollit elit deserunt qui. Et est ad fugiat qui sit Lorem quis dolor et ad qui veniam. Est consectetur occaecat deserunt dolore id excepteur ad culpa aute sit. Magna ut proident consectetur minim elit Lorem incididunt aliquip enim.\r\n", "registered": "2017-01-31T01:54:14 -01:00", "latitude": -81.485182, "longitude": 93.752491, "tags": [ "veniam", "et", "sint", "reprehenderit", "ea", "exercitation", "aute", "esse", "eiusmod", "proident" ], "friends": [ { "id": 0, "name": "Carey Mayer" }, { "id": 1, "name": "Shelton Mendez" }, { "id": 2, "name": "Bernard Watson" }, { "id": 3, "name": "Kline Washington" }, { "id": 4, "name": "Alexis Lang" } ], "greeting": "Hello, Alyssa Yang! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826422c67123910dfcc", "index": 210, "guid": "872f542b-1a73-4f32-b335-fc3f5adf98b5", "isActive": true, "balance": "$1,324.95", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "green", "name": "Clay Cardenas", "gender": "male", "company": "FARMAGE", "email": "claycardenas@farmage.com", "phone": "+1 (894) 451-3680", "address": "191 Losee Terrace, Datil, Montana, 3195", "about": "Nulla exercitation irure adipisicing sit sint eu ex dolor do est magna dolor do cillum. Non veniam qui quis veniam ipsum. Eu occaecat occaecat eu dolor culpa fugiat culpa velit. Ut anim aliqua eiusmod veniam deserunt laboris nostrud voluptate reprehenderit sit ea qui laborum.\r\n", "registered": "2017-06-05T06:37:19 -02:00", "latitude": 33.836398, "longitude": -98.297281, "tags": [ "et", "veniam", "consequat", "qui", "laboris", "esse", "consectetur", "do", "et", "do" ], "friends": [ { "id": 0, "name": "Enid Wynn" }, { "id": 1, "name": "Nancy Golden" }, { "id": 2, "name": "Berg Cantu" }, { "id": 3, "name": "Marshall Morse" }, { "id": 4, "name": "Cross Luna" } ], "greeting": "Hello, Clay Cardenas! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c57f0a7ed936d24c", "index": 211, "guid": "f4a8731a-9283-4c54-91ff-2d05274784a2", "isActive": false, "balance": "$1,025.98", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Jacqueline Santiago", "gender": "female", "company": "TOURMANIA", "email": "jacquelinesantiago@tourmania.com", "phone": "+1 (926) 600-3669", "address": "531 Seigel Court, Islandia, Texas, 8315", "about": "Laborum reprehenderit cupidatat dolor irure aliqua elit nisi ipsum fugiat do reprehenderit nulla consectetur. Veniam aliqua adipisicing consequat nisi laborum sit magna eiusmod adipisicing aute est culpa. Laboris pariatur sunt incididunt laboris nostrud commodo aliquip ea officia. Eu id veniam et proident laborum proident elit elit ullamco Lorem dolor. Sunt voluptate laborum Lorem aliqua proident ut fugiat tempor minim. Labore in tempor ipsum reprehenderit dolore eu elit sunt nostrud. Culpa pariatur in aliquip anim magna elit anim aliqua deserunt ex esse aliquip.\r\n", "registered": "2017-02-03T06:42:59 -01:00", "latitude": 3.218815, "longitude": 97.180896, "tags": [ "aliquip", "aliquip", "duis", "ullamco", "consequat", "in", "nostrud", "cupidatat", "qui", "velit" ], "friends": [ { "id": 0, "name": "Mendoza Vinson" }, { "id": 1, "name": "Clements Salas" }, { "id": 2, "name": "Koch Mayo" }, { "id": 3, "name": "Christina Herman" }, { "id": 4, "name": "Molly Pena" } ], "greeting": "Hello, Jacqueline Santiago! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826d665853b7a4a9a45", "index": 212, "guid": "406e8f16-db93-4cbb-b25a-284f41af43fc", "isActive": false, "balance": "$1,129.47", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Consuelo Murray", "gender": "female", "company": "MAGNAFONE", "email": "consuelomurray@magnafone.com", "phone": "+1 (809) 460-2701", "address": "614 Ridge Boulevard, Allamuchy, Washington, 7604", "about": "Aliquip et aliqua nulla commodo in eu magna elit elit. Proident eu nulla excepteur excepteur est in labore enim Lorem. Deserunt deserunt et ea ipsum pariatur esse est dolore esse consectetur dolore nulla. Enim amet in eiusmod duis exercitation qui incididunt in culpa duis velit amet. Reprehenderit exercitation incididunt sit incididunt fugiat pariatur.\r\n", "registered": "2017-04-11T01:26:30 -02:00", "latitude": -47.369912, "longitude": 144.467513, "tags": [ "officia", "cillum", "enim", "ex", "nostrud", "in", "mollit", "minim", "dolore", "esse" ], "friends": [ { "id": 0, "name": "Aileen Thomas" }, { "id": 1, "name": "Ofelia Phelps" }, { "id": 2, "name": "Bird Wolfe" }, { "id": 3, "name": "Stacie Tanner" }, { "id": 4, "name": "Mcclain Turner" } ], "greeting": "Hello, Consuelo Murray! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48269f5314bc4bdfed91", "index": 213, "guid": "52fa26bf-7b21-46d3-b143-ed3b7a8c1b1a", "isActive": false, "balance": "$1,870.82", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "brown", "name": "Rebekah Horn", "gender": "female", "company": "APEXTRI", "email": "rebekahhorn@apextri.com", "phone": "+1 (934) 411-2662", "address": "636 Walker Court, Fairacres, Wyoming, 4612", "about": "Ea velit aute tempor culpa aute aliquip id. Do aliquip occaecat ullamco anim ullamco eu esse cillum Lorem. Cillum tempor elit labore ex pariatur tempor nostrud. Adipisicing laboris exercitation aute est nulla proident commodo cupidatat. Ad commodo adipisicing minim irure pariatur est laborum qui.\r\n", "registered": "2017-07-09T12:51:21 -02:00", "latitude": 26.391652, "longitude": -24.061785, "tags": [ "aliquip", "et", "tempor", "exercitation", "ullamco", "magna", "id", "sint", "qui", "eu" ], "friends": [ { "id": 0, "name": "Karen Mcclain" }, { "id": 1, "name": "Delgado Serrano" }, { "id": 2, "name": "Dianna Molina" }, { "id": 3, "name": "Gordon Mccarty" }, { "id": 4, "name": "Anna Workman" } ], "greeting": "Hello, Rebekah Horn! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826e1f79d44d4c3c442", "index": 214, "guid": "229d8a7e-fd10-4bd8-b3c9-6066dfbde806", "isActive": true, "balance": "$2,380.23", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "green", "name": "Leonard Ross", "gender": "male", "company": "RONELON", "email": "leonardross@ronelon.com", "phone": "+1 (909) 423-2944", "address": "600 Vanderbilt Avenue, Troy, Indiana, 3086", "about": "Dolor quis esse dolor laboris. Eiusmod pariatur dolore sint deserunt dolor consequat elit id est quis sint pariatur eu. Esse sit occaecat eu in pariatur nulla ad. Et ut ad deserunt amet mollit dolor sit. In duis ea officia pariatur Lorem minim occaecat id veniam non ut qui. Laborum pariatur ullamco veniam proident dolor ea eiusmod reprehenderit ipsum.\r\n", "registered": "2016-10-27T01:06:30 -02:00", "latitude": -44.521036, "longitude": 63.905257, "tags": [ "excepteur", "aliquip", "nisi", "consectetur", "pariatur", "enim", "nisi", "in", "et", "aliquip" ], "friends": [ { "id": 0, "name": "Josefa Ramos" }, { "id": 1, "name": "Ingrid Russell" }, { "id": 2, "name": "Rachael Cochran" }, { "id": 3, "name": "Celeste Taylor" }, { "id": 4, "name": "Dona Dale" } ], "greeting": "Hello, Leonard Ross! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48268235b18e49e5b0aa", "index": 215, "guid": "afb0b9ab-08ad-4e44-9d9e-cf0c58caff99", "isActive": false, "balance": "$2,710.15", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "blue", "name": "Villarreal Adkins", "gender": "male", "company": "VENDBLEND", "email": "villarrealadkins@vendblend.com", "phone": "+1 (955) 421-2036", "address": "749 Chestnut Street, Northridge, Alabama, 2915", "about": "Voluptate laborum proident dolore consectetur veniam pariatur. Lorem reprehenderit aliquip Lorem anim amet eiusmod veniam velit ut excepteur pariatur consectetur nisi ad. Minim minim sint eu sint nisi.\r\n", "registered": "2016-02-24T03:29:12 -01:00", "latitude": -3.689811, "longitude": -119.404103, "tags": [ "laborum", "minim", "commodo", "eiusmod", "id", "id", "consectetur", "eiusmod", "occaecat", "cupidatat" ], "friends": [ { "id": 0, "name": "Tameka Noel" }, { "id": 1, "name": "Walton Moran" }, { "id": 2, "name": "Haynes Byers" }, { "id": 3, "name": "Nona Houston" }, { "id": 4, "name": "Angelina Lindsey" } ], "greeting": "Hello, Villarreal Adkins! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48268207679aff371b11", "index": 216, "guid": "ade9231e-0ab7-452a-a698-54ec053c1046", "isActive": true, "balance": "$2,150.13", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Craig Dyer", "gender": "male", "company": "VIAGRAND", "email": "craigdyer@viagrand.com", "phone": "+1 (860) 525-2083", "address": "525 Furman Avenue, Bowie, Virginia, 2344", "about": "Incididunt tempor excepteur esse quis duis proident proident enim tempor eu. Et consectetur eiusmod irure dolor minim nulla. Consequat ea voluptate deserunt in magna ut eiusmod consectetur duis occaecat. Deserunt dolore non magna anim exercitation eu est tempor anim amet esse do exercitation adipisicing.\r\n", "registered": "2014-10-24T11:14:07 -02:00", "latitude": 14.215174, "longitude": 26.121827, "tags": [ "sint", "ea", "velit", "excepteur", "quis", "minim", "dolor", "id", "eu", "velit" ], "friends": [ { "id": 0, "name": "Lakeisha Shields" }, { "id": 1, "name": "Wilma Lancaster" }, { "id": 2, "name": "Mary Harrison" }, { "id": 3, "name": "Decker Sosa" }, { "id": 4, "name": "Stevenson Thompson" } ], "greeting": "Hello, Craig Dyer! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826968aa2a4129c7633", "index": 217, "guid": "109a6a14-841a-4b77-9304-44e83a62d4f6", "isActive": false, "balance": "$2,617.55", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "brown", "name": "Meyers Kidd", "gender": "male", "company": "ELITA", "email": "meyerskidd@elita.com", "phone": "+1 (891) 598-2803", "address": "447 Monaco Place, Idamay, New Mexico, 8904", "about": "Laboris ut aliquip in nisi in consequat. Et ullamco ullamco aliquip qui pariatur non sint id culpa in do culpa aliquip. Eiusmod anim eu enim ad quis elit non laborum elit est anim. Ad consequat proident ullamco in qui velit. Occaecat veniam aute fugiat sunt cillum. Tempor excepteur occaecat labore est non fugiat adipisicing laborum aliqua elit qui.\r\n", "registered": "2015-07-17T06:42:18 -02:00", "latitude": -70.603886, "longitude": 29.601197, "tags": [ "exercitation", "anim", "elit", "ad", "dolore", "enim", "culpa", "ad", "officia", "nulla" ], "friends": [ { "id": 0, "name": "Callahan Joyner" }, { "id": 1, "name": "Herring Ochoa" }, { "id": 2, "name": "Holman Vang" }, { "id": 3, "name": "Murphy Pate" }, { "id": 4, "name": "Guadalupe Webb" } ], "greeting": "Hello, Meyers Kidd! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482678960ab8cfbf63ed", "index": 218, "guid": "27624279-42f2-4d34-a29c-d38d82223ef1", "isActive": true, "balance": "$2,404.19", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "brown", "name": "Joann Mcneil", "gender": "female", "company": "CANDECOR", "email": "joannmcneil@candecor.com", "phone": "+1 (953) 505-3291", "address": "462 Roosevelt Court, Harrison, Hawaii, 469", "about": "Qui nisi incididunt officia do ad tempor. Dolore ad proident amet aliquip ullamco aliqua voluptate non dolor consequat laborum. Aliquip irure enim adipisicing adipisicing nisi irure incididunt fugiat duis quis proident cupidatat qui. Tempor laboris mollit do cupidatat laboris tempor ex mollit cillum. Sit do ad excepteur ex id est exercitation esse eu. Magna mollit cupidatat ad nisi incididunt ad proident ut eu velit deserunt aliqua.\r\n", "registered": "2015-03-10T08:06:27 -01:00", "latitude": 72.834241, "longitude": -3.04368, "tags": [ "quis", "nisi", "exercitation", "veniam", "ad", "consectetur", "cillum", "eu", "ex", "quis" ], "friends": [ { "id": 0, "name": "Velasquez Glenn" }, { "id": 1, "name": "Saunders Hyde" }, { "id": 2, "name": "Elba Hurley" }, { "id": 3, "name": "Liz Bartlett" }, { "id": 4, "name": "Muriel Boyd" } ], "greeting": "Hello, Joann Mcneil! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e2169a9346e358cd", "index": 219, "guid": "188b40fb-f951-4cf4-9341-15eddd5b81d5", "isActive": false, "balance": "$2,898.24", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "green", "name": "Leta Kent", "gender": "female", "company": "KRAG", "email": "letakent@krag.com", "phone": "+1 (825) 533-3996", "address": "479 Eldert Lane, Galesville, Nebraska, 8761", "about": "Culpa magna non ea reprehenderit pariatur nulla commodo excepteur nisi quis aliquip minim anim esse. Deserunt tempor consectetur laboris id id officia minim. Velit sint sunt Lorem ea cillum sunt non occaecat id anim ut quis fugiat sit. Voluptate minim veniam commodo anim eiusmod velit sunt Lorem anim consectetur duis id ipsum.\r\n", "registered": "2014-12-24T03:20:20 -01:00", "latitude": -82.599397, "longitude": 66.301295, "tags": [ "laborum", "esse", "aliquip", "ut", "deserunt", "magna", "et", "sunt", "culpa", "reprehenderit" ], "friends": [ { "id": 0, "name": "Elnora Gillespie" }, { "id": 1, "name": "Mcconnell Stafford" }, { "id": 2, "name": "Mcfarland Arnold" }, { "id": 3, "name": "Wooten Ballard" }, { "id": 4, "name": "Hahn Sweeney" } ], "greeting": "Hello, Leta Kent! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826bda27c02c47bdec9", "index": 220, "guid": "f51dde29-b05c-4b7d-920b-e7cf07d1e73c", "isActive": false, "balance": "$3,051.57", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Kirkland Wong", "gender": "male", "company": "SUSTENZA", "email": "kirklandwong@sustenza.com", "phone": "+1 (929) 556-3821", "address": "629 Noble Street, Elwood, New York, 8313", "about": "Magna ad nulla pariatur laborum dolore. Duis eu eu dolor aliqua nulla in. Aliqua aliquip ea sit magna. Eiusmod exercitation ea velit consectetur. Ipsum est aliqua reprehenderit veniam duis nisi do ipsum aute. Enim in eiusmod tempor dolore deserunt ad aliqua commodo occaecat. Consectetur veniam tempor incididunt ex.\r\n", "registered": "2014-07-19T12:04:51 -02:00", "latitude": -82.924266, "longitude": 103.019533, "tags": [ "aliqua", "ullamco", "consectetur", "aute", "elit", "duis", "officia", "ipsum", "duis", "nostrud" ], "friends": [ { "id": 0, "name": "Heidi Delacruz" }, { "id": 1, "name": "Blanca Singleton" }, { "id": 2, "name": "Mandy Mccall" }, { "id": 3, "name": "Bennett Charles" }, { "id": 4, "name": "Lawson Wilcox" } ], "greeting": "Hello, Kirkland Wong! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48261fd789fd580d16f3", "index": 221, "guid": "c25760e4-f3d0-47b4-9f7c-e46597235e46", "isActive": false, "balance": "$3,929.57", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Althea Dorsey", "gender": "female", "company": "GEOFORM", "email": "altheadorsey@geoform.com", "phone": "+1 (978) 525-2572", "address": "205 Division Place, Hall, Marshall Islands, 8004", "about": "Non nostrud laborum esse ullamco consequat cillum pariatur cupidatat ullamco reprehenderit duis ea laborum ullamco. Aliqua sint duis cupidatat veniam aliquip dolor officia eiusmod. Velit sint esse nulla id pariatur consectetur irure elit quis nulla sunt dolore. Amet fugiat eu aliqua velit ea Lorem labore consectetur id eiusmod sunt.\r\n", "registered": "2015-07-24T08:43:58 -02:00", "latitude": 19.467722, "longitude": -33.415675, "tags": [ "nostrud", "ut", "nostrud", "incididunt", "officia", "eu", "reprehenderit", "ex", "cupidatat", "pariatur" ], "friends": [ { "id": 0, "name": "Eunice Morgan" }, { "id": 1, "name": "Phyllis Gay" }, { "id": 2, "name": "Harriett Odonnell" }, { "id": 3, "name": "Hicks Lawson" }, { "id": 4, "name": "Patel Massey" } ], "greeting": "Hello, Althea Dorsey! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826925c8e71060ca58c", "index": 222, "guid": "3e0f001a-ae4f-446a-aca1-4f4e849c0252", "isActive": true, "balance": "$3,718.85", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "green", "name": "Lorena Holcomb", "gender": "female", "company": "DIGIRANG", "email": "lorenaholcomb@digirang.com", "phone": "+1 (928) 517-2918", "address": "496 Kensington Street, Elfrida, Oregon, 8364", "about": "Commodo culpa tempor deserunt deserunt. Exercitation sunt excepteur ullamco culpa velit aute adipisicing aliquip in quis eu reprehenderit commodo labore. Ut ad dolor ex ullamco velit do incididunt ipsum sit enim ullamco commodo sit. Ullamco eiusmod nisi cillum nostrud nulla fugiat tempor sint eu duis ad deserunt adipisicing. Occaecat reprehenderit qui ullamco nisi anim fugiat cillum ea voluptate.\r\n", "registered": "2015-06-11T11:01:04 -02:00", "latitude": 13.530065, "longitude": 170.315305, "tags": [ "ullamco", "proident", "nisi", "excepteur", "pariatur", "reprehenderit", "ipsum", "ipsum", "eu", "cillum" ], "friends": [ { "id": 0, "name": "Fuentes Brooks" }, { "id": 1, "name": "Bobbi Hendrix" }, { "id": 2, "name": "Harriet Barnes" }, { "id": 3, "name": "Powers Cortez" }, { "id": 4, "name": "Young Kelly" } ], "greeting": "Hello, Lorena Holcomb! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826dc09d0fad975ec97", "index": 223, "guid": "7159155f-8966-441c-b543-bdd38177ce2d", "isActive": false, "balance": "$2,645.02", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "blue", "name": "Wade Shaffer", "gender": "male", "company": "ASSISTIX", "email": "wadeshaffer@assistix.com", "phone": "+1 (833) 521-3063", "address": "864 Cumberland Walk, Nord, Tennessee, 1111", "about": "Sit pariatur duis aute aliquip. In esse mollit velit voluptate sint velit magna voluptate velit magna. In voluptate qui occaecat voluptate minim occaecat aliqua. Laborum ipsum irure ipsum labore esse ad cupidatat sunt. Exercitation eiusmod mollit nulla quis.\r\n", "registered": "2015-06-24T05:37:49 -02:00", "latitude": 12.121605, "longitude": 6.420793, "tags": [ "voluptate", "laborum", "Lorem", "dolore", "sit", "magna", "proident", "nulla", "in", "in" ], "friends": [ { "id": 0, "name": "Guerrero Walters" }, { "id": 1, "name": "Rae English" }, { "id": 2, "name": "Parrish Osborne" }, { "id": 3, "name": "Lynn Schultz" }, { "id": 4, "name": "Allison Sullivan" } ], "greeting": "Hello, Wade Shaffer! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826851be017f4be8744", "index": 224, "guid": "7f359313-01a2-42b8-a3af-db8ba6a38cf9", "isActive": false, "balance": "$1,166.85", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "blue", "name": "Boyle Gomez", "gender": "male", "company": "XEREX", "email": "boylegomez@xerex.com", "phone": "+1 (940) 547-3680", "address": "956 Calder Place, Ballico, Nevada, 9741", "about": "Consectetur commodo esse pariatur incididunt sint nisi tempor. Excepteur ipsum et irure ullamco in cupidatat officia eiusmod dolor ullamco id. Aliqua proident officia et deserunt culpa incididunt occaecat nostrud fugiat voluptate commodo ipsum. Do sunt aliquip ad veniam.\r\n", "registered": "2016-02-21T07:14:48 -01:00", "latitude": -71.848022, "longitude": 37.91472, "tags": [ "officia", "magna", "fugiat", "irure", "cupidatat", "pariatur", "dolor", "Lorem", "enim", "excepteur" ], "friends": [ { "id": 0, "name": "Chris Maxwell" }, { "id": 1, "name": "Shannon Cash" }, { "id": 2, "name": "Sheila Rich" }, { "id": 3, "name": "Marilyn Gibbs" }, { "id": 4, "name": "Stevens Stephenson" } ], "greeting": "Hello, Boyle Gomez! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826f73499ee231a73e1", "index": 225, "guid": "f589a699-5fef-4cfd-a5bf-c5f8660527c9", "isActive": false, "balance": "$3,891.61", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "blue", "name": "Vaughan Hopkins", "gender": "male", "company": "EXOSIS", "email": "vaughanhopkins@exosis.com", "phone": "+1 (975) 493-3112", "address": "141 Eaton Court, Nutrioso, Alaska, 2568", "about": "Tempor id ad eu excepteur consectetur occaecat. Consectetur dolor veniam aliquip non ullamco in do laborum tempor non occaecat deserunt commodo. Excepteur quis sunt elit velit nostrud. Ut quis esse ut sit reprehenderit et reprehenderit reprehenderit veniam veniam ea do ex.\r\n", "registered": "2015-06-12T08:17:54 -02:00", "latitude": 39.097289, "longitude": -143.946404, "tags": [ "fugiat", "laboris", "ad", "est", "culpa", "amet", "proident", "exercitation", "quis", "eiusmod" ], "friends": [ { "id": 0, "name": "Sabrina Strickland" }, { "id": 1, "name": "Bonner Lee" }, { "id": 2, "name": "Ladonna Meyers" }, { "id": 3, "name": "Shari Casey" }, { "id": 4, "name": "Maura Sanchez" } ], "greeting": "Hello, Vaughan Hopkins! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48266c27ce2ad7814dfc", "index": 226, "guid": "6aff51bd-9023-442d-a8ae-3ef0d1d16afe", "isActive": false, "balance": "$2,443.46", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Baker Moreno", "gender": "male", "company": "BOSTONIC", "email": "bakermoreno@bostonic.com", "phone": "+1 (955) 593-3224", "address": "515 Dwight Street, Harleigh, Illinois, 7649", "about": "Sunt anim tempor adipisicing esse labore deserunt reprehenderit tempor anim do. Reprehenderit amet quis anim amet ipsum laboris. Enim Lorem labore aliqua ullamco ad pariatur excepteur magna dolore do in voluptate sint esse. Duis do laboris exercitation velit incididunt tempor esse pariatur.\r\n", "registered": "2014-09-19T11:40:34 -02:00", "latitude": -17.128888, "longitude": -127.122201, "tags": [ "deserunt", "est", "irure", "aliqua", "magna", "Lorem", "cillum", "quis", "in", "ullamco" ], "friends": [ { "id": 0, "name": "Trudy Schwartz" }, { "id": 1, "name": "Kelley Munoz" }, { "id": 2, "name": "Marla Terry" }, { "id": 3, "name": "Cervantes Thornton" }, { "id": 4, "name": "Janette Collins" } ], "greeting": "Hello, Baker Moreno! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f6265e1ba9986b1f", "index": 227, "guid": "4d0da808-f603-4bce-aaa9-c794b80bd739", "isActive": true, "balance": "$1,383.71", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Lauri Welch", "gender": "female", "company": "ASSURITY", "email": "lauriwelch@assurity.com", "phone": "+1 (805) 451-2517", "address": "314 Baltic Street, Glendale, Oklahoma, 6624", "about": "Incididunt culpa excepteur sint proident exercitation qui aliqua. Proident minim fugiat deserunt est culpa reprehenderit dolor quis officia ut. In cillum proident in enim amet consequat consectetur velit aliqua duis aliquip tempor.\r\n", "registered": "2016-11-09T06:17:18 -01:00", "latitude": 0.587991, "longitude": -113.54891, "tags": [ "commodo", "eiusmod", "cupidatat", "consequat", "qui", "laboris", "elit", "quis", "pariatur", "in" ], "friends": [ { "id": 0, "name": "Alicia Fuentes" }, { "id": 1, "name": "Hunt Carlson" }, { "id": 2, "name": "Oliver Hawkins" }, { "id": 3, "name": "Martina Brown" }, { "id": 4, "name": "Crystal Holt" } ], "greeting": "Hello, Lauri Welch! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826acb61a5e3262b45c", "index": 228, "guid": "c4b326f7-f78a-4616-8bdb-04ba2358acf9", "isActive": true, "balance": "$3,531.98", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "green", "name": "Pauline Moon", "gender": "female", "company": "ISOSTREAM", "email": "paulinemoon@isostream.com", "phone": "+1 (859) 431-3297", "address": "472 Quentin Road, Cuylerville, Delaware, 2490", "about": "Enim veniam cillum nulla nostrud consequat fugiat mollit cillum incididunt. Culpa commodo esse nulla est cupidatat nostrud deserunt consequat culpa in. In cupidatat nostrud commodo officia reprehenderit aliqua in veniam fugiat occaecat duis nostrud elit. Occaecat veniam dolore ipsum duis id ex non ad. Commodo exercitation irure pariatur aliqua tempor aliquip Lorem ullamco esse eiusmod eiusmod eu culpa id. Ut cillum irure ea qui amet labore laboris ullamco.\r\n", "registered": "2015-05-09T08:08:27 -02:00", "latitude": 53.484302, "longitude": -143.091415, "tags": [ "dolor", "nulla", "laboris", "eiusmod", "Lorem", "velit", "aliquip", "aute", "incididunt", "sunt" ], "friends": [ { "id": 0, "name": "Darlene Hull" }, { "id": 1, "name": "Lila Holder" }, { "id": 2, "name": "Mason Burns" }, { "id": 3, "name": "Mcmillan Porter" }, { "id": 4, "name": "Drake Hale" } ], "greeting": "Hello, Pauline Moon! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826a2949732e40b5835", "index": 229, "guid": "a0835668-c8eb-4f00-ad9a-6d37abc40133", "isActive": false, "balance": "$2,699.71", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "brown", "name": "Valencia Atkinson", "gender": "male", "company": "KOFFEE", "email": "valenciaatkinson@koffee.com", "phone": "+1 (936) 542-3542", "address": "797 Voorhies Avenue, Nescatunga, Federated States Of Micronesia, 7350", "about": "Nisi ea ut do labore reprehenderit sunt ea duis ipsum sint magna nostrud. Tempor officia mollit non labore ad deserunt incididunt eu mollit do ullamco enim. Consequat deserunt amet minim irure cupidatat occaecat sunt amet ad elit cillum. Velit cillum culpa do proident minim excepteur qui commodo. Non occaecat sint dolor labore aute. Exercitation pariatur veniam deserunt deserunt fugiat proident mollit duis in incididunt exercitation quis occaecat. Voluptate occaecat cupidatat dolore occaecat deserunt eiusmod culpa.\r\n", "registered": "2014-07-19T05:07:10 -02:00", "latitude": -41.205954, "longitude": 91.476454, "tags": [ "mollit", "pariatur", "ex", "laboris", "do", "magna", "est", "nulla", "cupidatat", "tempor" ], "friends": [ { "id": 0, "name": "Shana Jones" }, { "id": 1, "name": "Kate Melendez" }, { "id": 2, "name": "Megan Boyle" }, { "id": 3, "name": "Elisabeth Padilla" }, { "id": 4, "name": "Franklin Travis" } ], "greeting": "Hello, Valencia Atkinson! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482655b8cedbeb3f042a", "index": 230, "guid": "31acebbd-4c87-4371-b7cb-9b0af28ca09c", "isActive": true, "balance": "$1,139.93", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "brown", "name": "Sonia Malone", "gender": "female", "company": "TURNLING", "email": "soniamalone@turnling.com", "phone": "+1 (961) 594-2035", "address": "898 Erasmus Street, Tilden, Florida, 4251", "about": "Laboris deserunt deserunt excepteur qui. Ex voluptate sit id laboris sit occaecat amet fugiat irure nulla pariatur. Elit tempor ipsum ad eu velit eu cillum eiusmod cupidatat anim sit ea dolor voluptate. Adipisicing cillum ea ut eu tempor veniam pariatur ad enim quis.\r\n", "registered": "2014-02-15T01:13:43 -01:00", "latitude": 4.597299, "longitude": -8.181124, "tags": [ "amet", "enim", "pariatur", "id", "aliquip", "id", "quis", "et", "officia", "adipisicing" ], "friends": [ { "id": 0, "name": "Margery Mccray" }, { "id": 1, "name": "Vargas Whitney" }, { "id": 2, "name": "Whitney Ward" }, { "id": 3, "name": "Ursula Nolan" }, { "id": 4, "name": "Hilary Burnett" } ], "greeting": "Hello, Sonia Malone! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826484955666205e529", "index": 231, "guid": "e6a5ff1d-d030-4d08-a1fb-33816453e72b", "isActive": true, "balance": "$1,820.30", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "blue", "name": "Gill Poole", "gender": "male", "company": "DEVILTOE", "email": "gillpoole@deviltoe.com", "phone": "+1 (971) 403-3720", "address": "764 Bergen Court, Coventry, Massachusetts, 9991", "about": "Est fugiat magna sunt cillum elit velit dolor ipsum labore velit. Dolor in ea irure quis. Eiusmod magna fugiat do velit enim sint. Voluptate mollit cillum velit occaecat velit voluptate esse. Ea cupidatat et dolor consequat ex ad est nisi excepteur. Aute laboris nisi sit ullamco commodo minim laboris excepteur duis aliquip ut velit anim.\r\n", "registered": "2014-05-18T07:59:12 -02:00", "latitude": -0.342498, "longitude": 15.356066, "tags": [ "Lorem", "culpa", "elit", "enim", "ullamco", "consectetur", "non", "nostrud", "officia", "fugiat" ], "friends": [ { "id": 0, "name": "Montoya Calderon" }, { "id": 1, "name": "Susan Chapman" }, { "id": 2, "name": "Bishop Russo" }, { "id": 3, "name": "Mcfadden Baker" }, { "id": 4, "name": "Berger Hays" } ], "greeting": "Hello, Gill Poole! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482686aae55321264865", "index": 232, "guid": "80754c13-4a1f-40f1-966b-2f2f0b6d91a2", "isActive": false, "balance": "$1,218.46", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "brown", "name": "Sloan Madden", "gender": "male", "company": "SULTRAX", "email": "sloanmadden@sultrax.com", "phone": "+1 (807) 562-3266", "address": "759 Williams Place, Richville, Mississippi, 2842", "about": "Anim qui duis aute ipsum dolor incididunt elit. Magna dolor est dolore in eu veniam et id duis do. Consequat labore eu sunt Lorem occaecat excepteur. Commodo proident pariatur dolore exercitation magna. Laborum consectetur Lorem voluptate veniam. Fugiat aute mollit nostrud quis reprehenderit ipsum aliqua.\r\n", "registered": "2017-09-21T11:05:49 -02:00", "latitude": 16.225225, "longitude": 109.259984, "tags": [ "ea", "nostrud", "cupidatat", "incididunt", "cupidatat", "ipsum", "ipsum", "et", "velit", "irure" ], "friends": [ { "id": 0, "name": "Kinney Keller" }, { "id": 1, "name": "Fowler Kim" }, { "id": 2, "name": "Taylor Hood" }, { "id": 3, "name": "Katie Patterson" }, { "id": 4, "name": "Mckee Patel" } ], "greeting": "Hello, Sloan Madden! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48262475a849f9b96f64", "index": 233, "guid": "706f4cc0-95e7-4c79-a296-de72dba0e04f", "isActive": true, "balance": "$1,926.68", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Stella Knapp", "gender": "female", "company": "GOKO", "email": "stellaknapp@goko.com", "phone": "+1 (985) 544-3849", "address": "679 Diamond Street, Dola, Guam, 9100", "about": "Commodo deserunt exercitation commodo mollit quis dolore nisi sit. Sunt culpa culpa dolor in aliquip proident quis aute exercitation. Eu nostrud irure duis eu sunt quis eiusmod sunt proident ipsum nulla nostrud aliquip minim. Nulla mollit occaecat et duis aute dolore esse enim nulla sint elit. Labore enim ad quis consectetur culpa amet in. Nostrud laboris proident fugiat amet cillum Lorem. Eiusmod ullamco ex laborum dolore anim.\r\n", "registered": "2015-03-19T07:15:52 -01:00", "latitude": -82.932771, "longitude": -79.190804, "tags": [ "elit", "ullamco", "dolore", "cillum", "cillum", "sit", "ipsum", "velit", "dolor", "reprehenderit" ], "friends": [ { "id": 0, "name": "Cox Sanford" }, { "id": 1, "name": "Maria Rodriquez" }, { "id": 2, "name": "Barr Berger" }, { "id": 3, "name": "Lelia Snyder" }, { "id": 4, "name": "Vang Kirby" } ], "greeting": "Hello, Stella Knapp! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48264f1e4bf80add0014", "index": 234, "guid": "5e6762b3-e174-469c-a8b6-9eee55bbe4e5", "isActive": true, "balance": "$1,830.83", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "brown", "name": "Evans Gray", "gender": "male", "company": "DIGIPRINT", "email": "evansgray@digiprint.com", "phone": "+1 (874) 503-3712", "address": "228 Newport Street, Waikele, Louisiana, 5070", "about": "Ea pariatur velit do amet sunt ut velit deserunt ipsum enim non in. Do Lorem aute aliquip culpa tempor Lorem minim proident officia id esse est commodo. Fugiat reprehenderit adipisicing reprehenderit amet adipisicing adipisicing consectetur quis laboris dolore esse fugiat eiusmod non. Veniam officia dolor magna in irure. Esse nisi nulla pariatur ipsum amet magna voluptate aliqua laborum amet. Aute tempor quis esse id fugiat irure deserunt Lorem eiusmod sint.\r\n", "registered": "2015-03-12T10:18:22 -01:00", "latitude": 8.500056, "longitude": 26.811266, "tags": [ "in", "id", "quis", "cupidatat", "velit", "amet", "adipisicing", "mollit", "eu", "eu" ], "friends": [ { "id": 0, "name": "Raymond Jacobson" }, { "id": 1, "name": "Barnes Patton" }, { "id": 2, "name": "Stephenson Parks" }, { "id": 3, "name": "Willis Howard" }, { "id": 4, "name": "Hardin Black" } ], "greeting": "Hello, Evans Gray! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826f448c23d7fcd6dd8", "index": 235, "guid": "5b6ba5e9-ad06-4e26-960e-ad5160a605ee", "isActive": true, "balance": "$1,990.65", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "brown", "name": "Iris Hardin", "gender": "female", "company": "DOGNOST", "email": "irishardin@dognost.com", "phone": "+1 (863) 566-2709", "address": "586 Highland Place, Naomi, South Dakota, 3894", "about": "Irure laborum excepteur ullamco anim eiusmod enim ipsum non cillum. Cillum labore eiusmod ad in sint fugiat officia nostrud id cupidatat. Laboris sint id aute aute pariatur veniam do sint ea excepteur velit cillum. Aute deserunt eiusmod dolor irure nulla proident. Sint exercitation ullamco ullamco cillum incididunt nulla Lorem laborum laboris labore duis laborum magna.\r\n", "registered": "2016-03-27T09:33:52 -02:00", "latitude": 67.511801, "longitude": 141.412032, "tags": [ "cupidatat", "reprehenderit", "anim", "eiusmod", "et", "commodo", "quis", "exercitation", "velit", "consequat" ], "friends": [ { "id": 0, "name": "Patsy Griffin" }, { "id": 1, "name": "Navarro Lopez" }, { "id": 2, "name": "Fischer Walls" }, { "id": 3, "name": "Barker Bernard" }, { "id": 4, "name": "Sandoval Hooper" } ], "greeting": "Hello, Iris Hardin! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482677d7c33c49721ec0", "index": 236, "guid": "92f52aa3-e119-4363-ba4a-82bf7ea5eea9", "isActive": true, "balance": "$2,211.35", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Marylou Maddox", "gender": "female", "company": "COMTRAIL", "email": "maryloumaddox@comtrail.com", "phone": "+1 (949) 458-2372", "address": "507 Amber Street, Salvo, District Of Columbia, 4441", "about": "Lorem minim cillum occaecat commodo. Nulla laborum nostrud excepteur culpa minim culpa irure commodo Lorem non in. Dolor ipsum ea consequat laborum ex adipisicing do dolore officia ea. Excepteur dolor sint tempor labore dolor ipsum reprehenderit culpa sunt elit amet adipisicing cillum. Laboris duis qui culpa ipsum exercitation sit. Fugiat quis magna fugiat dolor dolor est sint quis dolore aliquip sint reprehenderit mollit.\r\n", "registered": "2014-12-22T05:32:23 -01:00", "latitude": 88.931174, "longitude": -51.450675, "tags": [ "Lorem", "aliquip", "dolore", "cupidatat", "magna", "duis", "amet", "nostrud", "ut", "voluptate" ], "friends": [ { "id": 0, "name": "Albert Mccoy" }, { "id": 1, "name": "Summer Sparks" }, { "id": 2, "name": "Delores Albert" }, { "id": 3, "name": "Dickson Mejia" }, { "id": 4, "name": "Michele Riddle" } ], "greeting": "Hello, Marylou Maddox! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48262011fffc2b993a55", "index": 237, "guid": "068a96bd-d3e8-4c5a-a0ba-880b485d10a4", "isActive": false, "balance": "$3,103.85", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Simpson Dixon", "gender": "male", "company": "ZENOLUX", "email": "simpsondixon@zenolux.com", "phone": "+1 (827) 564-2204", "address": "802 Emmons Avenue, Walker, Puerto Rico, 140", "about": "Sit laborum fugiat sit fugiat reprehenderit nulla non fugiat. Consequat fugiat in velit qui minim officia esse. Amet non magna ullamco quis reprehenderit et est nisi sunt. Officia ut incididunt nulla ipsum duis ea id. Eu aliqua dolor ut reprehenderit laborum aliqua aliquip exercitation. Aliqua est non eiusmod reprehenderit. Cillum ut aliquip id nulla quis deserunt.\r\n", "registered": "2016-10-03T03:01:10 -02:00", "latitude": -88.519633, "longitude": -55.25385, "tags": [ "velit", "est", "magna", "nisi", "ut", "incididunt", "mollit", "ipsum", "eiusmod", "Lorem" ], "friends": [ { "id": 0, "name": "Orr Ortiz" }, { "id": 1, "name": "Arlene Dunn" }, { "id": 2, "name": "Nelson Palmer" }, { "id": 3, "name": "Potts Ayers" }, { "id": 4, "name": "Lou Foster" } ], "greeting": "Hello, Simpson Dixon! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482653aa962eaa1d2dd7", "index": 238, "guid": "50bca915-c797-4c00-aa9b-148b960a634c", "isActive": true, "balance": "$1,694.15", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Soto Merritt", "gender": "male", "company": "VERAQ", "email": "sotomerritt@veraq.com", "phone": "+1 (993) 422-3358", "address": "712 Brightwater Avenue, Wyoming, Maine, 6762", "about": "Occaecat laboris quis ex est eiusmod minim nisi dolor sit commodo dolor commodo sint. Excepteur in ipsum cupidatat eiusmod sunt fugiat voluptate esse deserunt. Sint laboris veniam nostrud consequat fugiat culpa et labore Lorem quis do ipsum proident. Culpa Lorem Lorem aute duis magna ut ad Lorem mollit adipisicing. Veniam labore mollit incididunt est fugiat sunt cupidatat ut ipsum est. Officia adipisicing labore adipisicing reprehenderit sit aliqua mollit esse irure sit.\r\n", "registered": "2015-11-18T09:17:23 -01:00", "latitude": -61.71466, "longitude": 64.930701, "tags": [ "do", "aliqua", "veniam", "ipsum", "nulla", "et", "laboris", "aute", "magna", "do" ], "friends": [ { "id": 0, "name": "Mayo Allison" }, { "id": 1, "name": "Benton Clemons" }, { "id": 2, "name": "Francine Mcdonald" }, { "id": 3, "name": "Eva Leon" }, { "id": 4, "name": "Mcpherson Owen" } ], "greeting": "Hello, Soto Merritt! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f199e96612a77dd2", "index": 239, "guid": "6a3c7520-752d-417f-85e2-23679d96fd2c", "isActive": false, "balance": "$1,696.47", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Boyer Levy", "gender": "male", "company": "BITREX", "email": "boyerlevy@bitrex.com", "phone": "+1 (990) 415-3154", "address": "200 Lafayette Avenue, Marysville, New Jersey, 1267", "about": "Commodo ipsum amet adipisicing deserunt. Sint minim aute culpa ut magna labore proident anim. Voluptate velit eu labore laboris. Labore irure ea sunt nulla proident culpa.\r\n", "registered": "2017-12-26T03:35:04 -01:00", "latitude": -79.07149, "longitude": -129.571851, "tags": [ "sint", "esse", "culpa", "labore", "adipisicing", "ut", "voluptate", "ex", "culpa", "incididunt" ], "friends": [ { "id": 0, "name": "Santiago Cain" }, { "id": 1, "name": "Sosa Vance" }, { "id": 2, "name": "Margo Harvey" }, { "id": 3, "name": "Weeks Jackson" }, { "id": 4, "name": "Mccullough Rivas" } ], "greeting": "Hello, Boyer Levy! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48265d3a1b53eb7756a9", "index": 240, "guid": "74519106-dbef-4d71-b53e-b03abb8a3975", "isActive": true, "balance": "$1,915.93", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "green", "name": "Tabatha Craft", "gender": "female", "company": "VIASIA", "email": "tabathacraft@viasia.com", "phone": "+1 (923) 459-2669", "address": "262 Gunther Place, Faxon, Michigan, 6031", "about": "Lorem est duis commodo nostrud est enim ipsum amet et proident est. Ullamco qui exercitation magna nisi reprehenderit. Elit aute cupidatat deserunt sint irure exercitation. Aliqua ad magna cupidatat officia dolore culpa ea adipisicing mollit deserunt excepteur eiusmod est id.\r\n", "registered": "2015-11-08T01:49:50 -01:00", "latitude": 16.608203, "longitude": 80.86998, "tags": [ "ex", "exercitation", "adipisicing", "proident", "aliqua", "consequat", "adipisicing", "aliquip", "dolor", "nulla" ], "friends": [ { "id": 0, "name": "Janice Carver" }, { "id": 1, "name": "Knowles Vasquez" }, { "id": 2, "name": "Melendez Pitts" }, { "id": 3, "name": "Kelly Harmon" }, { "id": 4, "name": "Richards Stone" } ], "greeting": "Hello, Tabatha Craft! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b2a18cf96ecbf2a5", "index": 241, "guid": "72cfcce6-781b-49d8-98d5-e837d0df7622", "isActive": false, "balance": "$3,810.76", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Gray Mcdaniel", "gender": "male", "company": "PUSHCART", "email": "graymcdaniel@pushcart.com", "phone": "+1 (982) 586-2781", "address": "830 Cove Lane, Buxton, Rhode Island, 4418", "about": "Voluptate commodo sunt tempor ad. Id ullamco ad et irure ullamco eiusmod. Occaecat ad irure cupidatat mollit consequat. Nulla ullamco quis magna aute. Esse Lorem ullamco elit elit et nisi ut ea amet occaecat. Ea nisi amet sit ad laboris enim do cillum. Consequat irure nulla deserunt ad cupidatat quis fugiat et laboris elit anim laboris proident amet.\r\n", "registered": "2015-01-15T05:28:14 -01:00", "latitude": 14.767934, "longitude": 117.212255, "tags": [ "aliquip", "labore", "ut", "in", "ut", "anim", "consequat", "nostrud", "incididunt", "officia" ], "friends": [ { "id": 0, "name": "Porter Mcmillan" }, { "id": 1, "name": "Tracie Browning" }, { "id": 2, "name": "Underwood Harris" }, { "id": 3, "name": "Campbell Perez" }, { "id": 4, "name": "Grace Oconnor" } ], "greeting": "Hello, Gray Mcdaniel! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48266c94aa82fe0aa632", "index": 242, "guid": "d8c89e3c-bd57-40b6-8598-3459a9d588b7", "isActive": false, "balance": "$1,068.66", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "brown", "name": "Mcintyre Cooley", "gender": "male", "company": "NETPLODE", "email": "mcintyrecooley@netplode.com", "phone": "+1 (963) 483-3023", "address": "333 Huntington Street, Harborton, Kansas, 8827", "about": "Aliqua qui sit duis incididunt cupidatat duis commodo aliquip laboris aliqua aliqua minim. Aute sint culpa excepteur anim sunt dolor laboris aliqua aliqua. Sunt fugiat exercitation veniam culpa est eiusmod. Veniam do voluptate deserunt nostrud est nostrud.\r\n", "registered": "2015-09-05T12:08:09 -02:00", "latitude": 72.385412, "longitude": 170.962951, "tags": [ "veniam", "velit", "eiusmod", "laborum", "exercitation", "veniam", "ut", "ad", "dolor", "reprehenderit" ], "friends": [ { "id": 0, "name": "Julia Clarke" }, { "id": 1, "name": "Beard Castro" }, { "id": 2, "name": "Debora Diaz" }, { "id": 3, "name": "Lucas Garrison" }, { "id": 4, "name": "Burks Cantrell" } ], "greeting": "Hello, Mcintyre Cooley! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826e887b22c23c03f20", "index": 243, "guid": "9de69075-461b-4442-beaa-2c1f9ceb3714", "isActive": false, "balance": "$2,672.71", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "brown", "name": "Duncan Farrell", "gender": "male", "company": "ORBIFLEX", "email": "duncanfarrell@orbiflex.com", "phone": "+1 (861) 406-3652", "address": "197 Garfield Place, Edenburg, West Virginia, 7369", "about": "Consectetur mollit cillum pariatur incididunt cillum esse. Excepteur ex ea laboris id dolore aliquip dolore anim. Lorem do ex deserunt ipsum qui incididunt duis occaecat ut quis. Mollit laborum minim magna ut do proident. Adipisicing irure ut voluptate ullamco sunt tempor tempor Lorem. Aliqua ipsum dolore voluptate laborum reprehenderit tempor occaecat consectetur cillum eu sit. Anim nulla esse minim anim.\r\n", "registered": "2016-02-27T10:52:19 -01:00", "latitude": -65.690621, "longitude": 143.342369, "tags": [ "anim", "adipisicing", "deserunt", "laborum", "occaecat", "elit", "deserunt", "elit", "tempor", "sunt" ], "friends": [ { "id": 0, "name": "Fitzgerald Franco" }, { "id": 1, "name": "Adrian Hopper" }, { "id": 2, "name": "Crosby Dillon" }, { "id": 3, "name": "Rosalinda York" }, { "id": 4, "name": "Candace Rodriguez" } ], "greeting": "Hello, Duncan Farrell! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482643f00e919504e0ef", "index": 244, "guid": "e3ff5be6-30b2-4c96-bd54-935da8254a81", "isActive": false, "balance": "$2,214.63", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Janis Larson", "gender": "female", "company": "PYRAMIA", "email": "janislarson@pyramia.com", "phone": "+1 (837) 460-2397", "address": "864 Lawrence Street, Norris, American Samoa, 5243", "about": "Eu duis ad duis commodo adipisicing proident dolore nulla dolor. Excepteur ex occaecat ipsum aute est. Duis aliquip sunt non enim sint eu adipisicing aliqua id enim id velit minim proident. Cillum id quis commodo ipsum duis ut sunt ex sint aliqua sint eu elit minim.\r\n", "registered": "2015-01-15T04:39:31 -01:00", "latitude": 8.809974, "longitude": 135.283858, "tags": [ "do", "fugiat", "nostrud", "magna", "tempor", "aute", "mollit", "magna", "ut", "voluptate" ], "friends": [ { "id": 0, "name": "Schroeder Koch" }, { "id": 1, "name": "Ava Gregory" }, { "id": 2, "name": "Carlson Salazar" }, { "id": 3, "name": "Suarez Becker" }, { "id": 4, "name": "Georgette Byrd" } ], "greeting": "Hello, Janis Larson! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48266e81101f0799fafd", "index": 245, "guid": "95736526-c6c5-455d-94c4-80d82cc1c3eb", "isActive": true, "balance": "$1,001.88", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "green", "name": "Strong Boone", "gender": "male", "company": "ZERBINA", "email": "strongboone@zerbina.com", "phone": "+1 (829) 523-3163", "address": "304 Hicks Street, Verdi, Maryland, 720", "about": "Elit dolore in ex irure elit enim deserunt nostrud proident nostrud aute. Do consequat aute minim laborum id veniam eu. Excepteur velit aute commodo Lorem id minim ipsum irure proident Lorem reprehenderit adipisicing. Aute quis magna occaecat laborum. Et magna ullamco do ea culpa proident incididunt dolore do nisi.\r\n", "registered": "2015-11-26T04:34:40 -01:00", "latitude": -65.757582, "longitude": -98.856475, "tags": [ "cillum", "est", "do", "reprehenderit", "nulla", "quis", "eu", "ut", "amet", "irure" ], "friends": [ { "id": 0, "name": "Glenda Barnett" }, { "id": 1, "name": "Prince Huff" }, { "id": 2, "name": "Katheryn Brady" }, { "id": 3, "name": "Gibson Hoover" }, { "id": 4, "name": "Marquita Clay" } ], "greeting": "Hello, Strong Boone! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48269754d71e22a28add", "index": 246, "guid": "43c3ec02-ad21-4d13-ace3-f148d650dba6", "isActive": false, "balance": "$2,341.13", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Briana Chaney", "gender": "female", "company": "ZILLAR", "email": "brianachaney@zillar.com", "phone": "+1 (917) 518-3486", "address": "467 Greenwood Avenue, Rodman, California, 5099", "about": "Incididunt adipisicing occaecat esse id ullamco. Nulla nulla qui incididunt excepteur do nostrud irure cillum magna consectetur ea. Quis exercitation reprehenderit laboris aliquip sint occaecat mollit deserunt Lorem cupidatat consectetur aliqua.\r\n", "registered": "2017-03-01T12:35:34 -01:00", "latitude": -4.379075, "longitude": 26.057805, "tags": [ "occaecat", "nulla", "eiusmod", "sit", "pariatur", "esse", "in", "elit", "ullamco", "est" ], "friends": [ { "id": 0, "name": "Marianne Larsen" }, { "id": 1, "name": "Florence Nicholson" }, { "id": 2, "name": "Marguerite Mcmahon" }, { "id": 3, "name": "Mercedes Wilson" }, { "id": 4, "name": "Penny Galloway" } ], "greeting": "Hello, Briana Chaney! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48263c246d38d2b415c9", "index": 247, "guid": "51caac9b-49ba-46ec-87be-08446475f337", "isActive": false, "balance": "$2,042.87", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "brown", "name": "Riggs Everett", "gender": "male", "company": "XIXAN", "email": "riggseverett@xixan.com", "phone": "+1 (811) 521-3936", "address": "466 Hyman Court, Belfair, Utah, 9561", "about": "Adipisicing adipisicing labore id in commodo nulla nulla cupidatat sunt ipsum ea cupidatat minim. In sit sit reprehenderit occaecat do excepteur labore exercitation magna adipisicing. Reprehenderit proident veniam reprehenderit incididunt qui nostrud eiusmod dolor veniam incididunt ex. Consequat est ut duis excepteur ad commodo. Laborum consequat Lorem sint duis labore qui consequat Lorem voluptate sunt. Incididunt ad Lorem laboris enim dolore mollit commodo. Consequat id nostrud incididunt aliqua.\r\n", "registered": "2015-12-07T10:10:08 -01:00", "latitude": -22.785147, "longitude": -26.966008, "tags": [ "ex", "aliqua", "nulla", "reprehenderit", "ut", "aliquip", "reprehenderit", "ad", "culpa", "eiusmod" ], "friends": [ { "id": 0, "name": "Osborne Meadows" }, { "id": 1, "name": "Higgins Hinton" }, { "id": 2, "name": "Dorothea Sharpe" }, { "id": 3, "name": "Morgan Buckner" }, { "id": 4, "name": "Carly Morris" } ], "greeting": "Hello, Riggs Everett! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48261ed5160c0eb92638", "index": 248, "guid": "0d88ec8c-b859-410e-b91d-34713e403a3f", "isActive": false, "balance": "$3,288.15", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "brown", "name": "Jaclyn Wilder", "gender": "female", "company": "PORTALINE", "email": "jaclynwilder@portaline.com", "phone": "+1 (942) 501-3734", "address": "460 Sapphire Street, Frystown, Iowa, 6348", "about": "Velit ad occaecat mollit laboris elit labore ut culpa. Ut qui sint do id qui exercitation ipsum nostrud consequat eu reprehenderit. Dolore ex incididunt id ullamco incididunt amet ad eiusmod amet. Consectetur Lorem commodo esse ea amet sint eiusmod elit. Occaecat proident amet deserunt reprehenderit voluptate nostrud eu reprehenderit eu nostrud.\r\n", "registered": "2017-07-31T12:23:51 -02:00", "latitude": -46.53141, "longitude": 82.865802, "tags": [ "occaecat", "exercitation", "duis", "occaecat", "exercitation", "esse", "pariatur", "reprehenderit", "eu", "anim" ], "friends": [ { "id": 0, "name": "Sexton Olsen" }, { "id": 1, "name": "Amanda Garner" }, { "id": 2, "name": "Kimberley Walker" }, { "id": 3, "name": "Mariana Neal" }, { "id": 4, "name": "Garner Colon" } ], "greeting": "Hello, Jaclyn Wilder! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c90c8c048171963d", "index": 249, "guid": "610d4721-33f4-4cb7-90a5-f207e62a4c31", "isActive": true, "balance": "$1,346.04", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "blue", "name": "Betsy Mercer", "gender": "female", "company": "DANCITY", "email": "betsymercer@dancity.com", "phone": "+1 (922) 517-2222", "address": "681 Victor Road, Benson, North Dakota, 6499", "about": "Officia laborum laborum non sit nisi commodo laborum labore. Cillum dolore ea nostrud sint exercitation amet nulla amet eiusmod. Nulla cillum nulla ut veniam aute aute qui adipisicing sunt mollit aute duis. Fugiat do magna irure enim aliquip fugiat exercitation. Nisi qui aliqua ad dolor pariatur aliquip sint ad. Excepteur nulla ipsum et qui sit pariatur.\r\n", "registered": "2014-08-06T02:50:53 -02:00", "latitude": 32.575805, "longitude": -10.726051, "tags": [ "velit", "mollit", "aliquip", "sunt", "irure", "sunt", "duis", "nulla", "mollit", "deserunt" ], "friends": [ { "id": 0, "name": "Nichole Hicks" }, { "id": 1, "name": "Laverne Nguyen" }, { "id": 2, "name": "Reeves Bell" }, { "id": 3, "name": "Mcknight Leonard" }, { "id": 4, "name": "Day Hart" } ], "greeting": "Hello, Betsy Mercer! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826e3966bb3be3da67d", "index": 250, "guid": "e4b2edb3-1d2f-4a4f-a4c5-83c55a90dd7f", "isActive": true, "balance": "$2,131.98", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "blue", "name": "Chelsea Carr", "gender": "female", "company": "VANTAGE", "email": "chelseacarr@vantage.com", "phone": "+1 (852) 582-2673", "address": "500 Willoughby Avenue, Hanover, Kentucky, 8835", "about": "Lorem voluptate aute nisi elit mollit veniam esse eiusmod. Cupidatat ullamco quis mollit eu do incididunt Lorem. In quis dolor occaecat velit culpa id in esse do tempor. Veniam ut dolore amet dolore sit nulla do ipsum nisi. Culpa aute cupidatat commodo adipisicing laboris velit minim nostrud dolor duis esse ad dolor.\r\n", "registered": "2017-02-05T11:27:12 -01:00", "latitude": 3.68426, "longitude": 50.65642, "tags": [ "magna", "eu", "esse", "reprehenderit", "proident", "anim", "incididunt", "nulla", "deserunt", "veniam" ], "friends": [ { "id": 0, "name": "Mckay Mcgee" }, { "id": 1, "name": "Wells Smith" }, { "id": 2, "name": "Eugenia Riggs" }, { "id": 3, "name": "Chaney Oneil" }, { "id": 4, "name": "Castaneda Cobb" } ], "greeting": "Hello, Chelsea Carr! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826cab4b7cf3b70f120", "index": 251, "guid": "46283db6-d457-45e7-8ad4-58407b12a66f", "isActive": false, "balance": "$2,998.79", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "brown", "name": "Woodard Velez", "gender": "male", "company": "IMKAN", "email": "woodardvelez@imkan.com", "phone": "+1 (925) 516-2536", "address": "753 Murdock Court, Cherokee, Colorado, 674", "about": "Et commodo sit reprehenderit aute Lorem sunt duis incididunt laboris proident minim esse. Et minim nulla aliquip labore fugiat consequat Lorem. Enim ea cupidatat exercitation adipisicing et laboris esse incididunt fugiat aliquip. Eu sint aliqua amet sint magna proident. Do in anim magna duis dolore irure veniam reprehenderit laboris aliqua. Mollit enim in officia incididunt deserunt ea adipisicing.\r\n", "registered": "2014-08-24T07:27:48 -02:00", "latitude": -32.395854, "longitude": 177.88255, "tags": [ "dolore", "aliquip", "do", "dolor", "do", "commodo", "minim", "deserunt", "Lorem", "nulla" ], "friends": [ { "id": 0, "name": "Rosalind Wiley" }, { "id": 1, "name": "Melanie Doyle" }, { "id": 2, "name": "Jamie Rogers" }, { "id": 3, "name": "Galloway Lamb" }, { "id": 4, "name": "Leslie Juarez" } ], "greeting": "Hello, Woodard Velez! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826d18e2885336aea94", "index": 252, "guid": "4f157e1c-ea6c-4d60-be7c-7dd208212bfd", "isActive": true, "balance": "$2,315.98", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "brown", "name": "Adkins Duran", "gender": "male", "company": "RAMJOB", "email": "adkinsduran@ramjob.com", "phone": "+1 (805) 574-2874", "address": "792 Knapp Street, Forestburg, New Hampshire, 2772", "about": "Quis ad nisi cupidatat eu ut anim laboris. Eiusmod aute eiusmod non aute. Pariatur officia dolore ipsum do commodo fugiat sunt fugiat laboris ut culpa.\r\n", "registered": "2014-11-16T01:20:37 -01:00", "latitude": 13.489524, "longitude": 112.751497, "tags": [ "laborum", "ea", "cillum", "dolor", "do", "excepteur", "est", "esse", "minim", "ut" ], "friends": [ { "id": 0, "name": "Kane Rowe" }, { "id": 1, "name": "Trujillo Roberson" }, { "id": 2, "name": "Wilson Beach" }, { "id": 3, "name": "Nadine Schneider" }, { "id": 4, "name": "Giles Sharp" } ], "greeting": "Hello, Adkins Duran! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826df72c342962e0206", "index": 253, "guid": "dede9076-5ff4-423e-85c5-02ee84e27a75", "isActive": false, "balance": "$2,158.18", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Patrick Rocha", "gender": "male", "company": "EARBANG", "email": "patrickrocha@earbang.com", "phone": "+1 (869) 470-3531", "address": "741 Jackson Place, Dunlo, Wisconsin, 3748", "about": "Occaecat id dolore cupidatat duis aliqua consequat irure. Commodo exercitation aliquip aute laborum elit et pariatur sint est. Elit aute veniam culpa magna aliqua tempor veniam do commodo nulla anim esse. Fugiat deserunt tempor incididunt eu.\r\n", "registered": "2017-09-01T01:29:32 -02:00", "latitude": -25.853001, "longitude": 96.35487, "tags": [ "excepteur", "adipisicing", "occaecat", "dolore", "consequat", "enim", "voluptate", "esse", "irure", "ad" ], "friends": [ { "id": 0, "name": "Juliana Key" }, { "id": 1, "name": "Christi Barr" }, { "id": 2, "name": "Guerra Valdez" }, { "id": 3, "name": "Lina Kennedy" }, { "id": 4, "name": "Judith Marsh" } ], "greeting": "Hello, Patrick Rocha! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48263d935b310cc5f3f4", "index": 254, "guid": "0d6df89b-c2db-4c18-8ef1-4fab2feafd11", "isActive": false, "balance": "$2,465.37", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Wise Talley", "gender": "male", "company": "RODEOLOGY", "email": "wisetalley@rodeology.com", "phone": "+1 (802) 497-2151", "address": "734 Delmonico Place, Orick, Idaho, 2954", "about": "Nulla mollit anim voluptate occaecat cupidatat id quis voluptate sint. Minim proident dolor qui quis nulla esse minim velit. Do ea et excepteur exercitation ad consequat excepteur et laborum duis in veniam. Est irure et exercitation nostrud consequat nostrud voluptate consequat culpa eu duis minim. Mollit culpa adipisicing irure dolor eu est. Lorem duis ad ipsum deserunt duis tempor. Irure consequat ea pariatur irure ex ad consequat magna ex.\r\n", "registered": "2015-02-12T06:29:45 -01:00", "latitude": -29.45205, "longitude": 118.857727, "tags": [ "adipisicing", "fugiat", "non", "tempor", "ipsum", "minim", "ad", "nulla", "officia", "pariatur" ], "friends": [ { "id": 0, "name": "Mildred King" }, { "id": 1, "name": "Johnson Manning" }, { "id": 2, "name": "Rachelle Pittman" }, { "id": 3, "name": "Eleanor Bradford" }, { "id": 4, "name": "Brady Kane" } ], "greeting": "Hello, Wise Talley! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48266b8aa34d0dca825e", "index": 255, "guid": "7cc7fa26-2ea7-4d1c-b90f-2e0a95562277", "isActive": true, "balance": "$1,650.49", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Mcclure Mendoza", "gender": "male", "company": "PHARMEX", "email": "mccluremendoza@pharmex.com", "phone": "+1 (987) 442-2939", "address": "740 Alton Place, Delshire, Georgia, 5448", "about": "Sint adipisicing qui esse cupidatat adipisicing laborum enim. Cupidatat proident eu consequat ad cillum do sint eiusmod non qui adipisicing. Commodo commodo sit nostrud exercitation in consequat excepteur non aliqua ipsum sunt. Labore aliquip laborum quis ut nostrud velit dolor adipisicing sint elit sit excepteur. Aliqua laboris voluptate non fugiat tempor amet ullamco in. Duis quis nisi qui laborum occaecat velit nisi.\r\n", "registered": "2014-08-13T05:30:00 -02:00", "latitude": 80.590886, "longitude": -3.74397, "tags": [ "et", "deserunt", "est", "fugiat", "consequat", "tempor", "adipisicing", "fugiat", "mollit", "culpa" ], "friends": [ { "id": 0, "name": "Hubbard Hall" }, { "id": 1, "name": "Marcella Le" }, { "id": 2, "name": "Pollard Anthony" }, { "id": 3, "name": "Sheri French" }, { "id": 4, "name": "Williams Goodman" } ], "greeting": "Hello, Mcclure Mendoza! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826df387b0108885863", "index": 256, "guid": "02bbb84b-2913-4936-8d5e-3bb97d019468", "isActive": true, "balance": "$2,671.78", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "green", "name": "Nelda Ashley", "gender": "female", "company": "MEDICROIX", "email": "neldaashley@medicroix.com", "phone": "+1 (898) 523-3263", "address": "299 Frank Court, Richmond, Virgin Islands, 344", "about": "Enim Lorem ipsum Lorem culpa officia ad et esse ullamco fugiat. Eiusmod non tempor quis ad eu elit magna aliquip labore consectetur. Reprehenderit commodo reprehenderit elit nostrud consequat esse anim cillum cupidatat qui irure velit. Lorem ad cupidatat cupidatat sunt dolor aliqua minim excepteur ullamco.\r\n", "registered": "2017-08-26T01:33:09 -02:00", "latitude": 42.59506, "longitude": -138.183838, "tags": [ "voluptate", "in", "aliqua", "laborum", "enim", "veniam", "eu", "cupidatat", "laboris", "amet" ], "friends": [ { "id": 0, "name": "Bianca Skinner" }, { "id": 1, "name": "Bradford Woodward" }, { "id": 2, "name": "Agnes Barry" }, { "id": 3, "name": "Robbins Mack" }, { "id": 4, "name": "Sherman Woods" } ], "greeting": "Hello, Nelda Ashley! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48264a85130d356f19fb", "index": 257, "guid": "4686ab11-fe47-44df-869e-1c30b771d9ff", "isActive": false, "balance": "$3,130.06", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "brown", "name": "Araceli Bishop", "gender": "female", "company": "SULFAX", "email": "aracelibishop@sulfax.com", "phone": "+1 (949) 458-2045", "address": "406 Lester Court, Crenshaw, Minnesota, 6048", "about": "Aute aliqua amet ipsum incididunt dolore nostrud aliqua nostrud anim. Quis eu nulla ad dolor incididunt Lorem. Sit ex commodo reprehenderit laboris enim voluptate consectetur consectetur qui consectetur magna. Consectetur non culpa nisi laboris ad. Dolor qui est qui nulla aliquip.\r\n", "registered": "2016-04-19T11:51:05 -02:00", "latitude": -1.084987, "longitude": -141.654462, "tags": [ "aliqua", "est", "incididunt", "incididunt", "mollit", "in", "tempor", "mollit", "magna", "mollit" ], "friends": [ { "id": 0, "name": "Dolores Sanders" }, { "id": 1, "name": "Palmer Mcpherson" }, { "id": 2, "name": "Etta Oneill" }, { "id": 3, "name": "Riddle Rhodes" }, { "id": 4, "name": "Hatfield Ball" } ], "greeting": "Hello, Araceli Bishop! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482607969c58ace20e2a", "index": 258, "guid": "92ce8aa4-6d2d-4638-919d-13be764f21de", "isActive": false, "balance": "$1,613.59", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Booker Acosta", "gender": "male", "company": "MATRIXITY", "email": "bookeracosta@matrixity.com", "phone": "+1 (923) 529-3022", "address": "656 Montague Street, Interlochen, South Carolina, 847", "about": "Quis aliqua ad reprehenderit reprehenderit. Sunt ea labore tempor velit do ut ipsum elit Lorem. Sint eiusmod in nostrud anim labore reprehenderit amet tempor officia amet.\r\n", "registered": "2014-04-16T10:14:58 -02:00", "latitude": 29.883637, "longitude": 92.420798, "tags": [ "Lorem", "eiusmod", "sunt", "labore", "quis", "aliquip", "est", "anim", "sit", "qui" ], "friends": [ { "id": 0, "name": "Mara Cox" }, { "id": 1, "name": "Rosanne Cleveland" }, { "id": 2, "name": "Joyce Flynn" }, { "id": 3, "name": "Ashlee Martinez" }, { "id": 4, "name": "Hancock Sutton" } ], "greeting": "Hello, Booker Acosta! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48260a0c0f56d69eb91c", "index": 259, "guid": "4c0ffae7-1dc8-416a-92c9-cb5fd410f6ab", "isActive": false, "balance": "$3,545.59", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Long Jennings", "gender": "male", "company": "ACUSAGE", "email": "longjennings@acusage.com", "phone": "+1 (880) 405-2758", "address": "545 Navy Walk, Brule, Northern Mariana Islands, 8918", "about": "Aliqua mollit et velit ad quis magna. Dolor cillum reprehenderit dolore eiusmod occaecat velit. Adipisicing Lorem sunt excepteur excepteur quis.\r\n", "registered": "2017-08-10T09:35:04 -02:00", "latitude": 41.457029, "longitude": 118.621234, "tags": [ "in", "enim", "labore", "velit", "ipsum", "veniam", "eu", "id", "ut", "eu" ], "friends": [ { "id": 0, "name": "Payne Bender" }, { "id": 1, "name": "Lilia Norton" }, { "id": 2, "name": "Berry Mosley" }, { "id": 3, "name": "Patricia Ray" }, { "id": 4, "name": "Carson Banks" } ], "greeting": "Hello, Long Jennings! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826ce8c4a68d57f3fd7", "index": 260, "guid": "a5a7403d-6411-4e24-917e-e58387405c20", "isActive": false, "balance": "$2,260.72", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "brown", "name": "Susanna Bennett", "gender": "female", "company": "CHILLIUM", "email": "susannabennett@chillium.com", "phone": "+1 (873) 588-2268", "address": "970 Poplar Avenue, Delwood, Pennsylvania, 2410", "about": "Esse duis est exercitation magna anim esse sunt exercitation reprehenderit. Ea nisi fugiat non velit Lorem quis incididunt excepteur minim aliquip cupidatat cillum. Irure anim nostrud quis velit labore sit ut eu tempor anim cupidatat commodo aliquip. Deserunt ullamco magna ullamco dolor nisi fugiat officia commodo laboris ad aliquip. Laborum quis pariatur ex consequat eiusmod proident.\r\n", "registered": "2016-12-29T02:50:43 -01:00", "latitude": -59.325523, "longitude": 36.24346, "tags": [ "deserunt", "id", "occaecat", "ipsum", "pariatur", "officia", "ex", "Lorem", "deserunt", "laborum" ], "friends": [ { "id": 0, "name": "Angelique Orr" }, { "id": 1, "name": "Rosa Stanton" }, { "id": 2, "name": "Jeannine Bryant" }, { "id": 3, "name": "Vanessa Petty" }, { "id": 4, "name": "Leona Weber" } ], "greeting": "Hello, Susanna Bennett! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b3b468acfc137603", "index": 261, "guid": "a62738b9-921f-4a8d-bbf8-95cf7087dffd", "isActive": false, "balance": "$2,998.17", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Rosemary Romero", "gender": "female", "company": "GENMOM", "email": "rosemaryromero@genmom.com", "phone": "+1 (872) 449-3317", "address": "915 Lloyd Court, Downsville, Arkansas, 3249", "about": "Dolor et ipsum nostrud excepteur excepteur pariatur non. Laboris sit sunt exercitation est quis consectetur officia reprehenderit enim. Velit ad reprehenderit elit reprehenderit culpa ullamco adipisicing exercitation commodo minim nostrud proident. Commodo minim proident consectetur ipsum magna sint ad eu esse. Dolor dolor enim non incididunt proident laborum ullamco culpa laborum.\r\n", "registered": "2014-11-26T06:57:03 -01:00", "latitude": 61.364999, "longitude": -175.255716, "tags": [ "in", "sint", "voluptate", "mollit", "reprehenderit", "quis", "ex", "eiusmod", "consectetur", "do" ], "friends": [ { "id": 0, "name": "Oneil Price" }, { "id": 1, "name": "Rosalyn Steele" }, { "id": 2, "name": "Hoffman Stark" }, { "id": 3, "name": "Marta Alston" }, { "id": 4, "name": "Stanton Norman" } ], "greeting": "Hello, Rosemary Romero! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c1b66b7379a6ff0e", "index": 262, "guid": "35a786c9-bf4b-4f0d-9c1d-f1f1dfffb311", "isActive": false, "balance": "$2,330.12", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "brown", "name": "Pratt Morrow", "gender": "male", "company": "PIGZART", "email": "prattmorrow@pigzart.com", "phone": "+1 (874) 515-2719", "address": "417 Arkansas Drive, Irwin, Palau, 1438", "about": "Tempor sit elit exercitation duis est. Commodo minim aute consequat sunt. Esse laborum et voluptate veniam excepteur ad consequat et dolore. Exercitation laboris cillum ex nulla voluptate fugiat sunt consequat adipisicing esse proident quis est duis. Mollit ad pariatur proident ullamco sit mollit mollit. Et Lorem consequat sunt adipisicing aute occaecat aute consectetur ut cillum laboris ex tempor. Do consectetur do nostrud anim laborum adipisicing consequat tempor sit.\r\n", "registered": "2014-02-25T02:57:53 -01:00", "latitude": -41.092561, "longitude": -164.939045, "tags": [ "enim", "est", "Lorem", "nostrud", "cupidatat", "fugiat", "deserunt", "sint", "reprehenderit", "voluptate" ], "friends": [ { "id": 0, "name": "Lola Bowers" }, { "id": 1, "name": "Kara Crawford" }, { "id": 2, "name": "Mack Robbins" }, { "id": 3, "name": "Britney Silva" }, { "id": 4, "name": "Marcia Kaufman" } ], "greeting": "Hello, Pratt Morrow! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826ec22a3084a6c7619", "index": 263, "guid": "4531780c-4533-44c8-aa87-16c22292e94c", "isActive": true, "balance": "$2,800.34", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "blue", "name": "Bridges Crane", "gender": "male", "company": "HANDSHAKE", "email": "bridgescrane@handshake.com", "phone": "+1 (900) 579-2871", "address": "735 Hampton Avenue, Urbana, Connecticut, 2790", "about": "Nulla cillum dolore dolor sit nisi do. Irure esse elit sint pariatur aliquip dolor eiusmod do. Adipisicing aliqua aliqua laboris nisi ullamco qui laborum ex sit magna veniam eu aute consequat. Reprehenderit irure duis adipisicing consequat non irure in quis minim amet occaecat proident.\r\n", "registered": "2016-01-21T06:16:03 -01:00", "latitude": 30.799571, "longitude": -58.942027, "tags": [ "nostrud", "reprehenderit", "magna", "tempor", "Lorem", "tempor", "ipsum", "quis", "laborum", "proident" ], "friends": [ { "id": 0, "name": "Betty Robertson" }, { "id": 1, "name": "Tara Rosa" }, { "id": 2, "name": "Alissa Mccarthy" }, { "id": 3, "name": "Isabella Pace" }, { "id": 4, "name": "Hopkins Parker" } ], "greeting": "Hello, Bridges Crane! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826a88c4adffc3883fa", "index": 264, "guid": "443fcedf-3a14-4065-a4cd-649bfadda95d", "isActive": true, "balance": "$3,897.91", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Ernestine Francis", "gender": "female", "company": "BUNGA", "email": "ernestinefrancis@bunga.com", "phone": "+1 (831) 559-3735", "address": "836 Cobek Court, Cucumber, North Carolina, 6422", "about": "Occaecat dolor excepteur duis duis. Duis nisi mollit fugiat consequat quis excepteur sint velit dolor officia. Eu excepteur tempor elit magna amet. Proident veniam proident cillum in reprehenderit adipisicing. Pariatur velit do incididunt laboris. Laboris aliqua mollit eu ex cillum tempor cillum laboris est reprehenderit sunt laborum. Dolore labore in do deserunt pariatur elit do consectetur est non.\r\n", "registered": "2014-07-15T07:15:06 -02:00", "latitude": -28.958152, "longitude": -132.095365, "tags": [ "quis", "eu", "deserunt", "mollit", "exercitation", "Lorem", "est", "labore", "consectetur", "eiusmod" ], "friends": [ { "id": 0, "name": "Ida Tyler" }, { "id": 1, "name": "Parker Dejesus" }, { "id": 2, "name": "Delia Bonner" }, { "id": 3, "name": "Rollins Macias" }, { "id": 4, "name": "Lewis Ayala" } ], "greeting": "Hello, Ernestine Francis! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48266f0655e3a8e42fb0", "index": 265, "guid": "fa1f13a2-ecd9-4fdf-a301-59f3d3b85295", "isActive": false, "balance": "$3,399.14", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Linda Cherry", "gender": "female", "company": "AUSTECH", "email": "lindacherry@austech.com", "phone": "+1 (903) 461-2868", "address": "615 Remsen Street, Katonah, Missouri, 749", "about": "Ipsum duis minim sint velit deserunt ullamco esse duis nisi non. Mollit sunt voluptate est incididunt sunt nostrud quis qui nisi excepteur sunt et dolore. Cillum adipisicing minim Lorem enim commodo ullamco reprehenderit. In minim incididunt dolore irure sint. Aute tempor enim cupidatat et voluptate et nulla consectetur culpa.\r\n", "registered": "2017-07-22T06:01:23 -02:00", "latitude": 85.814106, "longitude": 128.916674, "tags": [ "sunt", "ex", "proident", "aliqua", "eu", "mollit", "elit", "dolor", "laborum", "quis" ], "friends": [ { "id": 0, "name": "Good Long" }, { "id": 1, "name": "Helena Burgess" }, { "id": 2, "name": "Alvarez Jefferson" }, { "id": 3, "name": "Leann Oliver" }, { "id": 4, "name": "Claudette Barton" } ], "greeting": "Hello, Linda Cherry! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826d6f0e5398cf75f5d", "index": 266, "guid": "78086786-053f-4f93-82aa-bfa109e72a76", "isActive": false, "balance": "$1,369.33", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Mclaughlin Olson", "gender": "male", "company": "DATAGENE", "email": "mclaughlinolson@datagene.com", "phone": "+1 (944) 551-3187", "address": "511 Aitken Place, Harold, Ohio, 8068", "about": "Id quis ad occaecat occaecat. Cupidatat quis velit officia laborum consectetur consequat ad non ut occaecat mollit. Officia velit irure ullamco deserunt in eu ut anim. Duis aliqua exercitation irure laboris nostrud consectetur irure sint nostrud Lorem non elit ullamco nisi. Labore cupidatat incididunt ullamco labore tempor duis non nulla.\r\n", "registered": "2017-12-18T09:38:58 -01:00", "latitude": 6.285162, "longitude": 32.111192, "tags": [ "eiusmod", "eiusmod", "dolore", "fugiat", "sint", "tempor", "culpa", "aliquip", "officia", "veniam" ], "friends": [ { "id": 0, "name": "Olson Stephens" }, { "id": 1, "name": "Hughes Miller" }, { "id": 2, "name": "Lydia Zimmerman" }, { "id": 3, "name": "Estrada Fry" }, { "id": 4, "name": "Dillon Waters" } ], "greeting": "Hello, Mclaughlin Olson! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48264a51b493ee904e07", "index": 267, "guid": "762c5c85-652d-4036-8b89-4fd1d278f418", "isActive": true, "balance": "$1,318.91", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Ford Hayden", "gender": "male", "company": "PROXSOFT", "email": "fordhayden@proxsoft.com", "phone": "+1 (890) 504-2900", "address": "735 Creamer Street, Monument, Arizona, 2514", "about": "Est officia dolor ipsum ex. Laborum irure laboris enim Lorem irure velit sint consequat culpa consectetur dolore mollit nisi. Aliquip ullamco fugiat eiusmod cupidatat voluptate quis tempor ut veniam. Nostrud minim aliquip excepteur veniam ullamco consequat excepteur duis adipisicing ex et. Excepteur adipisicing anim laboris laborum. Deserunt nulla incididunt adipisicing officia tempor id ut minim excepteur eiusmod ex. Adipisicing consectetur qui Lorem reprehenderit sunt voluptate laboris ex sit id ut aliquip reprehenderit ex.\r\n", "registered": "2015-07-13T05:29:01 -02:00", "latitude": -63.565195, "longitude": 38.726864, "tags": [ "dolore", "laborum", "esse", "labore", "velit", "laborum", "pariatur", "consectetur", "enim", "laboris" ], "friends": [ { "id": 0, "name": "Sally Pennington" }, { "id": 1, "name": "Landry Donovan" }, { "id": 2, "name": "Leach Carey" }, { "id": 3, "name": "Vera Love" }, { "id": 4, "name": "Mills Frye" } ], "greeting": "Hello, Ford Hayden! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826a86d34b9b154e201", "index": 268, "guid": "f2994fa4-ead8-4dea-a94d-977676adcdb0", "isActive": true, "balance": "$3,779.53", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Holloway Callahan", "gender": "male", "company": "BLANET", "email": "hollowaycallahan@blanet.com", "phone": "+1 (907) 433-3458", "address": "991 Devoe Street, Riviera, Montana, 3930", "about": "Elit esse proident anim ullamco. Ad eu aliquip minim mollit excepteur occaecat mollit. Laboris ea consequat qui qui quis ipsum. Cillum deserunt magna officia minim. Cillum amet velit nostrud labore sit labore minim laboris velit et ut eu.\r\n", "registered": "2014-01-06T02:03:51 -01:00", "latitude": 27.818712, "longitude": -110.713933, "tags": [ "pariatur", "nostrud", "ullamco", "id", "commodo", "Lorem", "anim", "magna", "excepteur", "laboris" ], "friends": [ { "id": 0, "name": "Suzette Winters" }, { "id": 1, "name": "Hines Gilliam" }, { "id": 2, "name": "Marci Melton" }, { "id": 3, "name": "Barbra Carrillo" }, { "id": 4, "name": "Hopper Warner" } ], "greeting": "Hello, Holloway Callahan! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48264c084b99c874f52a", "index": 269, "guid": "b80925a0-a92d-404b-a632-6b9ea6712d74", "isActive": true, "balance": "$1,184.14", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "brown", "name": "Hardy Alford", "gender": "male", "company": "FLOTONIC", "email": "hardyalford@flotonic.com", "phone": "+1 (999) 571-2057", "address": "315 Clymer Street, Chamberino, Texas, 7798", "about": "Dolore cillum veniam excepteur do amet veniam cillum esse id. Aute proident eu nostrud in incididunt ad aliquip labore in exercitation fugiat id nisi adipisicing. Amet minim ipsum ut adipisicing laboris ipsum exercitation. Velit ea commodo ea velit.\r\n", "registered": "2014-02-15T09:05:26 -01:00", "latitude": 58.364122, "longitude": 10.920249, "tags": [ "dolor", "aliqua", "irure", "eiusmod", "et", "deserunt", "in", "Lorem", "commodo", "quis" ], "friends": [ { "id": 0, "name": "Margarita Cline" }, { "id": 1, "name": "Anita Velasquez" }, { "id": 2, "name": "Bond Mckee" }, { "id": 3, "name": "Stephanie Hebert" }, { "id": 4, "name": "Maxwell Sykes" } ], "greeting": "Hello, Hardy Alford! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48263a547a08cad597e2", "index": 270, "guid": "7a197101-40a2-4630-9ab5-4b86438524ba", "isActive": false, "balance": "$2,579.54", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Dennis Blair", "gender": "male", "company": "STREZZO", "email": "dennisblair@strezzo.com", "phone": "+1 (969) 434-3769", "address": "625 Atkins Avenue, Kaka, Washington, 9986", "about": "Adipisicing aliquip tempor id Lorem anim. Sint do reprehenderit cupidatat nisi id consequat pariatur sit id. Ipsum elit id laboris in cupidatat exercitation reprehenderit amet aute. Mollit deserunt exercitation nostrud eu pariatur dolor mollit Lorem ea quis culpa voluptate. Non aliquip Lorem ut est eu nostrud.\r\n", "registered": "2016-09-01T11:15:56 -02:00", "latitude": -84.478004, "longitude": -96.193019, "tags": [ "veniam", "excepteur", "enim", "id", "velit", "ea", "velit", "sit", "reprehenderit", "excepteur" ], "friends": [ { "id": 0, "name": "Sanchez Roach" }, { "id": 1, "name": "Alyce Mitchell" }, { "id": 2, "name": "Sylvia Vincent" }, { "id": 3, "name": "Marjorie Austin" }, { "id": 4, "name": "Desiree Glover" } ], "greeting": "Hello, Dennis Blair! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826edd9192a7653d908", "index": 271, "guid": "5b9475bd-6f48-497d-b135-c2678b8188b4", "isActive": true, "balance": "$2,544.48", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Harrell Goodwin", "gender": "male", "company": "ZAPPIX", "email": "harrellgoodwin@zappix.com", "phone": "+1 (950) 531-2251", "address": "317 Williams Court, Dowling, Wyoming, 7595", "about": "Ut sunt ut occaecat do nulla veniam dolore non id excepteur. Lorem aute anim sunt enim laboris enim velit occaecat amet. Veniam commodo eiusmod veniam non.\r\n", "registered": "2014-08-07T12:55:41 -02:00", "latitude": 75.610176, "longitude": 1.378064, "tags": [ "sunt", "occaecat", "sint", "eiusmod", "culpa", "esse", "sunt", "do", "commodo", "exercitation" ], "friends": [ { "id": 0, "name": "Judy Compton" }, { "id": 1, "name": "Rowena Wooten" }, { "id": 2, "name": "Tessa Harding" }, { "id": 3, "name": "Waller Spears" }, { "id": 4, "name": "Roy Giles" } ], "greeting": "Hello, Harrell Goodwin! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826816d53a5c33740f0", "index": 272, "guid": "a31cb9c3-82e5-43b0-9f45-0940cbf4655e", "isActive": true, "balance": "$2,331.24", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "green", "name": "Katina Branch", "gender": "female", "company": "TELEQUIET", "email": "katinabranch@telequiet.com", "phone": "+1 (982) 590-2803", "address": "526 Lott Street, Nettie, Indiana, 9372", "about": "Mollit occaecat minim tempor ex culpa mollit. In labore et veniam quis sit cillum adipisicing magna ad qui reprehenderit consectetur mollit. Ullamco quis et voluptate esse consectetur minim ad est pariatur consectetur nulla dolor velit. Nostrud elit nostrud laborum exercitation ex anim Lorem est. Id incididunt amet adipisicing irure laborum sunt. In veniam commodo id culpa adipisicing tempor fugiat nostrud occaecat velit eiusmod.\r\n", "registered": "2015-02-09T02:17:56 -01:00", "latitude": 57.230135, "longitude": 115.556146, "tags": [ "velit", "consectetur", "sint", "ut", "adipisicing", "elit", "amet", "cupidatat", "adipisicing", "commodo" ], "friends": [ { "id": 0, "name": "Gamble Mathis" }, { "id": 1, "name": "Hudson Carpenter" }, { "id": 2, "name": "Patterson Blanchard" }, { "id": 3, "name": "Ross Mullen" }, { "id": 4, "name": "Bell Howe" } ], "greeting": "Hello, Katina Branch! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f33b94531cdfbbc0", "index": 273, "guid": "d4777c96-42c8-4f2a-a876-0d7e2627e361", "isActive": true, "balance": "$1,273.62", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "brown", "name": "Eve Decker", "gender": "female", "company": "INSOURCE", "email": "evedecker@insource.com", "phone": "+1 (994) 477-3694", "address": "856 President Street, Coral, Alabama, 8421", "about": "Non do dolore ex adipisicing eu do aliqua eu ex ex sit. Cillum labore aliqua mollit amet id fugiat occaecat aute. Et adipisicing voluptate aliqua qui cupidatat reprehenderit veniam proident tempor. Est nisi occaecat exercitation qui magna ipsum amet duis. Sint dolore anim officia officia consequat ad veniam dolor aliquip et nisi duis ad exercitation. Officia ullamco ullamco ea deserunt labore nostrud irure do officia minim minim anim et.\r\n", "registered": "2014-12-05T04:36:04 -01:00", "latitude": 74.450343, "longitude": 5.770369, "tags": [ "velit", "aliquip", "laborum", "amet", "et", "non", "voluptate", "voluptate", "deserunt", "non" ], "friends": [ { "id": 0, "name": "Nicholson Flowers" }, { "id": 1, "name": "Frankie Britt" }, { "id": 2, "name": "Nguyen Slater" }, { "id": 3, "name": "Jordan Whitaker" }, { "id": 4, "name": "Tabitha Weeks" } ], "greeting": "Hello, Eve Decker! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c2607f809e6cbe52", "index": 274, "guid": "e35e5169-b0fb-46cf-9e99-9e971082a996", "isActive": true, "balance": "$2,600.22", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Dickerson Faulkner", "gender": "male", "company": "PULZE", "email": "dickersonfaulkner@pulze.com", "phone": "+1 (813) 568-3617", "address": "944 Arion Place, Hamilton, Virginia, 1800", "about": "Dolor ad anim irure reprehenderit magna. Ipsum ad nisi qui laborum aute voluptate id deserunt enim. Ex exercitation mollit dolore anim sunt irure quis voluptate. Exercitation officia nostrud adipisicing eiusmod labore ullamco aliqua ipsum magna. Consequat ullamco sunt esse consequat cupidatat pariatur in excepteur. Velit adipisicing magna aute magna labore aute commodo laborum.\r\n", "registered": "2017-03-23T04:29:17 -01:00", "latitude": 45.665693, "longitude": 139.346597, "tags": [ "duis", "minim", "magna", "Lorem", "nisi", "quis", "est", "exercitation", "proident", "sint" ], "friends": [ { "id": 0, "name": "Rena Morales" }, { "id": 1, "name": "Anne Schmidt" }, { "id": 2, "name": "Tucker Mathews" }, { "id": 3, "name": "Vilma Hodge" }, { "id": 4, "name": "Fisher Sheppard" } ], "greeting": "Hello, Dickerson Faulkner! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826cab063a6ab2f2cb7", "index": 275, "guid": "2933a137-fbd0-4130-b52f-1cb48c459827", "isActive": false, "balance": "$2,567.23", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Lenore Alvarado", "gender": "female", "company": "DUOFLEX", "email": "lenorealvarado@duoflex.com", "phone": "+1 (875) 491-2853", "address": "552 Ingraham Street, Jennings, New Mexico, 6346", "about": "Aute eu fugiat aute sit amet et eu irure. Amet ut pariatur ex nisi dolore elit irure sint ipsum aliqua enim aute non. Sit est commodo nostrud duis eu enim proident et ullamco labore amet. Exercitation veniam duis officia reprehenderit eiusmod nisi.\r\n", "registered": "2014-12-30T07:00:10 -01:00", "latitude": 39.05356, "longitude": -51.73412, "tags": [ "adipisicing", "irure", "aliquip", "occaecat", "et", "culpa", "in", "labore", "proident", "consequat" ], "friends": [ { "id": 0, "name": "Lora Mckay" }, { "id": 1, "name": "Shirley Bradshaw" }, { "id": 2, "name": "Chavez Owens" }, { "id": 3, "name": "Foley Woodard" }, { "id": 4, "name": "Jenkins Miranda" } ], "greeting": "Hello, Lenore Alvarado! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261321c6b194033f80", "index": 276, "guid": "7c520b80-b787-449a-8919-8f931bc82b12", "isActive": true, "balance": "$1,206.65", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Kirsten Hamilton", "gender": "female", "company": "SOLGAN", "email": "kirstenhamilton@solgan.com", "phone": "+1 (907) 473-3638", "address": "123 Oxford Street, Rosewood, Hawaii, 9372", "about": "Ex aliqua ipsum et dolor nisi excepteur eu veniam tempor voluptate fugiat sunt aliquip. Consequat duis incididunt nostrud officia consectetur do amet ea ea nulla sit dolore esse voluptate. Consequat laborum incididunt enim elit irure. Ex amet sunt amet in labore officia incididunt culpa. Veniam cillum aliqua anim consectetur minim aute amet aliqua sint voluptate sunt. Cillum mollit amet ut laboris ex consequat ex enim. Amet deserunt consectetur magna ad culpa velit.\r\n", "registered": "2016-10-19T05:17:49 -02:00", "latitude": -37.864621, "longitude": 121.672501, "tags": [ "dolore", "voluptate", "qui", "minim", "occaecat", "Lorem", "quis", "culpa", "officia", "sunt" ], "friends": [ { "id": 0, "name": "Wolfe Matthews" }, { "id": 1, "name": "Millie Cohen" }, { "id": 2, "name": "House Trujillo" }, { "id": 3, "name": "Brigitte Calhoun" }, { "id": 4, "name": "Thomas Duffy" } ], "greeting": "Hello, Kirsten Hamilton! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482665522944a47c04e0", "index": 277, "guid": "4a8af9cc-4b9a-4473-a67d-c822d5f323e0", "isActive": true, "balance": "$1,736.04", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "brown", "name": "Jensen Mcfarland", "gender": "male", "company": "ACCUSAGE", "email": "jensenmcfarland@accusage.com", "phone": "+1 (819) 570-2060", "address": "101 Holt Court, Woodlake, Nebraska, 5533", "about": "Officia voluptate dolor quis eu excepteur quis qui mollit enim deserunt magna et fugiat. Ea adipisicing incididunt id enim eiusmod duis minim officia ipsum ad irure. Anim duis excepteur id in occaecat id duis exercitation sunt cillum qui commodo veniam. Nisi mollit ut anim nostrud ex minim.\r\n", "registered": "2017-12-13T08:05:58 -01:00", "latitude": 61.544049, "longitude": -61.406785, "tags": [ "ut", "fugiat", "esse", "ex", "tempor", "reprehenderit", "officia", "sit", "nisi", "laborum" ], "friends": [ { "id": 0, "name": "Bullock Strong" }, { "id": 1, "name": "Reid May" }, { "id": 2, "name": "Ophelia Lynch" }, { "id": 3, "name": "Jennings Reese" }, { "id": 4, "name": "Diaz Forbes" } ], "greeting": "Hello, Jensen Mcfarland! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826b828855f6137875b", "index": 278, "guid": "872e5272-85ca-4d10-965d-b92a3ba872b1", "isActive": true, "balance": "$2,666.98", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Cortez Summers", "gender": "male", "company": "TERRAGO", "email": "cortezsummers@terrago.com", "phone": "+1 (951) 521-2482", "address": "761 Sullivan Place, Winston, New York, 3488", "about": "Id dolor culpa aliquip aute duis excepteur. Et labore est est commodo enim id culpa veniam. Laboris duis in mollit ullamco ullamco excepteur laboris proident anim et nisi reprehenderit ex dolor. Pariatur ex aliqua mollit fugiat veniam. Consequat duis fugiat ipsum id irure voluptate. Quis ullamco cupidatat ex laboris labore ex mollit veniam deserunt veniam. Minim labore ad culpa dolore irure tempor cillum laborum non sint fugiat.\r\n", "registered": "2017-10-29T05:27:04 -01:00", "latitude": -59.455191, "longitude": 130.561951, "tags": [ "labore", "sit", "labore", "voluptate", "magna", "proident", "velit", "do", "exercitation", "do" ], "friends": [ { "id": 0, "name": "Contreras Lloyd" }, { "id": 1, "name": "Norman Potter" }, { "id": 2, "name": "Vincent Aguirre" }, { "id": 3, "name": "Margaret Gallagher" }, { "id": 4, "name": "Ila Rivers" } ], "greeting": "Hello, Cortez Summers! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48261771feb002ddfdfe", "index": 279, "guid": "a6f23614-aaab-40fa-8e5c-373e8c264c41", "isActive": false, "balance": "$1,916.90", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Anderson Nash", "gender": "male", "company": "BUZZWORKS", "email": "andersonnash@buzzworks.com", "phone": "+1 (885) 428-2025", "address": "530 Withers Street, Brooktrails, Marshall Islands, 361", "about": "Ipsum quis minim magna amet occaecat ipsum dolore. Non commodo minim nulla Lorem quis ut deserunt ex labore dolore nostrud esse minim in. Sunt do pariatur sunt tempor nisi. Adipisicing voluptate laboris veniam dolore aute.\r\n", "registered": "2014-06-17T07:21:22 -02:00", "latitude": 62.928055, "longitude": -37.095623, "tags": [ "adipisicing", "id", "esse", "ea", "do", "et", "ullamco", "enim", "consectetur", "ad" ], "friends": [ { "id": 0, "name": "Page Hahn" }, { "id": 1, "name": "Jacklyn Kramer" }, { "id": 2, "name": "Acevedo Estes" }, { "id": 3, "name": "Eula Hensley" }, { "id": 4, "name": "Peters Barrera" } ], "greeting": "Hello, Anderson Nash! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ea4bedb50342efff", "index": 280, "guid": "100f4316-f84b-4f29-88d4-ed10db37d3bb", "isActive": true, "balance": "$3,258.83", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Daniel Franklin", "gender": "male", "company": "PATHWAYS", "email": "danielfranklin@pathways.com", "phone": "+1 (809) 414-2845", "address": "980 Brown Street, Haena, Oregon, 7161", "about": "Voluptate aute consectetur ullamco sunt. Aliqua enim elit labore quis cupidatat commodo cupidatat culpa. Ipsum labore dolore consequat dolor elit. Laboris nulla in duis nostrud ad. Duis velit aliqua culpa do tempor sint aliquip cillum eiusmod ut anim quis adipisicing tempor.\r\n", "registered": "2014-10-22T09:13:57 -02:00", "latitude": 54.807819, "longitude": 51.231653, "tags": [ "deserunt", "aute", "mollit", "nulla", "consequat", "voluptate", "do", "proident", "sunt", "nulla" ], "friends": [ { "id": 0, "name": "Lee Tran" }, { "id": 1, "name": "Effie Gonzalez" }, { "id": 2, "name": "Noelle Knowles" }, { "id": 3, "name": "Crawford Cannon" }, { "id": 4, "name": "Luann Sampson" } ], "greeting": "Hello, Daniel Franklin! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48266d088877d3c14a14", "index": 281, "guid": "b40d3ea8-42db-418f-aa89-1101259917c4", "isActive": true, "balance": "$3,316.28", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Alvarado Case", "gender": "male", "company": "DAYCORE", "email": "alvaradocase@daycore.com", "phone": "+1 (945) 549-3944", "address": "204 Woodside Avenue, Roderfield, Tennessee, 5280", "about": "Excepteur nisi reprehenderit velit aliquip id et laboris minim ipsum minim deserunt sint ut. Labore ex id incididunt ipsum voluptate aliquip ullamco culpa nulla anim. Ipsum deserunt enim Lorem officia irure et mollit veniam duis velit Lorem sit. Qui officia tempor quis quis est laborum. Amet laboris magna proident dolor et minim culpa qui sit labore Lorem nostrud qui aliqua. Ex ullamco exercitation veniam fugiat consectetur nostrud id eu sint pariatur ex.\r\n", "registered": "2015-11-03T03:47:16 -01:00", "latitude": 11.269017, "longitude": 77.489646, "tags": [ "exercitation", "ad", "id", "fugiat", "laborum", "occaecat", "irure", "reprehenderit", "duis", "esse" ], "friends": [ { "id": 0, "name": "Calhoun Dean" }, { "id": 1, "name": "Holly Bond" }, { "id": 2, "name": "Howe Keith" }, { "id": 3, "name": "Jennifer Vaughan" }, { "id": 4, "name": "Robbie Ryan" } ], "greeting": "Hello, Alvarado Case! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48265f8b699cd3e62b56", "index": 282, "guid": "f30f8239-3875-4a3f-9ce4-86dd5ae9f163", "isActive": false, "balance": "$1,871.73", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Opal Kelley", "gender": "female", "company": "KONGLE", "email": "opalkelley@kongle.com", "phone": "+1 (982) 545-3608", "address": "156 Lawrence Avenue, Vallonia, Nevada, 4790", "about": "Culpa ut in aliquip sunt. In irure officia sit sunt aliquip aliquip. Fugiat laboris velit reprehenderit voluptate magna. Laborum tempor adipisicing minim ex qui qui velit esse. Deserunt nostrud Lorem consequat exercitation excepteur sunt.\r\n", "registered": "2018-01-07T07:36:48 -01:00", "latitude": -60.150152, "longitude": 115.807517, "tags": [ "ea", "dolore", "sit", "exercitation", "laboris", "proident", "anim", "duis", "minim", "non" ], "friends": [ { "id": 0, "name": "Roach Swanson" }, { "id": 1, "name": "Lois Roth" }, { "id": 2, "name": "Esperanza Powers" }, { "id": 3, "name": "Tammi Gould" }, { "id": 4, "name": "Dean Dotson" } ], "greeting": "Hello, Opal Kelley! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48267b53a690529f727d", "index": 283, "guid": "4172a5be-b059-4c94-b8bc-cbe4b4e26899", "isActive": false, "balance": "$1,575.15", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Lester Rice", "gender": "male", "company": "COMFIRM", "email": "lesterrice@comfirm.com", "phone": "+1 (875) 551-2662", "address": "621 Crescent Street, Cliff, Alaska, 2695", "about": "Velit ut excepteur sit veniam pariatur irure. Qui incididunt commodo deserunt nostrud deserunt Lorem. Duis velit anim magna voluptate consectetur pariatur et amet eu ullamco deserunt do. Ipsum aute fugiat sint id mollit. Aliqua cillum irure exercitation aute est labore cillum aute. Pariatur pariatur dolore esse cillum ut mollit duis consectetur pariatur ea. Sunt laborum in duis adipisicing proident reprehenderit labore aliqua culpa mollit.\r\n", "registered": "2016-02-11T07:46:46 -01:00", "latitude": 89.213509, "longitude": 58.864479, "tags": [ "non", "exercitation", "nisi", "labore", "deserunt", "dolore", "veniam", "duis", "irure", "aliqua" ], "friends": [ { "id": 0, "name": "Delacruz Clark" }, { "id": 1, "name": "Love Stein" }, { "id": 2, "name": "Latonya Mooney" }, { "id": 3, "name": "Stacey Fisher" }, { "id": 4, "name": "Carolyn Hester" } ], "greeting": "Hello, Lester Rice! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826a05a0a6a6a49779c", "index": 284, "guid": "16152415-13dc-4a61-a32a-d230027a7e83", "isActive": false, "balance": "$3,940.76", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "brown", "name": "Cochran Potts", "gender": "male", "company": "ROCKABYE", "email": "cochranpotts@rockabye.com", "phone": "+1 (894) 484-2971", "address": "485 Veranda Place, Spelter, Illinois, 5559", "about": "Officia velit irure cillum Lorem magna reprehenderit. Non exercitation dolor aliqua duis elit enim veniam anim esse laborum. Consectetur cupidatat anim et non tempor cupidatat aute aliquip magna elit nisi consectetur excepteur enim. Tempor anim aliqua adipisicing sint voluptate quis adipisicing qui eiusmod duis cupidatat. Ad cillum sit qui incididunt culpa Lorem incididunt aliquip ex laborum Lorem.\r\n", "registered": "2015-12-08T04:49:15 -01:00", "latitude": 62.770192, "longitude": 150.801404, "tags": [ "qui", "et", "cillum", "amet", "non", "adipisicing", "laborum", "duis", "quis", "enim" ], "friends": [ { "id": 0, "name": "Carney Hardy" }, { "id": 1, "name": "Beatrice Ellis" }, { "id": 2, "name": "Gay Wilkerson" }, { "id": 3, "name": "Maribel Meyer" }, { "id": 4, "name": "Snider Mcfadden" } ], "greeting": "Hello, Cochran Potts! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48263538d3931e7913f5", "index": 285, "guid": "288dc939-661b-4063-9993-88b0b08d11da", "isActive": false, "balance": "$1,349.37", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "green", "name": "Faith Garrett", "gender": "female", "company": "ZENSURE", "email": "faithgarrett@zensure.com", "phone": "+1 (991) 484-3156", "address": "827 Atlantic Avenue, Weedville, Oklahoma, 8231", "about": "Sint amet duis officia eiusmod ipsum duis laborum. Deserunt aliqua esse ea amet Lorem in amet in esse aute aliquip. Anim ipsum reprehenderit proident cillum aliqua nostrud Lorem officia do et ut laboris nostrud. Nostrud ipsum sint sit ea velit id. Adipisicing ipsum nulla irure commodo proident ea consectetur officia incididunt anim amet adipisicing voluptate.\r\n", "registered": "2017-09-25T04:53:50 -02:00", "latitude": -48.805608, "longitude": 171.755397, "tags": [ "do", "veniam", "duis", "sunt", "qui", "in", "ex", "velit", "commodo", "labore" ], "friends": [ { "id": 0, "name": "Curry Erickson" }, { "id": 1, "name": "Rosalie Small" }, { "id": 2, "name": "Abigail Fitzgerald" }, { "id": 3, "name": "Atkins Hodges" }, { "id": 4, "name": "Lucia Lara" } ], "greeting": "Hello, Faith Garrett! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826af1da360c5cb4f95", "index": 286, "guid": "68a06080-0ebf-4f92-bbfa-b5faa08d4ea0", "isActive": true, "balance": "$1,724.38", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "blue", "name": "Belinda Blankenship", "gender": "female", "company": "VELITY", "email": "belindablankenship@velity.com", "phone": "+1 (884) 538-3230", "address": "159 Irving Place, Detroit, Delaware, 9074", "about": "Ea veniam adipisicing aute occaecat ipsum veniam ex et sunt. Reprehenderit nostrud id consequat cillum qui duis ipsum magna ad ad cillum dolore. Est culpa officia magna dolor pariatur fugiat nisi mollit occaecat aliqua. Cupidatat ipsum ea deserunt elit nostrud anim dolore exercitation. Id id ut elit nostrud reprehenderit aute eiusmod qui proident labore nostrud ex sit voluptate. Enim irure ullamco exercitation pariatur aute exercitation qui consequat pariatur irure. Laboris velit consequat veniam duis esse.\r\n", "registered": "2016-02-23T01:13:41 -01:00", "latitude": 68.263436, "longitude": 2.639113, "tags": [ "aute", "ad", "nisi", "cillum", "irure", "consectetur", "id", "ad", "tempor", "cillum" ], "friends": [ { "id": 0, "name": "Workman Church" }, { "id": 1, "name": "Josefina Moses" }, { "id": 2, "name": "Violet Benjamin" }, { "id": 3, "name": "Lynne Mcintosh" }, { "id": 4, "name": "Rodriquez Townsend" } ], "greeting": "Hello, Belinda Blankenship! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826a706508cc53eaf0c", "index": 287, "guid": "d7085f33-d699-463a-ad7e-e600ef62e5a4", "isActive": false, "balance": "$1,294.20", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Potter Chen", "gender": "male", "company": "SCENTRIC", "email": "potterchen@scentric.com", "phone": "+1 (931) 542-2291", "address": "217 Hopkins Street, Cornfields, Federated States Of Micronesia, 7637", "about": "Aute tempor ex sit sint laboris ad culpa. Ad ipsum adipisicing ullamco aliqua consequat nostrud aliqua aute. Aute reprehenderit consequat irure et excepteur magna consectetur sunt proident dolor id et. Qui sint incididunt mollit id amet irure magna qui eiusmod. Lorem officia eu Lorem nisi cillum nisi. Cillum duis irure voluptate ad cillum officia esse officia non.\r\n", "registered": "2016-10-05T04:38:03 -02:00", "latitude": -77.275917, "longitude": -51.193159, "tags": [ "aliqua", "reprehenderit", "cillum", "elit", "minim", "reprehenderit", "labore", "ad", "incididunt", "culpa" ], "friends": [ { "id": 0, "name": "Garcia Freeman" }, { "id": 1, "name": "Cecile Willis" }, { "id": 2, "name": "Susana Baldwin" }, { "id": 3, "name": "Webster Blackwell" }, { "id": 4, "name": "Willa Fletcher" } ], "greeting": "Hello, Potter Chen! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482633d04190083fccb1", "index": 288, "guid": "f2df3152-549f-40f8-afba-781285e9ca96", "isActive": false, "balance": "$1,322.40", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Bertie Camacho", "gender": "female", "company": "ZIDANT", "email": "bertiecamacho@zidant.com", "phone": "+1 (933) 579-3179", "address": "762 Macdougal Street, Brookfield, Florida, 1340", "about": "Commodo consectetur occaecat non nostrud est sunt sunt incididunt mollit qui eiusmod laboris do esse. Et ex voluptate reprehenderit veniam sunt cillum et. Mollit deserunt non occaecat ut incididunt dolor nisi velit consequat ea sint. Nisi duis mollit Lorem ipsum velit in. Quis nostrud officia ipsum dolore in cillum nostrud minim et labore adipisicing laboris consequat ad. In id reprehenderit in sunt Lorem pariatur officia incididunt elit proident sit cupidatat consectetur.\r\n", "registered": "2014-06-16T01:36:00 -02:00", "latitude": -14.277517, "longitude": 52.454594, "tags": [ "ex", "dolore", "eu", "enim", "qui", "deserunt", "duis", "amet", "cupidatat", "officia" ], "friends": [ { "id": 0, "name": "Whitney Curtis" }, { "id": 1, "name": "Gertrude Mckinney" }, { "id": 2, "name": "Lorie Mays" }, { "id": 3, "name": "Guzman Baxter" }, { "id": 4, "name": "Kathryn Blevins" } ], "greeting": "Hello, Bertie Camacho! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48269a1e5e54f9bd4c1b", "index": 289, "guid": "b0658e87-76db-4a93-8f85-b2ed6405126e", "isActive": true, "balance": "$1,081.06", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Sharp Daniel", "gender": "male", "company": "SIGNIDYNE", "email": "sharpdaniel@signidyne.com", "phone": "+1 (910) 597-2310", "address": "727 Canda Avenue, Comptche, Massachusetts, 8990", "about": "Occaecat consequat Lorem minim non mollit non est pariatur et duis. Nisi laborum nisi excepteur ad amet exercitation. Non cupidatat minim ad laborum. Exercitation ea occaecat ullamco irure aliquip reprehenderit fugiat occaecat tempor. Nulla magna veniam in et duis dolor ut labore fugiat Lorem id. Ipsum culpa sit sint et quis consectetur ad aliqua non.\r\n", "registered": "2014-04-04T12:51:37 -02:00", "latitude": 56.582024, "longitude": 14.031336, "tags": [ "est", "amet", "nisi", "minim", "sit", "excepteur", "dolore", "cillum", "elit", "cillum" ], "friends": [ { "id": 0, "name": "Russo Battle" }, { "id": 1, "name": "Brewer Ellison" }, { "id": 2, "name": "Reyna Bright" }, { "id": 3, "name": "Melissa Valentine" }, { "id": 4, "name": "Brooks Levine" } ], "greeting": "Hello, Sharp Daniel! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826a2896b36cc0dcd4d", "index": 290, "guid": "b312406f-0884-44a7-9e8e-a896131330bb", "isActive": false, "balance": "$1,675.56", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "brown", "name": "Logan Hill", "gender": "male", "company": "ORBAXTER", "email": "loganhill@orbaxter.com", "phone": "+1 (911) 506-2255", "address": "878 Lancaster Avenue, Newkirk, Mississippi, 6241", "about": "Pariatur cillum do sint ullamco velit anim nostrud duis irure voluptate ipsum. Laboris voluptate aliquip irure sint officia aliquip occaecat incididunt sit commodo qui nostrud labore. Esse et officia pariatur nulla commodo sunt laboris ad dolore sint laboris nisi aliquip non. Est ullamco laboris reprehenderit dolore occaecat ullamco deserunt reprehenderit id ut ipsum excepteur.\r\n", "registered": "2014-03-10T12:40:04 -01:00", "latitude": 5.57734, "longitude": -159.366198, "tags": [ "magna", "duis", "pariatur", "anim", "ea", "officia", "magna", "nulla", "consectetur", "velit" ], "friends": [ { "id": 0, "name": "Bettie Gentry" }, { "id": 1, "name": "Sue Anderson" }, { "id": 2, "name": "Irene Horne" }, { "id": 3, "name": "Lupe Edwards" }, { "id": 4, "name": "Cheri Macdonald" } ], "greeting": "Hello, Logan Hill! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48266af283b196548e47", "index": 291, "guid": "722c29f1-3196-44b8-8021-8da09280a432", "isActive": false, "balance": "$2,728.39", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Tamara Aguilar", "gender": "female", "company": "PHUEL", "email": "tamaraaguilar@phuel.com", "phone": "+1 (840) 511-3132", "address": "800 Ridgewood Avenue, Kenvil, Guam, 1286", "about": "Quis occaecat veniam esse esse laboris. Excepteur laborum mollit ex fugiat elit exercitation cupidatat adipisicing. Sint deserunt nisi voluptate exercitation irure consectetur enim aliqua. Lorem laborum eu ullamco pariatur laboris anim pariatur eiusmod proident ullamco qui laboris laborum commodo. Exercitation in aute aliqua cupidatat. Exercitation velit sit tempor ad adipisicing. Irure ad sint sunt enim dolore aliqua non aliquip commodo.\r\n", "registered": "2014-06-10T10:41:05 -02:00", "latitude": -21.177144, "longitude": -117.086328, "tags": [ "aliqua", "deserunt", "laborum", "reprehenderit", "irure", "consectetur", "exercitation", "incididunt", "labore", "non" ], "friends": [ { "id": 0, "name": "Gina Rosales" }, { "id": 1, "name": "Lillian Saunders" }, { "id": 2, "name": "Mcdonald Gaines" }, { "id": 3, "name": "Alma Richardson" }, { "id": 4, "name": "Gale Mueller" } ], "greeting": "Hello, Tamara Aguilar! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48265988707f139e0aa1", "index": 292, "guid": "2bfe1825-915c-4bec-a00d-0c270b1a9f19", "isActive": true, "balance": "$2,645.91", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Rodriguez Chavez", "gender": "male", "company": "PAPRICUT", "email": "rodriguezchavez@papricut.com", "phone": "+1 (835) 458-3662", "address": "291 Bank Street, Dahlen, Louisiana, 3057", "about": "Velit ullamco id excepteur commodo ut do mollit commodo et proident non. Aliquip consectetur amet fugiat exercitation amet anim magna amet nostrud amet ipsum deserunt voluptate. Veniam incididunt Lorem qui ea. Officia ad non dolore consectetur ex magna et amet ad eiusmod voluptate id.\r\n", "registered": "2014-10-28T05:10:28 -01:00", "latitude": 12.883183, "longitude": 24.961107, "tags": [ "pariatur", "incididunt", "magna", "sint", "magna", "velit", "ex", "excepteur", "quis", "ullamco" ], "friends": [ { "id": 0, "name": "Roberson Pruitt" }, { "id": 1, "name": "Brandie Monroe" }, { "id": 2, "name": "Renee Rodgers" }, { "id": 3, "name": "Lynnette Solomon" }, { "id": 4, "name": "Kent Herrera" } ], "greeting": "Hello, Rodriguez Chavez! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48262c33e6944e9ae9fa", "index": 293, "guid": "e4c70fca-1aab-4887-afb1-239583b45712", "isActive": true, "balance": "$2,193.47", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Poole Valencia", "gender": "male", "company": "LIMOZEN", "email": "poolevalencia@limozen.com", "phone": "+1 (969) 414-2327", "address": "205 Cyrus Avenue, Woodruff, South Dakota, 6620", "about": "Nisi exercitation aliquip fugiat non culpa veniam ut sit nisi ipsum esse incididunt dolor. Mollit dolor nostrud aliquip incididunt in ad aliqua incididunt sint fugiat officia consequat. Elit esse velit ut reprehenderit mollit tempor aliquip voluptate voluptate id tempor occaecat. Deserunt elit exercitation ex ex.\r\n", "registered": "2014-02-15T05:38:15 -01:00", "latitude": 59.565098, "longitude": -120.772304, "tags": [ "ex", "laborum", "labore", "Lorem", "est", "nostrud", "enim", "nisi", "labore", "qui" ], "friends": [ { "id": 0, "name": "Beverly Booth" }, { "id": 1, "name": "Brittney Blackburn" }, { "id": 2, "name": "Henson House" }, { "id": 3, "name": "Wallace Kirkland" }, { "id": 4, "name": "Melva Ford" } ], "greeting": "Hello, Poole Valencia! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826a137847e5f2069e9", "index": 294, "guid": "d4b6973a-666a-4251-bf9c-3b4f08784944", "isActive": false, "balance": "$2,576.27", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Lavonne Justice", "gender": "female", "company": "PROFLEX", "email": "lavonnejustice@proflex.com", "phone": "+1 (908) 571-2771", "address": "749 Stryker Court, Ola, District Of Columbia, 8860", "about": "Ex exercitation non amet in sunt quis nostrud irure. Velit laboris consequat elit dolor occaecat enim adipisicing anim dolor aliqua aute eiusmod cupidatat. Cupidatat veniam incididunt aliquip proident sit incididunt excepteur do minim qui adipisicing reprehenderit. Voluptate excepteur culpa excepteur eiusmod cupidatat nisi deserunt quis Lorem. Do nulla esse pariatur velit do. Mollit id sit excepteur mollit.\r\n", "registered": "2017-01-10T10:59:58 -01:00", "latitude": -31.563416, "longitude": 51.579267, "tags": [ "duis", "laborum", "amet", "ut", "qui", "in", "cillum", "ex", "do", "proident" ], "friends": [ { "id": 0, "name": "Jeanine Watkins" }, { "id": 1, "name": "Durham Valenzuela" }, { "id": 2, "name": "Reynolds Dennis" }, { "id": 3, "name": "Buckner Alexander" }, { "id": 4, "name": "Caitlin Hutchinson" } ], "greeting": "Hello, Lavonne Justice! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b853779c1dea355b", "index": 295, "guid": "b5123a3e-2899-4cfc-9a34-059a386c6f55", "isActive": false, "balance": "$2,903.90", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Norma Simmons", "gender": "female", "company": "ECRAZE", "email": "normasimmons@ecraze.com", "phone": "+1 (877) 537-3273", "address": "721 Claver Place, Gallina, Puerto Rico, 8581", "about": "Lorem excepteur reprehenderit et commodo elit reprehenderit aliqua sint dolore nostrud aliqua. Dolor do mollit anim elit. Duis dolore minim ea duis voluptate nostrud id velit minim elit ipsum. Ad est occaecat aute tempor.\r\n", "registered": "2017-07-20T09:56:22 -02:00", "latitude": -64.096888, "longitude": 57.557432, "tags": [ "proident", "enim", "elit", "amet", "duis", "pariatur", "duis", "amet", "mollit", "anim" ], "friends": [ { "id": 0, "name": "Vega Obrien" }, { "id": 1, "name": "Catalina Contreras" }, { "id": 2, "name": "Wyatt Lambert" }, { "id": 3, "name": "Concetta Lynn" }, { "id": 4, "name": "Tania Mcintyre" } ], "greeting": "Hello, Norma Simmons! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48266c841f2bf9a51e83", "index": 296, "guid": "7f8e6651-8e38-4747-9d5d-3531f1e6761d", "isActive": false, "balance": "$2,207.52", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "brown", "name": "Marsh Sherman", "gender": "male", "company": "GEEKULAR", "email": "marshsherman@geekular.com", "phone": "+1 (899) 472-3857", "address": "539 Bouck Court, Beechmont, Maine, 3609", "about": "Adipisicing cupidatat incididunt non Lorem aliqua excepteur reprehenderit deserunt elit duis anim laborum amet id. Magna incididunt consectetur ipsum tempor commodo ex sit cupidatat laborum enim. Et minim quis reprehenderit magna nisi ea nisi tempor sunt. Elit dolor non proident sunt sint magna. Fugiat et velit ut culpa occaecat deserunt sint cillum cillum proident.\r\n", "registered": "2016-06-17T03:32:05 -02:00", "latitude": -18.341689, "longitude": -102.630355, "tags": [ "culpa", "eu", "est", "id", "aute", "tempor", "officia", "cillum", "irure", "cillum" ], "friends": [ { "id": 0, "name": "Roxie Phillips" }, { "id": 1, "name": "Leon Boyer" }, { "id": 2, "name": "Mae Burke" }, { "id": 3, "name": "Matthews Daniels" }, { "id": 4, "name": "Nixon Graham" } ], "greeting": "Hello, Marsh Sherman! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48268e4578592282f781", "index": 297, "guid": "504df5c3-6fb3-41f4-8f25-77302c7ba91d", "isActive": true, "balance": "$1,560.20", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Cathryn Wright", "gender": "female", "company": "DARWINIUM", "email": "cathrynwright@darwinium.com", "phone": "+1 (955) 478-2632", "address": "389 Chestnut Avenue, Forbestown, New Jersey, 8135", "about": "Incididunt anim minim pariatur officia irure veniam consequat mollit do ullamco tempor consectetur tempor id. Deserunt quis consectetur quis Lorem ex proident fugiat ea consequat velit ea commodo aute. Consectetur ad elit amet incididunt.\r\n", "registered": "2017-10-28T08:47:32 -02:00", "latitude": 17.791309, "longitude": 49.64537, "tags": [ "duis", "exercitation", "do", "aliqua", "ipsum", "dolor", "deserunt", "consequat", "nisi", "nostrud" ], "friends": [ { "id": 0, "name": "Rebecca Holland" }, { "id": 1, "name": "Frieda Campbell" }, { "id": 2, "name": "Angelita Gilbert" }, { "id": 3, "name": "Esmeralda Bryan" }, { "id": 4, "name": "Bridgett Snow" } ], "greeting": "Hello, Cathryn Wright! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48267a65cdfb18ea59a8", "index": 298, "guid": "4e4b1751-e6da-493f-97d8-7f71dc4e0106", "isActive": false, "balance": "$3,770.43", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Blankenship Ewing", "gender": "male", "company": "LYRIA", "email": "blankenshipewing@lyria.com", "phone": "+1 (924) 551-2000", "address": "182 Anchorage Place, Adelino, Michigan, 383", "about": "Cupidatat ullamco aliqua sint labore velit consectetur enim ut. Officia ex ut et occaecat ad eu proident Lorem qui ad tempor velit laborum consectetur. Reprehenderit exercitation labore occaecat deserunt. Veniam ullamco occaecat irure dolore duis anim ea tempor anim veniam proident. Adipisicing dolore elit pariatur nulla aute.\r\n", "registered": "2014-06-14T09:58:16 -02:00", "latitude": 38.066736, "longitude": -49.518997, "tags": [ "excepteur", "proident", "tempor", "tempor", "reprehenderit", "dolore", "reprehenderit", "non", "est", "aute" ], "friends": [ { "id": 0, "name": "Banks Pacheco" }, { "id": 1, "name": "Aurora James" }, { "id": 2, "name": "Blake Cooper" }, { "id": 3, "name": "Zamora Peters" }, { "id": 4, "name": "Duran Drake" } ], "greeting": "Hello, Blankenship Ewing! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482641e5de0d7c0c8782", "index": 299, "guid": "055530d9-e629-4165-af79-1204f60273c8", "isActive": false, "balance": "$2,740.96", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "brown", "name": "Byrd Salinas", "gender": "male", "company": "PROSURE", "email": "byrdsalinas@prosure.com", "phone": "+1 (806) 491-3457", "address": "744 Waldane Court, Wedgewood, Rhode Island, 9011", "about": "Officia minim quis amet cillum deserunt nisi proident eiusmod irure eu. Sunt excepteur nulla laborum sint magna do occaecat magna ipsum nulla cupidatat nostrud consequat. Quis mollit elit et occaecat eiusmod est enim. Occaecat labore non eu commodo excepteur proident aliqua. Voluptate velit qui ad voluptate minim aliquip amet aliqua adipisicing id ea.\r\n", "registered": "2017-05-28T01:56:16 -02:00", "latitude": 77.996893, "longitude": 133.408838, "tags": [ "occaecat", "cillum", "laboris", "sint", "culpa", "sunt", "laboris", "ea", "ad", "tempor" ], "friends": [ { "id": 0, "name": "Nunez Carroll" }, { "id": 1, "name": "Gentry Bradley" }, { "id": 2, "name": "Selma Castaneda" }, { "id": 3, "name": "Head Morrison" }, { "id": 4, "name": "Le Pratt" } ], "greeting": "Hello, Byrd Salinas! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826e07531f2b80f0453", "index": 300, "guid": "5bb7ed7c-abc7-468a-82ab-d3904335a249", "isActive": false, "balance": "$3,420.62", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "blue", "name": "Pearson Hammond", "gender": "male", "company": "ZOXY", "email": "pearsonhammond@zoxy.com", "phone": "+1 (875) 569-3598", "address": "246 Loring Avenue, National, Kansas, 306", "about": "Ea ad eiusmod do laborum incididunt ullamco non sit cupidatat anim cillum. Laboris enim aliquip pariatur ullamco exercitation elit esse deserunt deserunt. Excepteur nisi dolore fugiat et id ad mollit ex consectetur do minim dolore. Esse duis ullamco ex velit sit ut adipisicing ut do aliquip Lorem irure ex.\r\n", "registered": "2017-09-19T04:51:34 -02:00", "latitude": -11.474492, "longitude": 165.343357, "tags": [ "aliqua", "ut", "aliquip", "non", "sunt", "adipisicing", "ipsum", "occaecat", "et", "mollit" ], "friends": [ { "id": 0, "name": "Sampson Nixon" }, { "id": 1, "name": "Gay Maldonado" }, { "id": 2, "name": "Nora Fleming" }, { "id": 3, "name": "Merle Wheeler" }, { "id": 4, "name": "Kenya Durham" } ], "greeting": "Hello, Pearson Hammond! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826d59c639dd9a3967a", "index": 301, "guid": "2f96202e-6fd5-46de-91c4-24f4ba772652", "isActive": true, "balance": "$1,204.15", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "brown", "name": "Hanson Frank", "gender": "male", "company": "GINKLE", "email": "hansonfrank@ginkle.com", "phone": "+1 (904) 495-2223", "address": "806 Shale Street, Maxville, West Virginia, 8441", "about": "Mollit occaecat in occaecat elit mollit adipisicing. Non commodo reprehenderit enim sunt velit excepteur non et ullamco est Lorem eiusmod. Reprehenderit pariatur do culpa et. Exercitation officia duis laborum ad minim ullamco veniam veniam in et proident. Reprehenderit quis in Lorem aute laborum amet.\r\n", "registered": "2016-01-01T02:43:03 -01:00", "latitude": -23.590007, "longitude": -139.729357, "tags": [ "occaecat", "eiusmod", "exercitation", "in", "fugiat", "aliqua", "incididunt", "aute", "commodo", "laboris" ], "friends": [ { "id": 0, "name": "Madeleine Wilkins" }, { "id": 1, "name": "Cindy Gibson" }, { "id": 2, "name": "Baird Parsons" }, { "id": 3, "name": "Levine Tucker" }, { "id": 4, "name": "Felicia Tillman" } ], "greeting": "Hello, Hanson Frank! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48266bda97d606c09c59", "index": 302, "guid": "f7d19784-7212-4fba-8735-305b69733e84", "isActive": true, "balance": "$1,848.31", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Carter Henson", "gender": "male", "company": "CYTREX", "email": "carterhenson@cytrex.com", "phone": "+1 (910) 524-2381", "address": "442 Dorset Street, Croom, American Samoa, 3514", "about": "Cupidatat elit pariatur consectetur Lorem. Enim deserunt sit enim ex cupidatat do minim ex. Sit pariatur duis est labore adipisicing dolor officia reprehenderit exercitation in consequat nulla do pariatur. Laboris culpa ipsum magna exercitation. Nisi culpa incididunt velit aliqua laborum qui veniam consequat veniam. Veniam excepteur labore ipsum adipisicing do adipisicing exercitation ut minim ex culpa reprehenderit mollit. Tempor ut ut et tempor cillum adipisicing enim.\r\n", "registered": "2016-02-07T02:41:58 -01:00", "latitude": -39.565334, "longitude": -28.72863, "tags": [ "cupidatat", "mollit", "consectetur", "dolor", "dolor", "velit", "esse", "consectetur", "dolore", "mollit" ], "friends": [ { "id": 0, "name": "Nola Lawrence" }, { "id": 1, "name": "Mueller Puckett" }, { "id": 2, "name": "Massey Bolton" }, { "id": 3, "name": "Hayes Nunez" }, { "id": 4, "name": "Brandi Hartman" } ], "greeting": "Hello, Carter Henson! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826863d1429401989ef", "index": 303, "guid": "c032b1df-9764-4022-b336-38a498c051fb", "isActive": false, "balance": "$2,280.83", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "blue", "name": "Beasley Velazquez", "gender": "male", "company": "GRACKER", "email": "beasleyvelazquez@gracker.com", "phone": "+1 (869) 406-3947", "address": "490 Fenimore Street, Adamstown, Maryland, 4952", "about": "Mollit aliquip amet minim non tempor amet amet et magna duis enim ullamco. Velit esse ipsum est laboris non aute. Ut deserunt voluptate aliquip dolor aute Lorem in. Incididunt fugiat enim nostrud incididunt magna laborum cillum pariatur tempor.\r\n", "registered": "2014-08-18T03:57:01 -02:00", "latitude": 41.497968, "longitude": 93.809565, "tags": [ "labore", "fugiat", "aliquip", "esse", "nisi", "ad", "labore", "ullamco", "excepteur", "aute" ], "friends": [ { "id": 0, "name": "Janna Petersen" }, { "id": 1, "name": "Mindy Fitzpatrick" }, { "id": 2, "name": "Juliet Johns" }, { "id": 3, "name": "Daphne Ware" }, { "id": 4, "name": "Denise David" } ], "greeting": "Hello, Beasley Velazquez! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f236f6c7c806c7fc", "index": 304, "guid": "02e41ea3-313e-4386-9ad7-44022c8fe016", "isActive": false, "balance": "$1,444.33", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "brown", "name": "Foster Rios", "gender": "male", "company": "PLASMOX", "email": "fosterrios@plasmox.com", "phone": "+1 (900) 561-3962", "address": "201 Milford Street, Camino, California, 7879", "about": "Enim aliqua aliqua tempor in elit voluptate laborum pariatur. Magna laboris minim officia sunt aute aliquip elit magna magna mollit labore culpa. Ullamco occaecat enim ut sit anim. Duis consectetur cupidatat fugiat duis aliquip incididunt consectetur do minim sit incididunt excepteur. Nisi est quis et non consectetur amet irure aute ut non labore incididunt.\r\n", "registered": "2014-03-15T07:58:14 -01:00", "latitude": 59.864691, "longitude": 81.239291, "tags": [ "laborum", "culpa", "ad", "dolore", "in", "id", "dolore", "labore", "cupidatat", "qui" ], "friends": [ { "id": 0, "name": "Nicole Evans" }, { "id": 1, "name": "Lamb Huber" }, { "id": 2, "name": "Lacey Donaldson" }, { "id": 3, "name": "Buck Moore" }, { "id": 4, "name": "Moss Rollins" } ], "greeting": "Hello, Foster Rios! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482662d5049f16ba928a", "index": 305, "guid": "94ff6a0a-bcbe-4e57-bd86-4b5025e804c7", "isActive": true, "balance": "$2,683.52", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "brown", "name": "Stephens Grimes", "gender": "male", "company": "GEOSTELE", "email": "stephensgrimes@geostele.com", "phone": "+1 (995) 485-2798", "address": "875 Everit Street, Whitestone, Utah, 125", "about": "Nostrud non id non ut aute do non. Non commodo elit reprehenderit consectetur in dolore officia laborum consequat ullamco laborum nostrud veniam. Culpa tempor labore occaecat amet adipisicing ad cillum magna pariatur incididunt reprehenderit labore. Anim ut aliqua irure quis quis velit ut. Labore sunt anim veniam sunt elit culpa cillum duis et. Do eiusmod sunt sit incididunt culpa. Fugiat incididunt incididunt sunt deserunt non est voluptate enim est aliquip ipsum esse esse mollit.\r\n", "registered": "2014-05-17T08:14:37 -02:00", "latitude": -38.544699, "longitude": -48.179266, "tags": [ "sunt", "id", "ad", "velit", "Lorem", "velit", "voluptate", "voluptate", "ad", "anim" ], "friends": [ { "id": 0, "name": "Millicent Stevens" }, { "id": 1, "name": "Taylor Blake" }, { "id": 2, "name": "Vinson Cunningham" }, { "id": 3, "name": "Kari Gallegos" }, { "id": 4, "name": "Jefferson Zamora" } ], "greeting": "Hello, Stephens Grimes! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482637d111886f63cda2", "index": 306, "guid": "70400db4-afc9-4dc1-93f2-500cd4fe5e06", "isActive": true, "balance": "$3,637.94", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Rosie Kerr", "gender": "female", "company": "SHEPARD", "email": "rosiekerr@shepard.com", "phone": "+1 (923) 409-2935", "address": "808 Stryker Street, Rivers, Iowa, 9875", "about": "Proident magna laboris amet qui enim incididunt eiusmod. Laborum labore cillum mollit sunt eu adipisicing. Nulla deserunt exercitation nisi do consectetur officia labore cillum incididunt dolore laboris. Id adipisicing commodo tempor do in. Ea aute incididunt duis cupidatat elit qui eu.\r\n", "registered": "2015-01-04T02:01:44 -01:00", "latitude": -7.347067, "longitude": -50.102769, "tags": [ "irure", "reprehenderit", "consectetur", "labore", "Lorem", "id", "amet", "proident", "cillum", "et" ], "friends": [ { "id": 0, "name": "Bean Hickman" }, { "id": 1, "name": "Burgess Johnston" }, { "id": 2, "name": "Salinas Delgado" }, { "id": 3, "name": "Sasha Dunlap" }, { "id": 4, "name": "Downs Bush" } ], "greeting": "Hello, Rosie Kerr! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48261085d963ef57427a", "index": 307, "guid": "412da915-fbf8-4a28-a9ff-97dcfd73d0c7", "isActive": false, "balance": "$2,115.74", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "brown", "name": "Christian Rowland", "gender": "female", "company": "ECLIPTO", "email": "christianrowland@eclipto.com", "phone": "+1 (808) 497-2339", "address": "279 Troy Avenue, Gloucester, North Dakota, 5193", "about": "Sit ullamco occaecat cillum amet aliquip nostrud quis do esse quis. Qui sunt dolor ad excepteur laboris. Officia aute officia exercitation commodo laborum. Tempor enim eiusmod qui ipsum fugiat fugiat.\r\n", "registered": "2014-05-30T01:20:20 -02:00", "latitude": -8.08366, "longitude": -137.123545, "tags": [ "qui", "aliqua", "do", "cupidatat", "ad", "cillum", "commodo", "anim", "reprehenderit", "reprehenderit" ], "friends": [ { "id": 0, "name": "Lolita Walter" }, { "id": 1, "name": "Lakisha Dawson" }, { "id": 2, "name": "Tricia Bass" }, { "id": 3, "name": "Frazier Brewer" }, { "id": 4, "name": "Kelsey Wallace" } ], "greeting": "Hello, Christian Rowland! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482652c74bd5093dbdb6", "index": 308, "guid": "1ac4525d-9d1a-4698-8526-94a84d3df9b8", "isActive": false, "balance": "$3,561.60", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Concepcion Mcconnell", "gender": "female", "company": "DANJA", "email": "concepcionmcconnell@danja.com", "phone": "+1 (902) 410-2377", "address": "956 Kansas Place, Calpine, Kentucky, 1245", "about": "Duis minim velit consequat aute non amet duis. Officia voluptate velit esse eu qui occaecat adipisicing nostrud nulla aute labore consectetur. Veniam aute officia qui nostrud mollit mollit.\r\n", "registered": "2017-10-21T05:53:20 -02:00", "latitude": 84.273606, "longitude": -119.528209, "tags": [ "proident", "proident", "reprehenderit", "elit", "laborum", "incididunt", "enim", "officia", "ex", "velit" ], "friends": [ { "id": 0, "name": "Bridget Bates" }, { "id": 1, "name": "Mia Johnson" }, { "id": 2, "name": "Leanna Acevedo" }, { "id": 3, "name": "Adela Foreman" }, { "id": 4, "name": "Joseph Crosby" } ], "greeting": "Hello, Concepcion Mcconnell! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f77d7ea688d9bb31", "index": 309, "guid": "450c84f6-9b59-4a91-8bea-b98af83b7b67", "isActive": false, "balance": "$2,407.33", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "brown", "name": "Norris Day", "gender": "male", "company": "TALAE", "email": "norrisday@talae.com", "phone": "+1 (879) 469-3678", "address": "735 Thatford Avenue, Ventress, Colorado, 8678", "about": "Voluptate velit veniam ea qui quis exercitation dolore velit culpa reprehenderit sint. Cupidatat culpa commodo dolore id est veniam laborum. Magna aute id dolore minim aute sint. Aliqua adipisicing et dolore do. Sunt consectetur in laborum cupidatat cupidatat qui. Laborum aute voluptate dolore magna in excepteur qui tempor tempor pariatur.\r\n", "registered": "2014-08-02T10:49:56 -02:00", "latitude": 20.42198, "longitude": 137.440664, "tags": [ "esse", "aliqua", "enim", "minim", "Lorem", "ea", "quis", "consectetur", "duis", "pariatur" ], "friends": [ { "id": 0, "name": "Cannon Reilly" }, { "id": 1, "name": "Jewel Horton" }, { "id": 2, "name": "Addie Chang" }, { "id": 3, "name": "Howard Gonzales" }, { "id": 4, "name": "Jordan Rivera" } ], "greeting": "Hello, Norris Day! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826101dab3246526ab7", "index": 310, "guid": "b55dfb7a-346e-491c-9dce-867af0d5e69b", "isActive": true, "balance": "$2,067.91", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "brown", "name": "Bauer Noble", "gender": "male", "company": "SYBIXTEX", "email": "bauernoble@sybixtex.com", "phone": "+1 (894) 424-3905", "address": "834 Livonia Avenue, Austinburg, New Hampshire, 4211", "about": "Enim duis ex voluptate ipsum. Eu deserunt culpa do ullamco fugiat aliquip elit irure qui. Enim occaecat eiusmod ex anim anim sint fugiat adipisicing ad.\r\n", "registered": "2016-07-07T05:55:09 -02:00", "latitude": -58.097846, "longitude": 68.350276, "tags": [ "deserunt", "elit", "Lorem", "consectetur", "commodo", "magna", "id", "ipsum", "in", "elit" ], "friends": [ { "id": 0, "name": "Christy Underwood" }, { "id": 1, "name": "Jenifer Sandoval" }, { "id": 2, "name": "Rush Allen" }, { "id": 3, "name": "Francis Frost" }, { "id": 4, "name": "Bass George" } ], "greeting": "Hello, Bauer Noble! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826116df75b9648ea98", "index": 311, "guid": "fb0282ca-0fa5-4d69-8cc7-b90cb3529a54", "isActive": false, "balance": "$2,285.70", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Vivian Douglas", "gender": "female", "company": "ZILLAN", "email": "viviandouglas@zillan.com", "phone": "+1 (928) 597-2428", "address": "976 Lake Place, Herlong, Wisconsin, 7939", "about": "Dolore ea velit aute ad ullamco veniam qui aliquip aliqua ea velit tempor aute. Et do aliquip ipsum minim dolore duis mollit. Officia eiusmod amet occaecat laboris enim non consequat ut consectetur. Et aliqua consectetur duis occaecat dolore. Dolore eiusmod qui do ut anim. Aliqua commodo cillum incididunt reprehenderit est elit in laboris.\r\n", "registered": "2014-06-08T03:08:43 -02:00", "latitude": -14.420219, "longitude": -76.053672, "tags": [ "eu", "sint", "nulla", "sint", "cillum", "ex", "occaecat", "sit", "sit", "cillum" ], "friends": [ { "id": 0, "name": "Benson Ramirez" }, { "id": 1, "name": "Walters Burris" }, { "id": 2, "name": "Solis Hayes" }, { "id": 3, "name": "Frank Pope" }, { "id": 4, "name": "Morton Gutierrez" } ], "greeting": "Hello, Vivian Douglas! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48263abb432b803c622f", "index": 312, "guid": "663fb33d-4484-49e0-aa20-d339a52aa5d8", "isActive": true, "balance": "$2,016.34", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Houston Jensen", "gender": "male", "company": "GEEKKO", "email": "houstonjensen@geekko.com", "phone": "+1 (998) 583-3781", "address": "531 Lake Avenue, Wawona, Idaho, 8833", "about": "Consectetur minim irure commodo velit culpa irure quis laboris. Est officia eu in dolore incididunt. Tempor aliqua sit sint mollit duis. Exercitation cillum esse et nostrud sint ipsum in cupidatat. Voluptate nulla consectetur dolore fugiat enim ad culpa exercitation anim.\r\n", "registered": "2014-11-01T04:20:39 -01:00", "latitude": 53.181334, "longitude": -148.043284, "tags": [ "culpa", "est", "Lorem", "amet", "incididunt", "eu", "ullamco", "pariatur", "dolore", "pariatur" ], "friends": [ { "id": 0, "name": "Lenora Stewart" }, { "id": 1, "name": "Brown Landry" }, { "id": 2, "name": "Ruiz Guerra" }, { "id": 3, "name": "Huff Knight" }, { "id": 4, "name": "Alston Goff" } ], "greeting": "Hello, Houston Jensen! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826638bde6eef3feb26", "index": 313, "guid": "5f20f93d-a36a-43a4-af64-c7a959b01a3b", "isActive": true, "balance": "$1,368.66", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Kristine Fox", "gender": "female", "company": "KENEGY", "email": "kristinefox@kenegy.com", "phone": "+1 (861) 438-3258", "address": "277 Guernsey Street, Imperial, Georgia, 4934", "about": "Nulla in deserunt ullamco ut adipisicing nostrud exercitation do nulla do. Culpa ea aute excepteur ullamco duis sint pariatur dolor nulla nisi ullamco eu. Cupidatat officia minim aute laboris occaecat Lorem mollit qui culpa incididunt reprehenderit duis. Exercitation ut fugiat adipisicing velit ut ullamco fugiat dolore excepteur magna reprehenderit ex. Dolore tempor adipisicing fugiat fugiat voluptate quis dolore qui. Veniam incididunt do irure minim occaecat.\r\n", "registered": "2017-05-06T10:46:30 -02:00", "latitude": -7.523756, "longitude": -9.806869, "tags": [ "reprehenderit", "do", "nostrud", "cupidatat", "laboris", "dolore", "excepteur", "dolore", "sint", "proident" ], "friends": [ { "id": 0, "name": "Wanda Foley" }, { "id": 1, "name": "Douglas Carney" }, { "id": 2, "name": "Marva Richards" }, { "id": 3, "name": "Debra Mills" }, { "id": 4, "name": "Bradshaw Adams" } ], "greeting": "Hello, Kristine Fox! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826071cb92cd37428c7", "index": 314, "guid": "5d6bd2c3-90ea-456a-ae9a-31516817df28", "isActive": false, "balance": "$1,261.29", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Bessie Mccormick", "gender": "female", "company": "SPLINX", "email": "bessiemccormick@splinx.com", "phone": "+1 (908) 472-3263", "address": "706 Hanover Place, Smock, Virgin Islands, 6652", "about": "Quis ad mollit eu sit ullamco consectetur excepteur qui tempor officia ad do occaecat eiusmod. Anim laborum elit incididunt veniam dolore minim in. Aliqua exercitation nulla aliqua laboris est sint nostrud. Occaecat sit ad anim irure culpa sit mollit fugiat dolor nisi in ut fugiat. Exercitation duis consectetur ea nulla esse ea Lorem non Lorem anim sint. Non labore ea officia aliquip aliqua. Reprehenderit adipisicing veniam laboris laboris ea magna dolore eiusmod veniam incididunt.\r\n", "registered": "2017-05-24T03:49:57 -02:00", "latitude": 86.577367, "longitude": 165.167822, "tags": [ "commodo", "labore", "ullamco", "ut", "sint", "adipisicing", "irure", "elit", "labore", "minim" ], "friends": [ { "id": 0, "name": "Ramona Estrada" }, { "id": 1, "name": "Harrison Craig" }, { "id": 2, "name": "Martinez Coffey" }, { "id": 3, "name": "Mcintosh Wiggins" }, { "id": 4, "name": "Traci Daugherty" } ], "greeting": "Hello, Bessie Mccormick! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826aae3accd489e8c73", "index": 315, "guid": "55c68276-ec9c-434b-a971-30c52ad2e68a", "isActive": true, "balance": "$2,433.21", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Lorna Hines", "gender": "female", "company": "DYNO", "email": "lornahines@dyno.com", "phone": "+1 (849) 410-3638", "address": "372 Glendale Court, Abrams, Minnesota, 7531", "about": "Cillum velit laborum reprehenderit et voluptate. Occaecat id cupidatat velit reprehenderit voluptate Lorem enim sit magna duis tempor. Duis quis laborum tempor enim eu reprehenderit exercitation aute. Ut cupidatat anim non non. Est non enim est occaecat nisi labore proident laborum aliqua. Excepteur laborum esse reprehenderit non tempor tempor. Commodo ad in enim sit aute sunt amet eu commodo ex sint commodo.\r\n", "registered": "2016-06-13T12:27:53 -02:00", "latitude": -29.734157, "longitude": -164.094778, "tags": [ "ipsum", "dolor", "cupidatat", "do", "commodo", "aute", "eiusmod", "aute", "aute", "laboris" ], "friends": [ { "id": 0, "name": "Brock Brennan" }, { "id": 1, "name": "Arnold Yates" }, { "id": 2, "name": "Golden Jacobs" }, { "id": 3, "name": "Celina Best" }, { "id": 4, "name": "Ball Morin" } ], "greeting": "Hello, Lorna Hines! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48263adccd57f9f56357", "index": 316, "guid": "6fe2f42c-3bd3-4199-a103-f654a4881805", "isActive": false, "balance": "$3,845.14", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Erica Higgins", "gender": "female", "company": "SNORUS", "email": "ericahiggins@snorus.com", "phone": "+1 (987) 413-3983", "address": "798 Malbone Street, Bellamy, South Carolina, 202", "about": "Fugiat nisi elit minim magna aute nulla laborum elit dolor exercitation est non enim laboris. Cupidatat sit cupidatat consequat mollit ad adipisicing. Enim laboris id in ad et incididunt ullamco. Aliquip consectetur proident veniam Lorem cupidatat esse irure ut non aliquip aute magna sit ipsum. Et nulla laboris Lorem aliquip tempor esse ut deserunt elit labore elit.\r\n", "registered": "2014-04-18T03:17:07 -02:00", "latitude": -11.227724, "longitude": 139.280783, "tags": [ "enim", "excepteur", "occaecat", "proident", "eu", "mollit", "sunt", "minim", "do", "nisi" ], "friends": [ { "id": 0, "name": "Gabrielle Robinson" }, { "id": 1, "name": "Pena Greer" }, { "id": 2, "name": "Pam Mcknight" }, { "id": 3, "name": "Juarez Harper" }, { "id": 4, "name": "Natasha Whitehead" } ], "greeting": "Hello, Erica Higgins! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482628c58430862eb7eb", "index": 317, "guid": "84f9efc0-0ea0-4bf8-8984-56570c2f839f", "isActive": false, "balance": "$2,329.66", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Ramirez Chase", "gender": "male", "company": "COREPAN", "email": "ramirezchase@corepan.com", "phone": "+1 (898) 588-2796", "address": "127 Montauk Avenue, Derwood, Northern Mariana Islands, 7483", "about": "Et nisi sint amet exercitation ut et ullamco. Deserunt minim ea non do aliqua anim dolore. Cillum eu officia cupidatat ex est pariatur voluptate incididunt sunt tempor commodo.\r\n", "registered": "2015-12-15T06:45:47 -01:00", "latitude": 20.578116, "longitude": -30.841383, "tags": [ "aute", "dolor", "ex", "est", "exercitation", "quis", "quis", "elit", "incididunt", "ex" ], "friends": [ { "id": 0, "name": "Carissa Wood" }, { "id": 1, "name": "Maryellen Eaton" }, { "id": 2, "name": "Dawson Payne" }, { "id": 3, "name": "Alexander Barrett" }, { "id": 4, "name": "Pennington Pierce" } ], "greeting": "Hello, Ramirez Chase! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ee7dfa5391e7eefb", "index": 318, "guid": "6fe09bf9-b282-4602-beee-2016c4ea07cc", "isActive": true, "balance": "$2,253.28", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Ebony Lester", "gender": "female", "company": "ENOMEN", "email": "ebonylester@enomen.com", "phone": "+1 (827) 580-3567", "address": "285 Clarendon Road, Darbydale, Pennsylvania, 7102", "about": "Deserunt exercitation nisi non quis aliquip non. Sit in amet irure eu aliqua aliquip non non. Magna est consequat anim veniam exercitation quis aute velit. Exercitation ad qui Lorem consequat reprehenderit deserunt velit. Do tempor irure cillum ullamco occaecat cupidatat est. Cupidatat irure id pariatur amet cupidatat dolor officia aliquip.\r\n", "registered": "2016-04-18T06:15:44 -02:00", "latitude": -20.010865, "longitude": 141.941896, "tags": [ "excepteur", "ex", "enim", "commodo", "non", "veniam", "esse", "voluptate", "cillum", "mollit" ], "friends": [ { "id": 0, "name": "Mabel Farley" }, { "id": 1, "name": "Cobb Trevino" }, { "id": 2, "name": "Ginger Cummings" }, { "id": 3, "name": "Bettye Buckley" }, { "id": 4, "name": "Zimmerman Gilmore" } ], "greeting": "Hello, Ebony Lester! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f0d0e08e74adc6ad", "index": 319, "guid": "b7d69dba-259c-411b-8857-f41b37712fa9", "isActive": true, "balance": "$3,262.08", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Carroll Curry", "gender": "male", "company": "GAZAK", "email": "carrollcurry@gazak.com", "phone": "+1 (898) 492-3399", "address": "568 Dupont Street, Kraemer, Arkansas, 1443", "about": "Non labore sit consequat irure. Ullamco ea non sunt laboris duis. Cupidatat ea ea non labore. Incididunt deserunt ad voluptate irure. Dolore ad occaecat do est labore ut adipisicing ex deserunt nulla occaecat proident.\r\n", "registered": "2017-01-12T05:26:33 -01:00", "latitude": -44.080804, "longitude": -151.1663, "tags": [ "laboris", "id", "velit", "id", "proident", "nostrud", "incididunt", "anim", "Lorem", "officia" ], "friends": [ { "id": 0, "name": "Thornton Terrell" }, { "id": 1, "name": "Kellie Weiss" }, { "id": 2, "name": "Wilda Huffman" }, { "id": 3, "name": "Latasha Rose" }, { "id": 4, "name": "Sargent Cooke" } ], "greeting": "Hello, Carroll Curry! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826b945adffcaab51c3", "index": 320, "guid": "607888bf-0873-43fb-b5cb-8a39f086184f", "isActive": false, "balance": "$3,626.62", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "blue", "name": "Savage Berg", "gender": "male", "company": "KIGGLE", "email": "savageberg@kiggle.com", "phone": "+1 (915) 459-3881", "address": "283 Times Placez, Fingerville, Palau, 6002", "about": "Tempor fugiat anim deserunt id nisi est cillum incididunt nulla dolore. Nostrud nulla eiusmod cillum quis sint reprehenderit commodo irure veniam et duis ex sunt. Amet quis consequat laborum minim aliqua consectetur occaecat occaecat fugiat fugiat mollit.\r\n", "registered": "2017-05-26T06:46:13 -02:00", "latitude": 58.778181, "longitude": -9.594906, "tags": [ "proident", "cupidatat", "anim", "cupidatat", "pariatur", "reprehenderit", "commodo", "dolore", "minim", "do" ], "friends": [ { "id": 0, "name": "Charlene Wyatt" }, { "id": 1, "name": "Tamera Barron" }, { "id": 2, "name": "Gillespie Little" }, { "id": 3, "name": "Pat Villarreal" }, { "id": 4, "name": "Kaye Franks" } ], "greeting": "Hello, Savage Berg! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48264b331a503717ae25", "index": 321, "guid": "04ad15a1-0bd2-4567-889c-354a16c969c5", "isActive": false, "balance": "$3,992.84", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Deirdre Whitley", "gender": "female", "company": "NETUR", "email": "deirdrewhitley@netur.com", "phone": "+1 (900) 570-2901", "address": "402 Portland Avenue, Enetai, Connecticut, 3209", "about": "Pariatur ad consequat eu culpa nulla et cillum esse laboris adipisicing non non. Aliquip tempor ea officia mollit duis in exercitation cupidatat commodo dolor do. Labore do consequat cupidatat non voluptate aliqua id est exercitation proident magna sunt incididunt. Qui Lorem ad incididunt et consectetur. Ullamco dolor id velit qui esse quis dolor ut eiusmod irure et consectetur.\r\n", "registered": "2017-04-07T08:17:47 -02:00", "latitude": 19.997886, "longitude": -98.99045, "tags": [ "quis", "voluptate", "ad", "commodo", "sit", "anim", "Lorem", "magna", "nulla", "amet" ], "friends": [ { "id": 0, "name": "Goldie Reed" }, { "id": 1, "name": "Bonnie Shaw" }, { "id": 2, "name": "Ruby Brock" }, { "id": 3, "name": "Gabriela Randall" }, { "id": 4, "name": "Bates Lindsay" } ], "greeting": "Hello, Deirdre Whitley! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48261c21be970c98094b", "index": 322, "guid": "d2274cef-9dfa-4cea-8c1e-6aa30803e5d6", "isActive": true, "balance": "$3,738.74", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Constance Waller", "gender": "female", "company": "ATOMICA", "email": "constancewaller@atomica.com", "phone": "+1 (897) 471-2121", "address": "609 Stockholm Street, Vale, North Carolina, 2218", "about": "Ipsum laboris sit voluptate sit laborum anim. Dolore sint ex adipisicing adipisicing nostrud enim ullamco officia nulla eu est culpa aute. Duis consequat proident consectetur pariatur incididunt ullamco aliqua anim enim ut aliqua enim adipisicing. Laborum reprehenderit consequat adipisicing amet id in ex nulla pariatur nulla. Mollit nostrud minim et nostrud eu pariatur ullamco cillum est. Nisi laboris do magna qui sit qui. Id eu enim magna quis adipisicing ut nisi consectetur Lorem incididunt id.\r\n", "registered": "2015-12-27T04:35:44 -01:00", "latitude": -37.328439, "longitude": 157.683468, "tags": [ "officia", "occaecat", "non", "aliquip", "deserunt", "reprehenderit", "minim", "aute", "sunt", "nulla" ], "friends": [ { "id": 0, "name": "Sutton Fischer" }, { "id": 1, "name": "Snyder Sears" }, { "id": 2, "name": "Cantu Mcclure" }, { "id": 3, "name": "Ivy Hansen" }, { "id": 4, "name": "Sarah Vega" } ], "greeting": "Hello, Constance Waller! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826bf3a0313d516ffb3", "index": 323, "guid": "cd01287c-81cc-4a22-8a2f-b60e4613e0fc", "isActive": true, "balance": "$1,086.05", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "green", "name": "Erika Joyce", "gender": "female", "company": "CENTREXIN", "email": "erikajoyce@centrexin.com", "phone": "+1 (919) 557-2242", "address": "187 Varet Street, Wilmington, Missouri, 1388", "about": "Sit id in anim cillum in enim ea magna laborum irure elit enim fugiat. Fugiat commodo in cillum proident eiusmod fugiat consequat eu et eiusmod velit do deserunt. Consequat do culpa ut amet.\r\n", "registered": "2015-02-26T03:15:34 -01:00", "latitude": -25.14463, "longitude": 84.438882, "tags": [ "proident", "laboris", "tempor", "irure", "aliqua", "ex", "id", "esse", "aliqua", "ut" ], "friends": [ { "id": 0, "name": "Lesley Ratliff" }, { "id": 1, "name": "Powell Heath" }, { "id": 2, "name": "Angelia Reyes" }, { "id": 3, "name": "Mays Christian" }, { "id": 4, "name": "Maritza Shannon" } ], "greeting": "Hello, Erika Joyce! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482690e6c0b4b9380589", "index": 324, "guid": "8b57cadb-646a-4d93-8abd-0b1556253966", "isActive": false, "balance": "$1,384.85", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "brown", "name": "Brittany Soto", "gender": "female", "company": "POWERNET", "email": "brittanysoto@powernet.com", "phone": "+1 (880) 480-3342", "address": "311 Kay Court, Caroleen, Ohio, 4489", "about": "Nisi reprehenderit culpa sit minim. Sint ipsum cupidatat aliquip commodo esse. Ullamco labore aute aliqua voluptate ipsum irure qui minim nulla aliquip aliquip.\r\n", "registered": "2017-02-27T09:42:37 -01:00", "latitude": -85.840244, "longitude": 115.203555, "tags": [ "veniam", "commodo", "non", "consequat", "do", "proident", "cupidatat", "sint", "aliqua", "sit" ], "friends": [ { "id": 0, "name": "Armstrong Short" }, { "id": 1, "name": "June Downs" }, { "id": 2, "name": "Kirby Hendricks" }, { "id": 3, "name": "Silvia Henry" }, { "id": 4, "name": "Olsen Mckenzie" } ], "greeting": "Hello, Brittany Soto! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826fa9fda07fde12bdd", "index": 325, "guid": "02c625ec-d6e9-4170-94c1-669fe4a94b4f", "isActive": false, "balance": "$1,269.94", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Donna Mason", "gender": "female", "company": "MEDIOT", "email": "donnamason@mediot.com", "phone": "+1 (803) 590-3912", "address": "602 Woodhull Street, Springhill, Arizona, 1822", "about": "Veniam eiusmod ipsum et velit non elit laboris irure occaecat. Est sint sint ipsum culpa aliquip magna tempor ullamco sit sit incididunt veniam. Voluptate veniam laboris ut et cupidatat laborum quis minim amet incididunt. Deserunt laborum ad cupidatat commodo commodo pariatur mollit do sint est fugiat. Proident ex ad mollit officia proident incididunt culpa. Deserunt in tempor dolor dolor mollit tempor ut ullamco magna ut ex commodo. Irure voluptate exercitation ad ex est officia nostrud id tempor aliqua aute.\r\n", "registered": "2017-02-13T04:26:57 -01:00", "latitude": -74.316276, "longitude": 104.161437, "tags": [ "proident", "aute", "laboris", "esse", "cupidatat", "laboris", "excepteur", "nostrud", "fugiat", "aute" ], "friends": [ { "id": 0, "name": "Tia Head" }, { "id": 1, "name": "Lilly Williamson" }, { "id": 2, "name": "Sonja Coleman" }, { "id": 3, "name": "Gonzales Nielsen" }, { "id": 4, "name": "Dorsey Rosario" } ], "greeting": "Hello, Donna Mason! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482643eb322b20187860", "index": 326, "guid": "4b284fff-e8a3-44cf-a8be-3770e8b722e5", "isActive": false, "balance": "$1,826.54", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "brown", "name": "Scott Livingston", "gender": "male", "company": "CAXT", "email": "scottlivingston@caxt.com", "phone": "+1 (899) 417-2924", "address": "707 Nassau Street, Rote, Montana, 5902", "about": "Tempor nulla aute ea Lorem non veniam cupidatat do commodo enim anim exercitation sit. Non magna nisi ex enim mollit nisi veniam aliquip nulla. Do sunt deserunt tempor veniam dolor mollit do duis consequat consequat laboris eiusmod duis. Non amet laboris exercitation dolore excepteur.\r\n", "registered": "2014-11-14T08:01:33 -01:00", "latitude": -72.971092, "longitude": 5.381781, "tags": [ "sint", "officia", "ipsum", "duis", "Lorem", "et", "non", "duis", "qui", "Lorem" ], "friends": [ { "id": 0, "name": "Gould Beck" }, { "id": 1, "name": "Sadie Williams" }, { "id": 2, "name": "Cecilia Buck" }, { "id": 3, "name": "Freida Murphy" }, { "id": 4, "name": "Ora Bauer" } ], "greeting": "Hello, Scott Livingston! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826527cef7f00794826", "index": 327, "guid": "3abc5049-c215-42bc-b5b1-49168b7b01ee", "isActive": false, "balance": "$1,433.65", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Mattie Whitfield", "gender": "female", "company": "KEEG", "email": "mattiewhitfield@keeg.com", "phone": "+1 (825) 565-3737", "address": "338 Downing Street, Juarez, Texas, 1213", "about": "Ut aute cupidatat exercitation duis anim pariatur nulla ad commodo qui elit. Commodo non in enim ullamco ea ex qui sint reprehenderit do magna. Minim cillum sint quis dolore aliquip ad ad do et commodo. Non culpa ipsum veniam mollit ea duis. Ex mollit do exercitation qui eiusmod. Ex ad aute irure aute laboris non ea reprehenderit proident sit.\r\n", "registered": "2016-01-07T01:42:06 -01:00", "latitude": -85.137122, "longitude": 54.255676, "tags": [ "labore", "pariatur", "dolor", "velit", "eiusmod", "elit", "ullamco", "excepteur", "Lorem", "est" ], "friends": [ { "id": 0, "name": "Letitia Dudley" }, { "id": 1, "name": "Barton Klein" }, { "id": 2, "name": "Kendra Simon" }, { "id": 3, "name": "Rodgers Finley" }, { "id": 4, "name": "Hoover Fowler" } ], "greeting": "Hello, Mattie Whitfield! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826f1e77e7214864bb9", "index": 328, "guid": "b26e2126-742e-4486-92ec-337ec5ddb5c9", "isActive": true, "balance": "$3,054.63", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "green", "name": "Lizzie Stanley", "gender": "female", "company": "PAPRIKUT", "email": "lizziestanley@paprikut.com", "phone": "+1 (939) 460-3684", "address": "892 Alabama Avenue, Bodega, Washington, 1447", "about": "Eiusmod cillum nostrud velit ad aliqua. Enim nulla ut et ut labore ut proident Lorem et ex. Laborum consequat eu velit reprehenderit. Incididunt in dolor consequat laborum enim eiusmod deserunt duis eiusmod cillum.\r\n", "registered": "2014-12-31T06:44:50 -01:00", "latitude": -54.690674, "longitude": 37.345251, "tags": [ "velit", "anim", "tempor", "nostrud", "duis", "labore", "ex", "anim", "aute", "nisi" ], "friends": [ { "id": 0, "name": "Francis Henderson" }, { "id": 1, "name": "Morales Avila" }, { "id": 2, "name": "Ewing Reynolds" }, { "id": 3, "name": "Vasquez Frederick" }, { "id": 4, "name": "Claire Walsh" } ], "greeting": "Hello, Lizzie Stanley! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826f84cf8386f2dc90e", "index": 329, "guid": "eda0dd86-8c2f-4886-88b6-af239619e325", "isActive": true, "balance": "$1,323.00", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Luisa Bowman", "gender": "female", "company": "ZYTREX", "email": "luisabowman@zytrex.com", "phone": "+1 (996) 524-3383", "address": "215 Tehama Street, Loomis, Wyoming, 2753", "about": "Duis tempor occaecat proident elit ullamco fugiat ex occaecat fugiat eiusmod. Ut sunt nisi do irure velit adipisicing in. Velit ex reprehenderit voluptate in sunt incididunt nisi velit voluptate incididunt dolor tempor.\r\n", "registered": "2017-01-14T03:21:20 -01:00", "latitude": -46.091582, "longitude": 24.6281, "tags": [ "dolore", "laboris", "occaecat", "est", "ipsum", "exercitation", "eiusmod", "ipsum", "velit", "dolore" ], "friends": [ { "id": 0, "name": "Diana Vargas" }, { "id": 1, "name": "Patrice Stokes" }, { "id": 2, "name": "Franco Lewis" }, { "id": 3, "name": "Holt Vazquez" }, { "id": 4, "name": "Craft Gates" } ], "greeting": "Hello, Luisa Bowman! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826601349c2c95c2696", "index": 330, "guid": "9b5acb4d-98ec-4ab8-b2f4-2d13dfc59aa1", "isActive": true, "balance": "$1,354.24", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Joyner Espinoza", "gender": "male", "company": "MIRACULA", "email": "joynerespinoza@miracula.com", "phone": "+1 (984) 576-2800", "address": "735 Tapscott Street, Lodoga, Indiana, 1686", "about": "Est elit irure consequat laboris esse tempor pariatur irure sit nulla. Elit do id deserunt excepteur aute do cillum. Aute do id velit Lorem consequat enim aliquip do officia occaecat laborum incididunt in. Excepteur et ipsum labore proident ex magna dolore. Anim esse fugiat in nisi nostrud occaecat esse esse adipisicing. Amet et reprehenderit ad nulla eu elit consectetur nisi sunt eu nisi pariatur velit duis.\r\n", "registered": "2016-09-30T10:36:12 -02:00", "latitude": -28.663692, "longitude": 174.961607, "tags": [ "nulla", "nisi", "quis", "officia", "enim", "ut", "elit", "tempor", "sunt", "fugiat" ], "friends": [ { "id": 0, "name": "Naomi Collier" }, { "id": 1, "name": "Regina Riley" }, { "id": 2, "name": "Mcleod Sexton" }, { "id": 3, "name": "Lawrence Davis" }, { "id": 4, "name": "Holland Park" } ], "greeting": "Hello, Joyner Espinoza! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e857a2b82afb530a", "index": 331, "guid": "49e5251c-195f-4026-99c2-72aa9f36ea24", "isActive": false, "balance": "$1,127.66", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "brown", "name": "Mallory Kirk", "gender": "female", "company": "EBIDCO", "email": "mallorykirk@ebidco.com", "phone": "+1 (948) 495-3786", "address": "761 Montieth Street, Wacissa, Alabama, 6219", "about": "Sunt qui duis magna fugiat minim. Occaecat ipsum nostrud magna laborum non. Adipisicing dolore proident quis anim nostrud ullamco et adipisicing ipsum ipsum tempor reprehenderit sunt. Pariatur occaecat eiusmod esse est exercitation cillum sit.\r\n", "registered": "2014-10-05T12:53:21 -02:00", "latitude": -52.309834, "longitude": -63.356802, "tags": [ "enim", "ipsum", "consectetur", "cillum", "amet", "ad", "sit", "eu", "mollit", "eiusmod" ], "friends": [ { "id": 0, "name": "Moses Mccullough" }, { "id": 1, "name": "Morin Savage" }, { "id": 2, "name": "Harding Spencer" }, { "id": 3, "name": "Gallagher White" }, { "id": 4, "name": "Estelle Holloway" } ], "greeting": "Hello, Mallory Kirk! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826684bf3ffb1d121bc", "index": 332, "guid": "a30f7cf8-afaa-464f-b88c-7417e10768b7", "isActive": true, "balance": "$1,526.13", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Cameron Randolph", "gender": "male", "company": "INRT", "email": "cameronrandolph@inrt.com", "phone": "+1 (930) 588-3347", "address": "513 Sumpter Street, Camas, Virginia, 5204", "about": "Ea nisi commodo qui nisi proident consequat. Adipisicing ullamco quis mollit qui dolore fugiat laborum ad esse pariatur magna consequat. Minim nulla quis dolor esse officia amet proident qui. Consequat nostrud id commodo dolore et tempor adipisicing.\r\n", "registered": "2016-10-06T07:59:01 -02:00", "latitude": 52.211112, "longitude": 116.965502, "tags": [ "id", "eiusmod", "do", "aliqua", "cillum", "occaecat", "amet", "amet", "qui", "adipisicing" ], "friends": [ { "id": 0, "name": "Shelly Caldwell" }, { "id": 1, "name": "Burke Paul" }, { "id": 2, "name": "Wagner Mann" }, { "id": 3, "name": "Reed Burton" }, { "id": 4, "name": "Shawna Haney" } ], "greeting": "Hello, Cameron Randolph! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261eee113e3541ccd7", "index": 333, "guid": "f3818bef-f2f2-4e4e-b99c-4ac26e7ee6a3", "isActive": false, "balance": "$2,895.52", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Fay Hudson", "gender": "female", "company": "TELLIFLY", "email": "fayhudson@tellifly.com", "phone": "+1 (921) 402-2637", "address": "269 Seigel Street, Independence, New Mexico, 4057", "about": "Incididunt consequat commodo ea in magna non aliquip quis anim occaecat cupidatat in labore deserunt. Irure proident est laboris ut occaecat quis sunt proident officia proident Lorem mollit. Qui nostrud aliqua amet fugiat Lorem tempor excepteur et veniam ut eu eu consequat sunt. Deserunt dolore qui cillum incididunt irure non ex non.\r\n", "registered": "2014-01-31T01:31:24 -01:00", "latitude": -61.312615, "longitude": -119.411687, "tags": [ "proident", "minim", "sint", "Lorem", "consectetur", "consequat", "cillum", "officia", "id", "anim" ], "friends": [ { "id": 0, "name": "Walls Montgomery" }, { "id": 1, "name": "Fern Nelson" }, { "id": 2, "name": "Tanisha Patrick" }, { "id": 3, "name": "Frances Burks" }, { "id": 4, "name": "Parks Dickerson" } ], "greeting": "Hello, Fay Hudson! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482634b7d963e52a61c0", "index": 334, "guid": "9c9560b5-20d6-490e-94cb-6612093c5cee", "isActive": false, "balance": "$3,347.08", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Marsha Ortega", "gender": "female", "company": "SCHOOLIO", "email": "marshaortega@schoolio.com", "phone": "+1 (893) 471-3372", "address": "528 Monitor Street, Coyote, Hawaii, 4181", "about": "In esse tempor elit proident commodo consequat sunt ut dolore minim nostrud cillum pariatur sunt. Anim sunt reprehenderit adipisicing eiusmod aliqua pariatur fugiat duis mollit. Tempor officia minim amet ullamco laboris reprehenderit anim et voluptate commodo. Cillum ex nulla esse ullamco. Esse duis cupidatat qui ex do magna excepteur do aute sunt. Quis do aute magna anim incididunt.\r\n", "registered": "2014-12-31T10:43:48 -01:00", "latitude": 47.917642, "longitude": 168.145217, "tags": [ "fugiat", "sunt", "proident", "officia", "occaecat", "non", "sint", "excepteur", "duis", "qui" ], "friends": [ { "id": 0, "name": "Steele Dominguez" }, { "id": 1, "name": "Jeannie Mercado" }, { "id": 2, "name": "Kay Conway" }, { "id": 3, "name": "Wilkerson Bean" }, { "id": 4, "name": "Keith Montoya" } ], "greeting": "Hello, Marsha Ortega! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826b3636ae44eaae7a4", "index": 335, "guid": "7e4eb8c1-eb63-4656-b110-76105871aeee", "isActive": true, "balance": "$2,775.32", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Glover Sellers", "gender": "male", "company": "GEEKOLOGY", "email": "gloversellers@geekology.com", "phone": "+1 (876) 411-3558", "address": "852 Rutland Road, Whitmer, Nebraska, 4785", "about": "Nisi qui consectetur cillum sint Lorem excepteur ea proident amet elit aliqua commodo culpa. Non et nostrud excepteur occaecat. Deserunt sit qui non irure culpa dolore.\r\n", "registered": "2017-05-12T01:50:12 -02:00", "latitude": 32.342412, "longitude": 45.559009, "tags": [ "nostrud", "fugiat", "ea", "eu", "velit", "do", "ipsum", "proident", "do", "sint" ], "friends": [ { "id": 0, "name": "Washington Holman" }, { "id": 1, "name": "Mari Floyd" }, { "id": 2, "name": "Ines Santana" }, { "id": 3, "name": "Barber Tate" }, { "id": 4, "name": "Marian Barber" } ], "greeting": "Hello, Glover Sellers! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482604e29b79b43f8d0c", "index": 336, "guid": "6ec86e3c-431f-4a3c-9877-8b1df7181a17", "isActive": true, "balance": "$2,547.43", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "blue", "name": "Benjamin Sawyer", "gender": "male", "company": "GLEAMINK", "email": "benjaminsawyer@gleamink.com", "phone": "+1 (812) 527-3040", "address": "927 Irving Avenue, Lynn, New York, 9597", "about": "Sunt mollit ex fugiat non nostrud ullamco cillum esse. Ad sint anim duis ex eu et consectetur labore est dolore non reprehenderit adipisicing mollit. Id cupidatat est nulla Lorem laborum. Ut labore sint sunt deserunt esse pariatur pariatur ex.\r\n", "registered": "2014-05-31T02:03:00 -02:00", "latitude": -34.596342, "longitude": -119.185138, "tags": [ "sint", "voluptate", "commodo", "ex", "veniam", "ad", "amet", "cupidatat", "enim", "ipsum" ], "friends": [ { "id": 0, "name": "Castro Harrington" }, { "id": 1, "name": "Case Davenport" }, { "id": 2, "name": "Hill Ferguson" }, { "id": 3, "name": "Barrett Burch" }, { "id": 4, "name": "Noemi Maynard" } ], "greeting": "Hello, Benjamin Sawyer! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826af17b1bdb58ef09c", "index": 337, "guid": "560746aa-db3d-4ec0-8d2f-310090e2e817", "isActive": false, "balance": "$1,736.07", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Jeanne Andrews", "gender": "female", "company": "SULTRAXIN", "email": "jeanneandrews@sultraxin.com", "phone": "+1 (932) 464-3344", "address": "785 Grove Place, Edgar, Marshall Islands, 7377", "about": "Officia occaecat do laboris voluptate occaecat enim. Eiusmod duis amet adipisicing laborum anim. Fugiat laborum anim elit excepteur qui esse laboris irure aliqua est nostrud. Do excepteur dolore proident fugiat ad laboris cillum dolor non duis nostrud eiusmod dolore aliquip. Veniam esse reprehenderit adipisicing adipisicing duis. Nostrud commodo incididunt cillum cupidatat labore et magna. Nulla ullamco proident proident amet labore dolore eu velit nulla sit elit aliquip.\r\n", "registered": "2016-12-10T06:06:36 -01:00", "latitude": -67.274428, "longitude": -41.698565, "tags": [ "eiusmod", "amet", "excepteur", "irure", "cillum", "ad", "est", "eiusmod", "culpa", "fugiat" ], "friends": [ { "id": 0, "name": "Minerva Lott" }, { "id": 1, "name": "Myrtle Rojas" }, { "id": 2, "name": "Moran Lane" }, { "id": 3, "name": "White Wells" }, { "id": 4, "name": "Yates Mullins" } ], "greeting": "Hello, Jeanne Andrews! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826aa5dfb530dfa7490", "index": 338, "guid": "46429fd1-45e7-49c1-8d07-397e1134e10a", "isActive": true, "balance": "$2,460.04", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "brown", "name": "Whitaker Schroeder", "gender": "male", "company": "BEDLAM", "email": "whitakerschroeder@bedlam.com", "phone": "+1 (984) 534-2013", "address": "236 Arlington Avenue, Robinette, Oregon, 7119", "about": "Consectetur duis magna laborum nulla pariatur officia ipsum. Duis eiusmod eu consequat ex sit amet est anim. Do aute dolore reprehenderit do. Ad sunt amet occaecat mollit eiusmod sunt aute ea. Consequat dolor irure ad laborum qui proident reprehenderit. Veniam eu do elit et Lorem ex culpa tempor fugiat nulla id. Aute cillum dolore ipsum ad nisi aliqua eiusmod et dolore culpa labore veniam consequat.\r\n", "registered": "2016-11-08T10:18:21 -01:00", "latitude": -18.667517, "longitude": 111.884601, "tags": [ "magna", "mollit", "ex", "quis", "sint", "mollit", "consectetur", "officia", "commodo", "irure" ], "friends": [ { "id": 0, "name": "Loretta Frazier" }, { "id": 1, "name": "Tracey Robles" }, { "id": 2, "name": "Trevino Beard" }, { "id": 3, "name": "Gallegos Stout" }, { "id": 4, "name": "Sweeney Cameron" } ], "greeting": "Hello, Whitaker Schroeder! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261924338768f4bbd9", "index": 339, "guid": "6bdea96a-471a-42e4-b2cc-10bd655c209a", "isActive": false, "balance": "$1,264.06", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Vicki Briggs", "gender": "female", "company": "GLASSTEP", "email": "vickibriggs@glasstep.com", "phone": "+1 (928) 433-3955", "address": "863 Opal Court, Hessville, Tennessee, 9010", "about": "Duis consequat fugiat deserunt ea deserunt nostrud magna. In voluptate aliquip veniam ea dolore. Esse non nostrud laborum occaecat veniam dolore sunt culpa adipisicing.\r\n", "registered": "2015-03-04T12:56:29 -01:00", "latitude": 80.229232, "longitude": -6.311087, "tags": [ "enim", "esse", "velit", "fugiat", "magna", "aliquip", "eiusmod", "aliqua", "culpa", "consequat" ], "friends": [ { "id": 0, "name": "Jarvis Dodson" }, { "id": 1, "name": "Ilene Gross" }, { "id": 2, "name": "Karla Bridges" }, { "id": 3, "name": "Strickland Todd" }, { "id": 4, "name": "Tina Simpson" } ], "greeting": "Hello, Vicki Briggs! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482617d27cb2ba5fc9c0", "index": 340, "guid": "bc2bedde-ad5c-4f27-a25b-f5f6b7065933", "isActive": true, "balance": "$2,315.49", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "brown", "name": "Rosella Peck", "gender": "female", "company": "ZILPHUR", "email": "rosellapeck@zilphur.com", "phone": "+1 (982) 542-3795", "address": "971 Gallatin Place, Gerber, Nevada, 4027", "about": "Dolore sint ipsum nostrud est adipisicing velit ad occaecat voluptate dolore sunt. Ut non proident amet elit pariatur in deserunt duis ea deserunt do Lorem adipisicing. Labore duis anim dolore cupidatat ex nisi ut reprehenderit magna amet duis.\r\n", "registered": "2017-12-29T08:15:17 -01:00", "latitude": -85.323868, "longitude": 41.968559, "tags": [ "fugiat", "in", "dolore", "sunt", "aute", "est", "excepteur", "qui", "elit", "anim" ], "friends": [ { "id": 0, "name": "Owens Marquez" }, { "id": 1, "name": "Deanna Medina" }, { "id": 2, "name": "Kimberly Snider" }, { "id": 3, "name": "Farrell Nieves" }, { "id": 4, "name": "Chang Pugh" } ], "greeting": "Hello, Rosella Peck! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482660121438391b0986", "index": 341, "guid": "9b2f6769-958a-4ecf-b9be-d1c07d97589f", "isActive": true, "balance": "$1,712.08", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "brown", "name": "Aisha Young", "gender": "female", "company": "ANIMALIA", "email": "aishayoung@animalia.com", "phone": "+1 (818) 418-2748", "address": "702 Charles Place, Chesterfield, Alaska, 6840", "about": "Ipsum ullamco tempor irure excepteur fugiat irure proident magna nulla reprehenderit fugiat ad fugiat. Commodo commodo reprehenderit cillum duis anim sint duis sint eu mollit reprehenderit. Nulla laborum officia consequat incididunt ullamco est occaecat non ullamco ullamco sint sunt. Velit ipsum nulla exercitation veniam id excepteur labore ipsum aliquip aliquip ut eu. Mollit sit quis occaecat qui quis ut deserunt minim aute mollit duis sunt.\r\n", "registered": "2017-11-20T06:35:18 -01:00", "latitude": -88.324821, "longitude": -151.923024, "tags": [ "veniam", "veniam", "officia", "exercitation", "laborum", "aliqua", "id", "do", "dolore", "exercitation" ], "friends": [ { "id": 0, "name": "Paige Garza" }, { "id": 1, "name": "Myers Tyson" }, { "id": 2, "name": "Michael Dalton" }, { "id": 3, "name": "Buckley Pearson" }, { "id": 4, "name": "Tiffany Sloan" } ], "greeting": "Hello, Aisha Young! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48264ae70ae81bbd10de", "index": 342, "guid": "f5f59d0d-b965-41ea-adc7-7d6df64601d1", "isActive": true, "balance": "$2,369.47", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Vance Wade", "gender": "male", "company": "SONGLINES", "email": "vancewade@songlines.com", "phone": "+1 (986) 435-2638", "address": "603 Cortelyou Road, Swartzville, Illinois, 904", "about": "Reprehenderit ut velit laborum cupidatat labore et. Dolor voluptate adipisicing laboris ea qui ipsum nostrud laboris. Irure fugiat mollit fugiat ullamco labore enim eu ullamco sit enim do exercitation reprehenderit.\r\n", "registered": "2017-12-16T11:03:22 -01:00", "latitude": 45.613699, "longitude": 133.223987, "tags": [ "velit", "dolor", "aute", "incididunt", "nulla", "minim", "ut", "officia", "laboris", "occaecat" ], "friends": [ { "id": 0, "name": "Walter Burt" }, { "id": 1, "name": "Goodwin Shelton" }, { "id": 2, "name": "Reba Combs" }, { "id": 3, "name": "Gonzalez Duncan" }, { "id": 4, "name": "Sheppard Holmes" } ], "greeting": "Hello, Vance Wade! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826c57a4ccf5bf857b0", "index": 343, "guid": "c2ede9e4-6f99-4bd6-b001-dc86a0a12c6f", "isActive": true, "balance": "$3,634.95", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Clarke Moss", "gender": "male", "company": "FROSNEX", "email": "clarkemoss@frosnex.com", "phone": "+1 (867) 508-2158", "address": "565 Decatur Street, Rehrersburg, Oklahoma, 4813", "about": "Eiusmod quis minim laborum irure et adipisicing. Deserunt aliquip reprehenderit velit proident pariatur veniam sint labore aliqua. Esse officia sunt aliquip commodo proident. Sunt sunt tempor eu est commodo ipsum labore nostrud culpa non labore.\r\n", "registered": "2016-07-26T07:07:39 -02:00", "latitude": -60.654788, "longitude": 179.604986, "tags": [ "ad", "reprehenderit", "aute", "dolore", "ullamco", "anim", "consectetur", "do", "irure", "excepteur" ], "friends": [ { "id": 0, "name": "Sears Gill" }, { "id": 1, "name": "Bethany Roy" }, { "id": 2, "name": "Lambert Duke" }, { "id": 3, "name": "Dale Rush" }, { "id": 4, "name": "Callie Wall" } ], "greeting": "Hello, Clarke Moss! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48263705ab6f45e38fb7", "index": 344, "guid": "0d65ef23-60bc-4309-9abe-44317f16068e", "isActive": true, "balance": "$1,829.88", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Alexandria Cervantes", "gender": "female", "company": "EVIDENDS", "email": "alexandriacervantes@evidends.com", "phone": "+1 (943) 434-2135", "address": "925 Harway Avenue, Osage, Delaware, 5349", "about": "Consectetur aliqua ea excepteur nostrud sint nostrud fugiat amet. Do sit ad deserunt adipisicing elit exercitation aliquip quis in cillum reprehenderit. Cupidatat aute consequat consectetur aliquip dolor elit officia cillum fugiat consequat fugiat sit.\r\n", "registered": "2016-01-04T12:22:32 -01:00", "latitude": -79.963829, "longitude": -80.787636, "tags": [ "est", "ad", "enim", "adipisicing", "mollit", "do", "cupidatat", "reprehenderit", "minim", "esse" ], "friends": [ { "id": 0, "name": "Joyce Chan" }, { "id": 1, "name": "Short Hewitt" }, { "id": 2, "name": "Dixie Witt" }, { "id": 3, "name": "Ratliff Marshall" }, { "id": 4, "name": "Rios Ruiz" } ], "greeting": "Hello, Alexandria Cervantes! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482662e658bd746f5062", "index": 345, "guid": "1e235500-e1f9-47c7-ad5b-204ec237771f", "isActive": true, "balance": "$1,772.08", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Bush Richard", "gender": "male", "company": "PRISMATIC", "email": "bushrichard@prismatic.com", "phone": "+1 (966) 521-3252", "address": "229 Willmohr Street, Sardis, Federated States Of Micronesia, 4384", "about": "Aliqua ex exercitation id consequat proident anim pariatur veniam duis incididunt exercitation laboris. Lorem amet tempor voluptate do voluptate voluptate minim. Non amet do mollit esse mollit amet eu adipisicing consequat minim cillum voluptate. Ad aute proident laborum nostrud anim do nisi aute. Qui tempor id laborum nulla excepteur. Dolore occaecat ut irure aute ullamco do cupidatat labore cillum amet non ex esse ipsum.\r\n", "registered": "2017-08-28T06:56:32 -02:00", "latitude": 13.917744, "longitude": 127.180288, "tags": [ "adipisicing", "elit", "eiusmod", "aliqua", "veniam", "et", "enim", "occaecat", "reprehenderit", "laborum" ], "friends": [ { "id": 0, "name": "Daisy Cook" }, { "id": 1, "name": "Shields Alvarez" }, { "id": 2, "name": "Keisha Gardner" }, { "id": 3, "name": "Ina West" }, { "id": 4, "name": "Ballard Carter" } ], "greeting": "Hello, Bush Richard! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482696cd7efab9cd5f10", "index": 346, "guid": "40712355-fa0f-447f-bd0a-3f3c61b0e6bb", "isActive": true, "balance": "$2,149.27", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "green", "name": "Nina Farmer", "gender": "female", "company": "ISOLOGIA", "email": "ninafarmer@isologia.com", "phone": "+1 (804) 483-2530", "address": "110 Heath Place, Coalmont, Florida, 8265", "about": "Laborum dolor non ex sint Lorem cillum reprehenderit. Cupidatat nisi ipsum laboris dolore pariatur velit non incididunt velit est. Nisi magna voluptate fugiat labore. Adipisicing do incididunt aute excepteur sit enim ad irure ullamco sit. Dolor eu aute fugiat fugiat irure cupidatat labore ex minim aliquip tempor est aliquip. Deserunt aliquip laborum nulla anim aliquip aute aliqua.\r\n", "registered": "2016-04-10T12:44:23 -02:00", "latitude": -44.901089, "longitude": 49.344708, "tags": [ "cupidatat", "proident", "mollit", "eiusmod", "consectetur", "ipsum", "deserunt", "consectetur", "sunt", "nisi" ], "friends": [ { "id": 0, "name": "Mayer Michael" }, { "id": 1, "name": "Blair Joseph" }, { "id": 2, "name": "Church Bird" }, { "id": 3, "name": "Kathrine Humphrey" }, { "id": 4, "name": "Caldwell Bray" } ], "greeting": "Hello, Nina Farmer! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826452e5bac9bc07e0c", "index": 347, "guid": "7fbafdc1-60a3-40ea-8dad-c16308f25867", "isActive": false, "balance": "$2,327.72", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Rosales Moody", "gender": "male", "company": "OBLIQ", "email": "rosalesmoody@obliq.com", "phone": "+1 (932) 491-3992", "address": "475 Garden Street, Glasgow, Massachusetts, 9204", "about": "Esse magna veniam amet aute eiusmod laboris irure eu enim sunt officia sint ipsum. Elit ullamco incididunt elit esse commodo. Sint aliquip aliquip irure eiusmod est amet aute dolore culpa nisi. Est elit do aliqua dolore nostrud proident esse do fugiat id deserunt qui aute. Enim dolor velit culpa et non Lorem tempor voluptate nulla. Deserunt cupidatat consequat qui quis cillum qui dolore culpa reprehenderit sint culpa.\r\n", "registered": "2016-03-29T05:20:27 -02:00", "latitude": -35.415954, "longitude": -89.43045, "tags": [ "anim", "aliquip", "veniam", "ullamco", "commodo", "nisi", "veniam", "in", "ullamco", "magna" ], "friends": [ { "id": 0, "name": "Staci Hatfield" }, { "id": 1, "name": "Natalia Clayton" }, { "id": 2, "name": "Myra Mcbride" }, { "id": 3, "name": "Kristie Barlow" }, { "id": 4, "name": "Meadows Mcgowan" } ], "greeting": "Hello, Rosales Moody! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826249edfde945aae60", "index": 348, "guid": "b0ec9461-3e46-469b-ad29-7f9926c688bb", "isActive": false, "balance": "$1,379.83", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "brown", "name": "Foreman Hancock", "gender": "male", "company": "FURNIGEER", "email": "foremanhancock@furnigeer.com", "phone": "+1 (946) 508-3363", "address": "819 Barbey Street, Kingstowne, Mississippi, 8037", "about": "Eu tempor id enim deserunt minim eu. Ea irure voluptate culpa ullamco ex aliquip ea. Laboris aliquip tempor ut duis velit aliqua. Dolore ad cillum nulla dolore nisi consequat excepteur labore dolor qui reprehenderit incididunt ullamco aliqua.\r\n", "registered": "2017-09-07T01:01:36 -02:00", "latitude": -82.509156, "longitude": -114.955872, "tags": [ "aliqua", "commodo", "veniam", "exercitation", "pariatur", "qui", "do", "cupidatat", "reprehenderit", "laboris" ], "friends": [ { "id": 0, "name": "Quinn Preston" }, { "id": 1, "name": "Bolton Marks" }, { "id": 2, "name": "Carla Carson" }, { "id": 3, "name": "Myrna Quinn" }, { "id": 4, "name": "Hale Warren" } ], "greeting": "Hello, Foreman Hancock! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c9eca3503db9b775", "index": 349, "guid": "8201f4b7-c67b-44e8-858c-1c8733200430", "isActive": false, "balance": "$2,413.94", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "brown", "name": "Daniels Copeland", "gender": "male", "company": "ZILLATIDE", "email": "danielscopeland@zillatide.com", "phone": "+1 (819) 475-3435", "address": "426 Front Street, Baker, Guam, 8000", "about": "Commodo amet nostrud cillum in deserunt laborum eiusmod est enim sint elit eu consequat. Tempor est minim aliqua nostrud sint pariatur ipsum pariatur. Dolore duis Lorem pariatur labore incididunt Lorem pariatur voluptate sunt. Incididunt voluptate deserunt nulla nostrud cillum qui ipsum in et nulla. Pariatur eiusmod laboris laboris laborum esse minim irure duis nulla ex occaecat et commodo esse. Pariatur sit esse mollit laboris labore pariatur elit adipisicing culpa voluptate mollit dolor duis ipsum.\r\n", "registered": "2017-04-12T07:54:05 -02:00", "latitude": 61.940608, "longitude": 9.446675, "tags": [ "magna", "laboris", "aliqua", "consequat", "officia", "est", "esse", "quis", "adipisicing", "labore" ], "friends": [ { "id": 0, "name": "Sophie Buchanan" }, { "id": 1, "name": "Tonya Roberts" }, { "id": 2, "name": "Kristina Clements" }, { "id": 3, "name": "Carmela Figueroa" }, { "id": 4, "name": "Noreen Weaver" } ], "greeting": "Hello, Daniels Copeland! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482664af8f5fb39d3e80", "index": 350, "guid": "f789af66-f07e-4d00-997e-ab1cd94d150f", "isActive": false, "balance": "$2,727.87", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Coffey Rasmussen", "gender": "male", "company": "SOPRANO", "email": "coffeyrasmussen@soprano.com", "phone": "+1 (987) 556-2758", "address": "977 Madison Place, Disautel, Louisiana, 9928", "about": "Voluptate est reprehenderit sit aliqua anim id nisi aliquip nulla consequat est tempor. Adipisicing deserunt ipsum officia ullamco id et ea aute fugiat minim. Excepteur officia ad laboris dolore laborum ullamco aute ea ut exercitation dolore eu.\r\n", "registered": "2015-10-20T06:40:08 -02:00", "latitude": 47.039814, "longitude": 29.264499, "tags": [ "est", "cupidatat", "voluptate", "eu", "sint", "sit", "nulla", "labore", "nisi", "aliquip" ], "friends": [ { "id": 0, "name": "Haley Hoffman" }, { "id": 1, "name": "Dorothy Scott" }, { "id": 2, "name": "Black Raymond" }, { "id": 3, "name": "Claudia Atkins" }, { "id": 4, "name": "Jerry Dickson" } ], "greeting": "Hello, Coffey Rasmussen! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826f4c627769ee56e6c", "index": 351, "guid": "b9200c2f-f0f2-4a7c-8a63-01b02a1d5063", "isActive": true, "balance": "$3,420.92", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "blue", "name": "Mitchell Mcguire", "gender": "male", "company": "QUILTIGEN", "email": "mitchellmcguire@quiltigen.com", "phone": "+1 (946) 599-2881", "address": "508 Harbor Court, Rew, South Dakota, 4114", "about": "Reprehenderit mollit aliquip elit anim do proident id qui fugiat laborum minim ex. Consectetur non ad ex eu nostrud consequat est dolore quis non sit occaecat culpa. Labore elit sunt incididunt nisi id pariatur anim voluptate aute labore et nostrud. Ex incididunt eu aliquip reprehenderit excepteur ad pariatur minim reprehenderit culpa. Qui occaecat laboris est et.\r\n", "registered": "2015-11-08T01:07:42 -01:00", "latitude": 11.271038, "longitude": 24.555747, "tags": [ "fugiat", "est", "ullamco", "sit", "eiusmod", "duis", "anim", "amet", "nostrud", "reprehenderit" ], "friends": [ { "id": 0, "name": "Olive Osborn" }, { "id": 1, "name": "William Fields" }, { "id": 2, "name": "Conway Dillard" }, { "id": 3, "name": "Sharron Jarvis" }, { "id": 4, "name": "Ana Hubbard" } ], "greeting": "Hello, Mitchell Mcguire! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b463c76d4e0ee85d", "index": 352, "guid": "409cd25d-14ff-45c3-9dee-2216dd93b9f4", "isActive": false, "balance": "$1,880.82", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Beck Elliott", "gender": "male", "company": "CIPROMOX", "email": "beckelliott@cipromox.com", "phone": "+1 (924) 444-2412", "address": "140 Jerome Avenue, Kempton, District Of Columbia, 2751", "about": "Culpa est reprehenderit deserunt officia consectetur labore dolor dolor ea. Sint incididunt ullamco cupidatat mollit tempor amet. Nisi pariatur labore ipsum qui ullamco commodo cillum et duis eiusmod.\r\n", "registered": "2017-07-18T06:30:52 -02:00", "latitude": 47.896835, "longitude": -170.289939, "tags": [ "voluptate", "non", "laboris", "id", "eiusmod", "excepteur", "ullamco", "est", "velit", "eu" ], "friends": [ { "id": 0, "name": "Wong Davidson" }, { "id": 1, "name": "Larson Cole" }, { "id": 2, "name": "Davidson William" }, { "id": 3, "name": "Annabelle Pollard" }, { "id": 4, "name": "Tisha Green" } ], "greeting": "Hello, Beck Elliott! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f45901486ac13442", "index": 353, "guid": "9ff0fe89-cba7-4cfa-b143-e7e27b3ae660", "isActive": true, "balance": "$1,480.09", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Dunlap Hampton", "gender": "male", "company": "VITRICOMP", "email": "dunlaphampton@vitricomp.com", "phone": "+1 (928) 460-3837", "address": "803 Willoughby Street, Outlook, Puerto Rico, 2464", "about": "Do laboris elit officia non aliqua dolor magna Lorem. Nostrud nisi enim enim consectetur consectetur commodo eu ut anim ullamco est esse. Enim dolor culpa est ullamco velit laboris enim cillum ullamco voluptate fugiat fugiat tempor. Minim duis dolor laboris qui adipisicing in ad. Incididunt sit do aute ad dolor nulla ad Lorem qui reprehenderit. In esse in ad aliquip fugiat sit Lorem amet ullamco velit id exercitation.\r\n", "registered": "2015-05-08T10:42:33 -02:00", "latitude": 70.634408, "longitude": -127.888686, "tags": [ "labore", "ut", "aliqua", "nostrud", "et", "mollit", "veniam", "labore", "sit", "in" ], "friends": [ { "id": 0, "name": "Dollie Abbott" }, { "id": 1, "name": "Robert Campos" }, { "id": 2, "name": "Graves Pickett" }, { "id": 3, "name": "Valdez Ingram" }, { "id": 4, "name": "Becky Howell" } ], "greeting": "Hello, Dunlap Hampton! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f6826c4a3fea6cf2", "index": 354, "guid": "82be953c-22e1-4995-a4f5-8ebff207c4cd", "isActive": true, "balance": "$3,911.97", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Allen Greene", "gender": "male", "company": "VERTON", "email": "allengreene@verton.com", "phone": "+1 (887) 565-3696", "address": "624 Brighton Avenue, Leland, Maine, 4126", "about": "Amet sint ad do deserunt veniam in. Dolor sit esse eu fugiat sunt velit qui fugiat enim ullamco eiusmod. Non ea aute ut nisi in occaecat incididunt excepteur magna aliqua amet deserunt qui. Magna do eiusmod veniam ad nostrud ullamco et ullamco eiusmod ad commodo labore. Veniam eu duis pariatur do voluptate et officia consectetur commodo ad.\r\n", "registered": "2017-10-23T10:44:43 -02:00", "latitude": 86.242764, "longitude": 3.360296, "tags": [ "ea", "aliqua", "aliqua", "in", "excepteur", "consectetur", "nulla", "ullamco", "commodo", "ut" ], "friends": [ { "id": 0, "name": "Peggy Christensen" }, { "id": 1, "name": "Acosta Miles" }, { "id": 2, "name": "Booth Holden" }, { "id": 3, "name": "Conrad Newton" }, { "id": 4, "name": "Sondra Bowen" } ], "greeting": "Hello, Allen Greene! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482602dd82ad3e0148c6", "index": 355, "guid": "a0d70961-a7d4-47b5-bd29-65a631b4df97", "isActive": true, "balance": "$1,841.13", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "blue", "name": "Frye Griffith", "gender": "male", "company": "NORALI", "email": "fryegriffith@norali.com", "phone": "+1 (994) 569-2793", "address": "970 Elm Place, Belmont, New Jersey, 5505", "about": "In cupidatat labore officia aute sunt officia. In anim ullamco anim duis mollit excepteur occaecat aute officia consequat. Enim elit ad adipisicing consequat ea ipsum veniam commodo id. Incididunt reprehenderit adipisicing occaecat id laborum amet id cillum ut ipsum fugiat aute aliquip irure. Excepteur magna enim cillum incididunt fugiat mollit anim. Et ex eiusmod aute cupidatat do ullamco Lorem eu fugiat dolor labore labore. Quis est voluptate sint laboris veniam anim aliqua.\r\n", "registered": "2014-03-30T02:29:23 -02:00", "latitude": 66.335858, "longitude": 120.965779, "tags": [ "enim", "reprehenderit", "consectetur", "eu", "ea", "incididunt", "eiusmod", "enim", "ut", "eiusmod" ], "friends": [ { "id": 0, "name": "Lynch Martin" }, { "id": 1, "name": "Christian Glass" }, { "id": 2, "name": "Cathy Barker" }, { "id": 3, "name": "Marcy Torres" }, { "id": 4, "name": "Wood Beasley" } ], "greeting": "Hello, Frye Griffith! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482698c9cb56f9de9c78", "index": 356, "guid": "2afd79cf-4ea0-4637-9efa-7034e3574cea", "isActive": false, "balance": "$3,045.67", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Thelma Roman", "gender": "female", "company": "TRANSLINK", "email": "thelmaroman@translink.com", "phone": "+1 (995) 483-2629", "address": "152 Fleet Place, Itmann, Michigan, 4691", "about": "Incididunt dolore est velit occaecat nulla reprehenderit id ipsum cupidatat. Do minim voluptate sint consequat. Mollit labore Lorem esse non non dolor aliquip elit laboris. Proident velit aliqua consectetur Lorem mollit proident et magna irure aute nostrud. Esse deserunt aliquip ut pariatur occaecat veniam officia amet do est officia. Pariatur enim deserunt non esse duis pariatur consectetur ea pariatur deserunt officia ex incididunt occaecat.\r\n", "registered": "2016-09-16T01:01:11 -02:00", "latitude": -72.409287, "longitude": -144.347454, "tags": [ "ad", "dolore", "labore", "fugiat", "qui", "Lorem", "amet", "ex", "dolor", "mollit" ], "friends": [ { "id": 0, "name": "Langley Powell" }, { "id": 1, "name": "Margret Booker" }, { "id": 2, "name": "Cleo Garcia" }, { "id": 3, "name": "Patty Grant" }, { "id": 4, "name": "Angel Wilkinson" } ], "greeting": "Hello, Thelma Roman! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482679b7056e318d53df", "index": 357, "guid": "4e7eb047-17db-4f9f-b505-1f22576d8167", "isActive": true, "balance": "$1,288.45", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "blue", "name": "Macias Delaney", "gender": "male", "company": "EPLOSION", "email": "maciasdelaney@eplosion.com", "phone": "+1 (808) 409-3644", "address": "720 Whitty Lane, Watrous, Rhode Island, 3647", "about": "Dolor esse Lorem officia exercitation ad laborum qui sint non. Laborum adipisicing minim laboris cupidatat amet aliqua est aliquip ex mollit in. Anim mollit sint consequat ullamco. Cillum est in occaecat exercitation nostrud aute elit duis exercitation incididunt irure non aliqua. Labore sint aliquip commodo laborum reprehenderit anim sit deserunt elit esse ad occaecat. Aute velit nisi enim esse eiusmod proident ullamco.\r\n", "registered": "2016-07-11T10:36:55 -02:00", "latitude": 83.612615, "longitude": -178.55378, "tags": [ "incididunt", "aliquip", "non", "magna", "sint", "dolor", "aliquip", "elit", "ipsum", "id" ], "friends": [ { "id": 0, "name": "Ester Logan" }, { "id": 1, "name": "Therese Reid" }, { "id": 2, "name": "Conner Kinney" }, { "id": 3, "name": "Emilia Graves" }, { "id": 4, "name": "Maude Berry" } ], "greeting": "Hello, Macias Delaney! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826209ec7684ee52583", "index": 358, "guid": "8d212975-9be6-43b1-b3ee-7c837937c9db", "isActive": false, "balance": "$2,367.52", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "brown", "name": "Elvia Ramsey", "gender": "female", "company": "LUXURIA", "email": "elviaramsey@luxuria.com", "phone": "+1 (936) 412-3779", "address": "451 Beaumont Street, Cutter, Kansas, 1765", "about": "Commodo incididunt nostrud consequat fugiat anim mollit ea minim mollit cupidatat eiusmod laborum. Ut nostrud fugiat duis consequat aliqua nulla in aliqua voluptate non cupidatat. Officia dolore ullamco culpa occaecat eiusmod adipisicing incididunt cupidatat eu sunt exercitation officia veniam. Cillum incididunt quis labore sit reprehenderit duis nisi aliqua qui nisi sunt irure aute ea. Amet do incididunt cupidatat veniam cillum. Reprehenderit adipisicing ea amet qui minim anim dolore enim cupidatat laborum. Eu do non cillum id occaecat ea.\r\n", "registered": "2016-09-04T08:22:03 -02:00", "latitude": 63.702043, "longitude": 93.14206, "tags": [ "eiusmod", "consequat", "ut", "enim", "enim", "incididunt", "velit", "officia", "cupidatat", "consequat" ], "friends": [ { "id": 0, "name": "Mercer Richmond" }, { "id": 1, "name": "Cole Kline" }, { "id": 2, "name": "Carolina Peterson" }, { "id": 3, "name": "Mann Bentley" }, { "id": 4, "name": "Abbott Wagner" } ], "greeting": "Hello, Elvia Ramsey! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48260d99c87006530ca3", "index": 359, "guid": "245cbb26-809c-4722-9ec6-b2dc15c41b15", "isActive": false, "balance": "$1,301.15", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Odom Shepard", "gender": "male", "company": "ASIMILINE", "email": "odomshepard@asimiline.com", "phone": "+1 (913) 475-3879", "address": "737 Seba Avenue, Stouchsburg, West Virginia, 177", "about": "Veniam mollit mollit consequat velit pariatur aute dolore ipsum sint adipisicing non ut veniam proident. Ullamco enim pariatur duis occaecat cillum ad est consequat. Eiusmod ut in officia aliqua ullamco. Proident magna est consequat quis excepteur.\r\n", "registered": "2015-10-12T02:12:20 -02:00", "latitude": -7.765221, "longitude": 147.916666, "tags": [ "tempor", "labore", "aliquip", "sit", "irure", "enim", "quis", "voluptate", "cupidatat", "sint" ], "friends": [ { "id": 0, "name": "Rogers Merrill" }, { "id": 1, "name": "Garrison Armstrong" }, { "id": 2, "name": "Cherry Shepherd" }, { "id": 3, "name": "Hooper Spence" }, { "id": 4, "name": "Cunningham Conrad" } ], "greeting": "Hello, Odom Shepard! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482668017feea96635ba", "index": 360, "guid": "378bc7c9-0770-4986-a84c-b78153f8eeac", "isActive": false, "balance": "$3,160.57", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "brown", "name": "Griffith Wolf", "gender": "male", "company": "MUSANPOLY", "email": "griffithwolf@musanpoly.com", "phone": "+1 (812) 590-3578", "address": "271 Jay Street, Washington, American Samoa, 2462", "about": "Aliqua proident in commodo Lorem dolore ea irure. Labore duis adipisicing consectetur aute. Reprehenderit in dolor excepteur culpa amet proident est ea eiusmod proident tempor aliquip est.\r\n", "registered": "2015-09-10T08:25:20 -02:00", "latitude": 85.812105, "longitude": -105.395952, "tags": [ "sit", "ad", "laborum", "aute", "qui", "Lorem", "occaecat", "minim", "est", "laboris" ], "friends": [ { "id": 0, "name": "Karina Myers" }, { "id": 1, "name": "Hazel Bullock" }, { "id": 2, "name": "Butler Navarro" }, { "id": 3, "name": "Kitty Haynes" }, { "id": 4, "name": "Kelli Benson" } ], "greeting": "Hello, Griffith Wolf! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48265a5144d390d42f8f", "index": 361, "guid": "5463dd0c-0555-4422-a8ee-eea7752fd370", "isActive": false, "balance": "$3,928.44", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "brown", "name": "Veronica Stuart", "gender": "female", "company": "OATFARM", "email": "veronicastuart@oatfarm.com", "phone": "+1 (961) 564-3830", "address": "962 Dover Street, Lindcove, Maryland, 2003", "about": "Lorem ad magna consectetur esse dolor duis qui tempor deserunt aliquip ut sit dolor mollit. Voluptate eu est tempor nostrud culpa velit incididunt non sint deserunt irure est. Minim in consectetur velit ad ea Lorem reprehenderit consectetur. Sint Lorem ea tempor do anim sint sunt esse ut commodo eu.\r\n", "registered": "2016-12-06T11:30:25 -01:00", "latitude": 84.271015, "longitude": 175.846964, "tags": [ "culpa", "commodo", "non", "do", "incididunt", "in", "ea", "incididunt", "ex", "mollit" ], "friends": [ { "id": 0, "name": "Marina Sweet" }, { "id": 1, "name": "Cote Watts" }, { "id": 2, "name": "May Sims" }, { "id": 3, "name": "Jocelyn Hernandez" }, { "id": 4, "name": "Ryan Knox" } ], "greeting": "Hello, Veronica Stuart! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826a9478245cb34f46b", "index": 362, "guid": "baa54079-cf22-4119-8120-d0086f7021f8", "isActive": true, "balance": "$3,886.62", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Wright Norris", "gender": "male", "company": "XOGGLE", "email": "wrightnorris@xoggle.com", "phone": "+1 (810) 594-3510", "address": "812 High Street, Ivanhoe, California, 5046", "about": "Labore aliqua amet nostrud aliqua minim nisi minim consequat tempor fugiat voluptate ad fugiat. Officia ut quis pariatur ipsum minim ex nostrud deserunt non sunt sint ad enim. Anim tempor in in occaecat nisi labore cupidatat mollit Lorem. Laborum velit minim fugiat aliqua incididunt aliqua elit. Eiusmod ex non elit nostrud labore qui. Proident consequat irure fugiat do et. Ea nulla ea ex labore ut ad aliqua reprehenderit.\r\n", "registered": "2017-12-13T02:23:19 -01:00", "latitude": 56.935919, "longitude": 23.662689, "tags": [ "nisi", "duis", "Lorem", "mollit", "dolore", "fugiat", "et", "pariatur", "ea", "laborum" ], "friends": [ { "id": 0, "name": "Pace Cotton" }, { "id": 1, "name": "Beryl Guzman" }, { "id": 2, "name": "Harris Ferrell" }, { "id": 3, "name": "Marcie Nichols" }, { "id": 4, "name": "Casey Flores" } ], "greeting": "Hello, Wright Norris! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826aa68aefca8397f5d", "index": 363, "guid": "78d68f9e-a40e-4c42-8fdd-50cc5c8075a6", "isActive": false, "balance": "$1,088.07", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Vazquez Cabrera", "gender": "male", "company": "ENTALITY", "email": "vazquezcabrera@entality.com", "phone": "+1 (852) 466-3356", "address": "564 River Street, Yonah, Utah, 6279", "about": "Exercitation id culpa reprehenderit laboris. Consectetur occaecat et eiusmod cupidatat mollit esse veniam occaecat. Consequat proident aliquip commodo excepteur exercitation do veniam velit consequat ut labore ad deserunt sint. Nisi aute magna dolor nisi et in veniam esse consectetur esse veniam ea ipsum magna. Nulla sunt consequat deserunt nostrud ex est nulla amet id anim laboris sit labore irure.\r\n", "registered": "2017-12-01T09:37:27 -01:00", "latitude": 87.424298, "longitude": -103.385906, "tags": [ "occaecat", "dolore", "reprehenderit", "nostrud", "consectetur", "aute", "culpa", "sit", "nisi", "cupidatat" ], "friends": [ { "id": 0, "name": "Sara Hunter" }, { "id": 1, "name": "Tracy Hanson" }, { "id": 2, "name": "Oneal Stevenson" }, { "id": 3, "name": "Graciela Lowe" }, { "id": 4, "name": "Yesenia Wise" } ], "greeting": "Hello, Vazquez Cabrera! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48268175fa6fbec0693c", "index": 364, "guid": "53f23fa5-5a95-4e02-beea-d9ea7949f8a2", "isActive": false, "balance": "$1,398.76", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "green", "name": "Kristin Conner", "gender": "female", "company": "ELPRO", "email": "kristinconner@elpro.com", "phone": "+1 (889) 444-2970", "address": "787 Malta Street, Marne, Iowa, 2630", "about": "Anim nisi veniam anim exercitation et eiusmod minim labore aute ut qui minim. Quis irure aliqua ut quis in consequat eiusmod. Nulla nulla aute do veniam aliqua veniam dolor qui commodo enim. Officia laboris velit ea laboris ipsum.\r\n", "registered": "2014-08-25T08:00:05 -02:00", "latitude": 63.871299, "longitude": -132.002008, "tags": [ "dolore", "mollit", "elit", "mollit", "ipsum", "dolor", "id", "aliquip", "ad", "adipisicing" ], "friends": [ { "id": 0, "name": "Snow Mcdowell" }, { "id": 1, "name": "Elaine Middleton" }, { "id": 2, "name": "Knox Guthrie" }, { "id": 3, "name": "Cash Chandler" }, { "id": 4, "name": "Heather Mclaughlin" } ], "greeting": "Hello, Kristin Conner! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826f112eb123b59e4d9", "index": 365, "guid": "b27cd9ed-c59b-40a1-8623-bffe71ca5488", "isActive": false, "balance": "$2,967.32", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "brown", "name": "Moon Lucas", "gender": "male", "company": "ANIVET", "email": "moonlucas@anivet.com", "phone": "+1 (986) 578-3662", "address": "711 Bassett Avenue, Gibsonia, North Dakota, 9415", "about": "Commodo elit eu irure ex eu eiusmod ipsum et laboris enim dolore nulla fugiat enim. Excepteur non dolor anim ipsum Lorem nisi eu eu mollit incididunt Lorem Lorem ipsum. Sit ullamco esse elit qui id officia minim nulla qui ut proident eu exercitation. Eiusmod consequat aliqua deserunt commodo excepteur excepteur sunt est fugiat.\r\n", "registered": "2015-11-18T04:08:00 -01:00", "latitude": 82.791788, "longitude": 150.204495, "tags": [ "consectetur", "eiusmod", "proident", "tempor", "magna", "veniam", "ipsum", "velit", "ut", "culpa" ], "friends": [ { "id": 0, "name": "Paulette Page" }, { "id": 1, "name": "Rocha Butler" }, { "id": 2, "name": "Moreno Prince" }, { "id": 3, "name": "Wiggins Jordan" }, { "id": 4, "name": "Carrillo Morton" } ], "greeting": "Hello, Moon Lucas! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826cc13db9d0e2a1bc6", "index": 366, "guid": "5557cc94-29d4-43e9-a7d2-bcaabada38dd", "isActive": false, "balance": "$2,156.89", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Joanne Hobbs", "gender": "female", "company": "EXODOC", "email": "joannehobbs@exodoc.com", "phone": "+1 (876) 448-2793", "address": "413 Lott Place, Shawmut, Kentucky, 6927", "about": "Aliqua eiusmod aliquip ea consequat cillum quis cillum id dolore ex incididunt. Qui elit amet anim fugiat sint aute nisi laborum pariatur laboris proident qui Lorem. Commodo occaecat Lorem nulla anim ipsum velit sit voluptate eiusmod aliquip. Minim irure sunt commodo commodo elit aliqua amet. Anim qui velit et excepteur officia aute voluptate non occaecat do dolore consectetur non enim. Exercitation ad officia eu occaecat sunt veniam et esse elit nulla. Non reprehenderit laborum non deserunt elit anim dolor fugiat aute ipsum voluptate.\r\n", "registered": "2017-08-01T01:56:50 -02:00", "latitude": -56.628016, "longitude": -114.395674, "tags": [ "duis", "elit", "labore", "officia", "Lorem", "est", "anim", "voluptate", "culpa", "et" ], "friends": [ { "id": 0, "name": "Monique Deleon" }, { "id": 1, "name": "Figueroa Perkins" }, { "id": 2, "name": "Ethel Kemp" }, { "id": 3, "name": "Goff Hogan" }, { "id": 4, "name": "Alta Webster" } ], "greeting": "Hello, Joanne Hobbs! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826382e92e622666505", "index": 367, "guid": "857ba0ee-c0c1-4c51-85bd-8b7b863e5e98", "isActive": true, "balance": "$3,017.64", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "York Hunt", "gender": "male", "company": "AMTAP", "email": "yorkhunt@amtap.com", "phone": "+1 (936) 503-3810", "address": "227 Bedford Avenue, Glenville, Colorado, 5975", "about": "Voluptate et labore ad et exercitation deserunt Lorem sit ex eu dolore. Ut cupidatat velit officia ad ullamco magna occaecat velit eiusmod. Anim in id labore qui mollit excepteur aliquip proident. Qui consectetur dolor pariatur proident aliqua minim.\r\n", "registered": "2015-07-12T03:17:22 -02:00", "latitude": -26.073237, "longitude": 31.31745, "tags": [ "minim", "reprehenderit", "anim", "duis", "est", "velit", "voluptate", "irure", "mollit", "commodo" ], "friends": [ { "id": 0, "name": "Gaines Emerson" }, { "id": 1, "name": "Schmidt Mcleod" }, { "id": 2, "name": "Emma Hughes" }, { "id": 3, "name": "Lisa Haley" }, { "id": 4, "name": "Alyson Lyons" } ], "greeting": "Hello, York Hunt! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482698cfb93006dcda9a", "index": 368, "guid": "6ca6a435-279e-4d49-88b7-6406df6e3600", "isActive": false, "balance": "$2,767.02", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Medina Walton", "gender": "male", "company": "SOLAREN", "email": "medinawalton@solaren.com", "phone": "+1 (963) 584-2335", "address": "142 Verona Place, Smeltertown, New Hampshire, 661", "about": "Irure proident pariatur reprehenderit aute veniam ea sit. Et cillum do laboris pariatur voluptate cupidatat. Sunt irure sunt ipsum duis. Amet reprehenderit occaecat in laboris commodo sit qui culpa in laboris. Excepteur est ullamco nulla cillum ut pariatur eiusmod veniam nostrud veniam anim duis ullamco sit. Id ad ex occaecat reprehenderit proident incididunt laborum commodo occaecat.\r\n", "registered": "2014-08-04T06:44:52 -02:00", "latitude": -26.211922, "longitude": 66.748187, "tags": [ "elit", "pariatur", "qui", "fugiat", "cillum", "eu", "ad", "qui", "laborum", "nulla" ], "friends": [ { "id": 0, "name": "Freda Guy" }, { "id": 1, "name": "Marlene Irwin" }, { "id": 2, "name": "Doreen Herring" }, { "id": 3, "name": "Shawn Solis" }, { "id": 4, "name": "Blanche Fuller" } ], "greeting": "Hello, Medina Walton! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261c5a4e4ed01f4f4e", "index": 369, "guid": "e2fe8558-e4a9-4d9a-aba1-a9c6555bf717", "isActive": false, "balance": "$3,336.77", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Pearl Bruce", "gender": "female", "company": "GREEKER", "email": "pearlbruce@greeker.com", "phone": "+1 (809) 437-3819", "address": "648 Kathleen Court, Allensworth, Wisconsin, 1056", "about": "Occaecat exercitation ex est do. Id ut proident commodo tempor deserunt est culpa deserunt anim. Amet fugiat duis sit nostrud Lorem laborum occaecat in eu. Laboris elit ipsum enim exercitation minim aliquip mollit. Elit sint cupidatat esse nisi. Ipsum incididunt officia fugiat ex nisi reprehenderit eiusmod est est. Minim et qui cupidatat enim.\r\n", "registered": "2015-04-29T01:11:08 -02:00", "latitude": 61.694732, "longitude": 10.519194, "tags": [ "velit", "ad", "nostrud", "eiusmod", "exercitation", "ullamco", "velit", "culpa", "ad", "esse" ], "friends": [ { "id": 0, "name": "French Benton" }, { "id": 1, "name": "Alfreda Oneal" }, { "id": 2, "name": "Stefanie Hess" }, { "id": 3, "name": "Morse Leach" }, { "id": 4, "name": "Mosley Sargent" } ], "greeting": "Hello, Pearl Bruce! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482684904ca41e87fe40", "index": 370, "guid": "20fe23e9-0e88-4004-a56f-af326146a88f", "isActive": false, "balance": "$2,564.81", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Letha Leblanc", "gender": "female", "company": "SNIPS", "email": "lethaleblanc@snips.com", "phone": "+1 (869) 495-2893", "address": "776 Navy Street, Boyd, Idaho, 2241", "about": "Deserunt occaecat consequat eu dolor aliquip elit reprehenderit aliqua ad voluptate officia consectetur. Sint anim velit dolor aliquip. Consectetur do exercitation excepteur sunt adipisicing nulla esse dolor id. Do sint anim duis incididunt duis sint. Incididunt pariatur nulla do veniam pariatur exercitation. Labore ex adipisicing in tempor quis commodo Lorem adipisicing aute est. Reprehenderit dolore eiusmod do quis velit.\r\n", "registered": "2016-09-16T08:54:37 -02:00", "latitude": 37.844231, "longitude": 163.576666, "tags": [ "exercitation", "ea", "quis", "excepteur", "est", "ipsum", "enim", "nulla", "dolor", "culpa" ], "friends": [ { "id": 0, "name": "Helga Jenkins" }, { "id": 1, "name": "Wheeler Gordon" }, { "id": 2, "name": "Krista Conley" }, { "id": 3, "name": "Peck Rutledge" }, { "id": 4, "name": "Tami Baird" } ], "greeting": "Hello, Letha Leblanc! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c0ad0f5d2304c608", "index": 371, "guid": "e54c3ed6-5805-414e-9ab2-e882ad91583b", "isActive": true, "balance": "$1,361.89", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "blue", "name": "Donovan Finch", "gender": "male", "company": "GEEKETRON", "email": "donovanfinch@geeketron.com", "phone": "+1 (895) 450-3731", "address": "955 Fleet Walk, Walton, Georgia, 2064", "about": "Ea ut voluptate ex enim aute dolore deserunt exercitation officia amet ad commodo. Officia do est velit enim officia veniam. Ipsum quis occaecat consectetur nisi. Enim amet officia ad laborum commodo pariatur ipsum reprehenderit et.\r\n", "registered": "2016-09-07T07:23:09 -02:00", "latitude": -89.282409, "longitude": 165.299581, "tags": [ "Lorem", "mollit", "id", "et", "exercitation", "esse", "eu", "et", "officia", "anim" ], "friends": [ { "id": 0, "name": "Santana Cruz" }, { "id": 1, "name": "Kristi Bailey" }, { "id": 2, "name": "Mejia England" }, { "id": 3, "name": "Katy Gamble" }, { "id": 4, "name": "Hobbs Chambers" } ], "greeting": "Hello, Donovan Finch! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826c9dced57fa8ddfec", "index": 372, "guid": "3d97367e-ea8d-4513-a2d2-8e66cfa5ceb0", "isActive": false, "balance": "$2,027.06", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Carrie Castillo", "gender": "female", "company": "UNCORP", "email": "carriecastillo@uncorp.com", "phone": "+1 (992) 406-2385", "address": "370 Amity Street, Thatcher, Virgin Islands, 9020", "about": "Aliqua irure esse Lorem in eiusmod nostrud tempor culpa ipsum amet incididunt. Enim duis aliquip sit eu commodo amet voluptate consectetur cupidatat officia. Excepteur consequat deserunt ipsum ad eu laborum amet voluptate quis enim.\r\n", "registered": "2016-02-29T09:48:10 -01:00", "latitude": 4.822045, "longitude": -36.105255, "tags": [ "do", "adipisicing", "magna", "esse", "ad", "nulla", "sit", "fugiat", "consequat", "ex" ], "friends": [ { "id": 0, "name": "Spence Lowery" }, { "id": 1, "name": "Beach Cross" }, { "id": 2, "name": "Duffy Santos" }, { "id": 3, "name": "Matilda Langley" }, { "id": 4, "name": "Evangelina Good" } ], "greeting": "Hello, Carrie Castillo! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482641ded07e42b39cc9", "index": 373, "guid": "58af8aae-6355-4fbb-83e9-d2c5427ddaba", "isActive": true, "balance": "$3,166.76", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "green", "name": "Fleming Jimenez", "gender": "male", "company": "CUBICIDE", "email": "flemingjimenez@cubicide.com", "phone": "+1 (976) 482-2042", "address": "606 Grafton Street, Kohatk, Minnesota, 5947", "about": "Cupidatat anim amet reprehenderit veniam tempor tempor aliquip enim tempor id enim. Excepteur aute adipisicing mollit aute est minim et anim fugiat. Adipisicing eiusmod officia qui tempor ex incididunt amet do. Dolore ut ea non sunt eiusmod ex excepteur.\r\n", "registered": "2018-01-06T09:23:42 -01:00", "latitude": 25.350457, "longitude": -93.568558, "tags": [ "tempor", "excepteur", "sit", "consequat", "aliqua", "pariatur", "cillum", "ad", "est", "ut" ], "friends": [ { "id": 0, "name": "Hyde Fernandez" }, { "id": 1, "name": "Jeri Parrish" }, { "id": 2, "name": "Maryann Avery" }, { "id": 3, "name": "Lily Hurst" }, { "id": 4, "name": "Mayra Suarez" } ], "greeting": "Hello, Fleming Jimenez! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826c11083964a860b3c", "index": 374, "guid": "d06fc1d2-c8a2-4e2f-8ac8-0e9eb332c86a", "isActive": false, "balance": "$1,276.54", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "brown", "name": "Robinson Reeves", "gender": "male", "company": "PORTICA", "email": "robinsonreeves@portica.com", "phone": "+1 (896) 427-2166", "address": "882 Meadow Street, Cazadero, South Carolina, 2043", "about": "Ullamco amet quis voluptate nostrud nisi ullamco est. Duis eu incididunt fugiat occaecat consectetur fugiat et sint labore sunt laborum sint. Aliquip do aliqua velit et quis eiusmod eu pariatur.\r\n", "registered": "2017-03-31T02:52:57 -02:00", "latitude": -7.68662, "longitude": 42.483666, "tags": [ "ut", "dolore", "proident", "fugiat", "minim", "minim", "Lorem", "non", "tempor", "qui" ], "friends": [ { "id": 0, "name": "Collier Mclean" }, { "id": 1, "name": "Jacobson Guerrero" }, { "id": 2, "name": "Eliza Perry" }, { "id": 3, "name": "Hilda Fulton" }, { "id": 4, "name": "Winifred Harrell" } ], "greeting": "Hello, Robinson Reeves! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826336f0f470e2f9305", "index": 375, "guid": "6882bedc-c836-4cda-8794-17089adf38e0", "isActive": false, "balance": "$3,379.54", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "blue", "name": "Kennedy Odom", "gender": "male", "company": "KONGENE", "email": "kennedyodom@kongene.com", "phone": "+1 (833) 437-2167", "address": "474 Strong Place, Bethany, Northern Mariana Islands, 6938", "about": "Deserunt ut dolore proident deserunt proident occaecat labore fugiat qui. Aliquip cupidatat velit velit non. Laboris labore laborum enim mollit ipsum tempor id ex. Sit dolore cillum ipsum commodo excepteur officia officia duis reprehenderit ad quis id esse. Dolore fugiat dolore ex sit enim deserunt ullamco voluptate laborum. Sunt laborum et commodo qui.\r\n", "registered": "2016-12-02T08:27:54 -01:00", "latitude": -62.18234, "longitude": -113.824271, "tags": [ "et", "labore", "commodo", "ad", "nisi", "exercitation", "ea", "aliquip", "dolor", "irure" ], "friends": [ { "id": 0, "name": "Skinner Newman" }, { "id": 1, "name": "Anthony Cote" }, { "id": 2, "name": "Queen Yang" }, { "id": 3, "name": "Fuller Mayer" }, { "id": 4, "name": "Rhoda Mendez" } ], "greeting": "Hello, Kennedy Odom! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482612fd7489f7b15c68", "index": 376, "guid": "d519cb2d-1ccd-43e8-b2b5-a49aa5d62b6b", "isActive": false, "balance": "$1,889.84", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Toni Watson", "gender": "female", "company": "DANCERITY", "email": "toniwatson@dancerity.com", "phone": "+1 (830) 498-2859", "address": "872 Orient Avenue, Kenwood, Pennsylvania, 1925", "about": "Cupidatat excepteur aute amet eu amet magna. In culpa commodo est duis eiusmod labore enim commodo ut cupidatat. Adipisicing proident consequat deserunt sunt deserunt fugiat.\r\n", "registered": "2014-07-31T09:06:12 -02:00", "latitude": 32.565215, "longitude": 53.060838, "tags": [ "irure", "velit", "cillum", "velit", "velit", "velit", "reprehenderit", "sint", "sunt", "ullamco" ], "friends": [ { "id": 0, "name": "Gates Washington" }, { "id": 1, "name": "Rutledge Lang" }, { "id": 2, "name": "Karin Cardenas" }, { "id": 3, "name": "Loraine Wynn" }, { "id": 4, "name": "Becker Golden" } ], "greeting": "Hello, Toni Watson! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826687ad96e8b82a9d4", "index": 377, "guid": "8c390764-4f6b-49e1-9468-4c9986464aa9", "isActive": true, "balance": "$1,102.64", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Nadia Cantu", "gender": "female", "company": "MANGLO", "email": "nadiacantu@manglo.com", "phone": "+1 (864) 451-3933", "address": "459 Schroeders Avenue, Santel, Arkansas, 1206", "about": "Anim nostrud dolore ullamco id. Sint fugiat sunt consectetur qui cupidatat nisi dolor. Mollit enim proident ad sit. Non veniam labore ut voluptate. Tempor magna et nisi ullamco nisi nostrud laborum. Pariatur velit ipsum cillum veniam proident velit nisi eiusmod aute ipsum sunt. In ea et ad eiusmod aliqua proident.\r\n", "registered": "2014-02-21T07:28:35 -01:00", "latitude": 8.850428, "longitude": 65.169009, "tags": [ "qui", "consectetur", "eiusmod", "sunt", "consectetur", "irure", "ad", "duis", "fugiat", "cillum" ], "friends": [ { "id": 0, "name": "Watson Morse" }, { "id": 1, "name": "Stafford Luna" }, { "id": 2, "name": "Daugherty Santiago" }, { "id": 3, "name": "Monica Vinson" }, { "id": 4, "name": "Rivera Salas" } ], "greeting": "Hello, Nadia Cantu! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48263da8b0105450e90d", "index": 378, "guid": "f6a3c9d4-d24d-4cf1-8193-114d1630418c", "isActive": true, "balance": "$1,314.89", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Pope Mayo", "gender": "male", "company": "KINETICA", "email": "popemayo@kinetica.com", "phone": "+1 (841) 407-3980", "address": "764 Logan Street, Gordon, Palau, 2924", "about": "In magna pariatur in do incididunt do et laboris anim dolore. Cupidatat consequat incididunt culpa et ad sit deserunt irure ea in sit ex. Et mollit aliqua aliqua aute anim aliqua sint est elit. Anim elit qui mollit labore ea ex incididunt adipisicing. Qui excepteur tempor cillum dolore tempor occaecat dolor eiusmod.\r\n", "registered": "2014-10-14T12:11:36 -02:00", "latitude": -83.026253, "longitude": -120.660748, "tags": [ "esse", "amet", "sunt", "est", "officia", "do", "ex", "et", "eu", "labore" ], "friends": [ { "id": 0, "name": "Hood Herman" }, { "id": 1, "name": "Alejandra Pena" }, { "id": 2, "name": "Phoebe Murray" }, { "id": 3, "name": "Ada Thomas" }, { "id": 4, "name": "Burton Phelps" } ], "greeting": "Hello, Pope Mayo! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482615ceceb1993ef612", "index": 379, "guid": "48b0408d-3b09-4b67-bc63-1cc11c693b4d", "isActive": false, "balance": "$2,339.65", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Tamika Wolfe", "gender": "female", "company": "FROLIX", "email": "tamikawolfe@frolix.com", "phone": "+1 (842) 568-3648", "address": "146 Covert Street, Tibbie, Connecticut, 4839", "about": "Nulla elit sint fugiat amet. Ex esse irure aliquip tempor. Irure cupidatat dolore Lorem magna.\r\n", "registered": "2017-03-01T04:09:55 -01:00", "latitude": 0.450554, "longitude": -44.464232, "tags": [ "eiusmod", "aliqua", "ullamco", "ex", "fugiat", "adipisicing", "dolor", "qui", "adipisicing", "consectetur" ], "friends": [ { "id": 0, "name": "Sophia Tanner" }, { "id": 1, "name": "Yang Turner" }, { "id": 2, "name": "Finley Horn" }, { "id": 3, "name": "Danielle Mcclain" }, { "id": 4, "name": "Battle Serrano" } ], "greeting": "Hello, Tamika Wolfe! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826d88f314c79877b37", "index": 380, "guid": "39d25d69-16fe-4b7c-8f4e-c6e986bf2411", "isActive": true, "balance": "$3,764.43", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Richardson Molina", "gender": "male", "company": "PETIGEMS", "email": "richardsonmolina@petigems.com", "phone": "+1 (820) 522-2074", "address": "815 Rapelye Street, Maybell, North Carolina, 2791", "about": "Qui commodo tempor et aliquip commodo pariatur consectetur laboris aute consequat ex dolore quis dolore. Amet eiusmod velit minim cillum commodo cupidatat nisi consequat non aute ipsum cillum. Officia occaecat nisi eu non ex. In eu eiusmod ad adipisicing cillum adipisicing. Velit id magna aute proident mollit incididunt non anim excepteur magna adipisicing.\r\n", "registered": "2017-08-22T10:11:20 -02:00", "latitude": -3.905367, "longitude": 138.216927, "tags": [ "anim", "aute", "Lorem", "eiusmod", "minim", "enim", "esse", "commodo", "reprehenderit", "velit" ], "friends": [ { "id": 0, "name": "Haney Mccarty" }, { "id": 1, "name": "Delaney Workman" }, { "id": 2, "name": "Brenda Ross" }, { "id": 3, "name": "Mamie Ramos" }, { "id": 4, "name": "Miriam Russell" } ], "greeting": "Hello, Richardson Molina! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826dbc358f0af7d683a", "index": 381, "guid": "65f00e4e-ff2c-47b8-93af-9d659ab29a57", "isActive": true, "balance": "$1,961.52", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "blue", "name": "Leblanc Cochran", "gender": "male", "company": "XURBAN", "email": "leblanccochran@xurban.com", "phone": "+1 (849) 434-2208", "address": "415 Court Street, Rivera, Missouri, 6111", "about": "Et est quis voluptate ipsum Lorem commodo ipsum. Incididunt ex aute magna officia Lorem. Exercitation consequat ad commodo non cillum ea. Laboris Lorem aute aliquip laborum irure dolore. Commodo sint cupidatat reprehenderit voluptate ex in esse ad amet incididunt aute minim ut amet.\r\n", "registered": "2015-02-26T02:00:49 -01:00", "latitude": -29.20993, "longitude": 168.547698, "tags": [ "magna", "et", "incididunt", "do", "aute", "laborum", "deserunt", "sunt", "nisi", "labore" ], "friends": [ { "id": 0, "name": "Lana Taylor" }, { "id": 1, "name": "Jerri Dale" }, { "id": 2, "name": "Candy Adkins" }, { "id": 3, "name": "Hester Noel" }, { "id": 4, "name": "Hensley Moran" } ], "greeting": "Hello, Leblanc Cochran! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826edaebe10b809aeea", "index": 382, "guid": "56a81ebf-8417-4d73-926e-4cd8d05d8f8a", "isActive": true, "balance": "$2,508.18", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "green", "name": "Patrica Byers", "gender": "female", "company": "ENTROPIX", "email": "patricabyers@entropix.com", "phone": "+1 (817) 450-2540", "address": "846 Interborough Parkway, Saticoy, Ohio, 6503", "about": "Commodo sit aute exercitation duis do mollit occaecat ullamco sunt do occaecat. Mollit officia dolore esse quis id dolor tempor excepteur aliqua dolore. Proident in amet id elit incididunt officia sit eiusmod ipsum anim veniam nulla sit mollit. Excepteur ipsum dolor duis velit.\r\n", "registered": "2014-10-11T02:06:51 -02:00", "latitude": -36.615199, "longitude": -11.654342, "tags": [ "velit", "labore", "do", "ipsum", "cupidatat", "sunt", "magna", "ipsum", "aliquip", "do" ], "friends": [ { "id": 0, "name": "Lauren Houston" }, { "id": 1, "name": "Vaughn Lindsey" }, { "id": 2, "name": "Johanna Dyer" }, { "id": 3, "name": "Rowe Shields" }, { "id": 4, "name": "Hodges Lancaster" } ], "greeting": "Hello, Patrica Byers! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261b43be4bff393059", "index": 383, "guid": "632cfbcc-30cc-4a4f-a8c4-d06b46b255ba", "isActive": true, "balance": "$3,299.69", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Shaffer Harrison", "gender": "male", "company": "SONIQUE", "email": "shafferharrison@sonique.com", "phone": "+1 (982) 446-3345", "address": "628 Howard Avenue, Genoa, Arizona, 9175", "about": "Tempor elit ex quis aliqua qui elit consectetur velit eu voluptate eiusmod aliqua est aute. Laborum laborum adipisicing in enim fugiat occaecat sit. Cillum pariatur id esse ex magna mollit. Ullamco labore eiusmod ut culpa commodo pariatur cupidatat.\r\n", "registered": "2016-08-17T09:52:39 -02:00", "latitude": 86.945429, "longitude": -160.480632, "tags": [ "elit", "aliquip", "nostrud", "elit", "amet", "laboris", "consectetur", "ex", "dolore", "labore" ], "friends": [ { "id": 0, "name": "Perez Sosa" }, { "id": 1, "name": "Gilmore Thompson" }, { "id": 2, "name": "Winnie Kidd" }, { "id": 3, "name": "Amalia Joyner" }, { "id": 4, "name": "Benita Ochoa" } ], "greeting": "Hello, Shaffer Harrison! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482671aa737b14357714", "index": 384, "guid": "902788c8-b3d9-451a-b4a7-b2077dbd34f4", "isActive": true, "balance": "$1,824.77", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Jeanette Vang", "gender": "female", "company": "BLEENDOT", "email": "jeanettevang@bleendot.com", "phone": "+1 (804) 556-2256", "address": "528 Schenck Street, Lorraine, Montana, 1901", "about": "Ut aute id ipsum consectetur veniam minim. Cupidatat exercitation labore Lorem officia. Amet sit in cupidatat commodo laborum commodo nostrud cillum occaecat cillum. Ex eiusmod magna tempor officia elit voluptate exercitation commodo culpa. Nostrud dolore occaecat commodo do adipisicing quis proident cupidatat dolor non aute cupidatat.\r\n", "registered": "2015-01-21T03:32:48 -01:00", "latitude": -21.272663, "longitude": 165.181456, "tags": [ "laborum", "nulla", "sit", "qui", "cillum", "in", "nulla", "occaecat", "minim", "do" ], "friends": [ { "id": 0, "name": "Shannon Pate" }, { "id": 1, "name": "Janine Webb" }, { "id": 2, "name": "Michael Mcneil" }, { "id": 3, "name": "Levy Glenn" }, { "id": 4, "name": "Catherine Hyde" } ], "greeting": "Hello, Jeanette Vang! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826ae48d6785d0bb001", "index": 385, "guid": "a0b9c8fa-053a-463f-b796-09dbcc8819ed", "isActive": true, "balance": "$2,829.22", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "blue", "name": "Woods Hurley", "gender": "male", "company": "SCENTY", "email": "woodshurley@scenty.com", "phone": "+1 (972) 435-2880", "address": "506 Provost Street, Blodgett, Texas, 8521", "about": "Est veniam irure dolore aliquip ex. Dolore minim sunt eu voluptate aliqua. Enim elit cupidatat cupidatat laborum fugiat. Magna Lorem ipsum occaecat veniam aute velit veniam ad deserunt id minim magna Lorem enim.\r\n", "registered": "2016-06-17T03:01:29 -02:00", "latitude": -34.475183, "longitude": -74.887983, "tags": [ "non", "ullamco", "id", "cupidatat", "nulla", "ut", "cillum", "eiusmod", "ullamco", "duis" ], "friends": [ { "id": 0, "name": "Keri Bartlett" }, { "id": 1, "name": "Estella Boyd" }, { "id": 2, "name": "Meagan Kent" }, { "id": 3, "name": "Carr Gillespie" }, { "id": 4, "name": "Susanne Stafford" } ], "greeting": "Hello, Woods Hurley! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48260efee6a1ee287bfc", "index": 386, "guid": "10400680-3e1b-47f2-bd59-41adab20531e", "isActive": false, "balance": "$1,304.28", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Lott Arnold", "gender": "male", "company": "NIMON", "email": "lottarnold@nimon.com", "phone": "+1 (851) 450-3259", "address": "105 Green Street, Coldiron, Washington, 4591", "about": "Laboris aute laboris eiusmod Lorem esse est ut. Mollit ullamco reprehenderit cillum laboris proident incididunt nulla minim consectetur labore adipisicing qui in laborum. Anim qui velit Lorem nulla nulla enim ad minim consectetur. Reprehenderit ullamco do proident commodo et sunt do dolore eu duis laborum. Aliqua amet nulla laborum eu irure ipsum quis aute dolore consequat irure aute.\r\n", "registered": "2017-06-04T01:25:52 -02:00", "latitude": -75.899171, "longitude": 3.786903, "tags": [ "eu", "sint", "duis", "sint", "commodo", "dolor", "fugiat", "irure", "velit", "ad" ], "friends": [ { "id": 0, "name": "Kathie Ballard" }, { "id": 1, "name": "Pierce Sweeney" }, { "id": 2, "name": "Lawanda Wong" }, { "id": 3, "name": "Darcy Delacruz" }, { "id": 4, "name": "Aguilar Singleton" } ], "greeting": "Hello, Lott Arnold! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48262c04cefe24ffe786", "index": 387, "guid": "1798cb77-1e5a-48c9-ac3c-94c2f6cdf4d4", "isActive": true, "balance": "$3,129.35", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Miller Mccall", "gender": "male", "company": "RADIANTIX", "email": "millermccall@radiantix.com", "phone": "+1 (810) 512-3415", "address": "965 Varanda Place, Defiance, Wyoming, 4814", "about": "Excepteur pariatur incididunt commodo ex reprehenderit pariatur incididunt consectetur ea excepteur culpa non nostrud est. Qui eiusmod sit occaecat cupidatat aliquip cupidatat consequat ipsum ipsum in irure eu. Ut cillum nostrud culpa nostrud excepteur ea sit deserunt. Do ea ad deserunt ut in reprehenderit laborum tempor nulla.\r\n", "registered": "2017-04-08T11:27:35 -02:00", "latitude": 12.577918, "longitude": 174.593922, "tags": [ "id", "quis", "ad", "eu", "consectetur", "labore", "incididunt", "eu", "nisi", "et" ], "friends": [ { "id": 0, "name": "Jo Charles" }, { "id": 1, "name": "Cummings Wilcox" }, { "id": 2, "name": "Robles Dorsey" }, { "id": 3, "name": "Jody Morgan" }, { "id": 4, "name": "Ramsey Gay" } ], "greeting": "Hello, Miller Mccall! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826d2ab410ddc0b8d94", "index": 388, "guid": "0ad450f5-3bfb-41de-94f6-bc68a5f0e8f3", "isActive": false, "balance": "$3,001.50", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Silva Odonnell", "gender": "male", "company": "MAROPTIC", "email": "silvaodonnell@maroptic.com", "phone": "+1 (957) 598-2050", "address": "374 Post Court, Conway, Indiana, 6559", "about": "Reprehenderit commodo occaecat aute incididunt mollit excepteur sint nisi nisi esse do eiusmod nisi. Deserunt dolor aliqua in dolore est ea mollit. Voluptate ea exercitation quis commodo eu.\r\n", "registered": "2016-08-11T04:35:18 -02:00", "latitude": 26.791006, "longitude": 134.589252, "tags": [ "labore", "aute", "qui", "consectetur", "commodo", "voluptate", "pariatur", "eu", "consectetur", "reprehenderit" ], "friends": [ { "id": 0, "name": "Mckenzie Lawson" }, { "id": 1, "name": "Holden Massey" }, { "id": 2, "name": "Brandy Holcomb" }, { "id": 3, "name": "Boyd Brooks" }, { "id": 4, "name": "Emily Hendrix" } ], "greeting": "Hello, Silva Odonnell! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482611b2d64bda15fb73", "index": 389, "guid": "3483c00c-fca8-456c-bfd0-014780fa4d83", "isActive": true, "balance": "$1,878.06", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Little Barnes", "gender": "male", "company": "KROG", "email": "littlebarnes@krog.com", "phone": "+1 (905) 573-2180", "address": "269 Hill Street, Orovada, Alabama, 5207", "about": "Ea officia eiusmod veniam occaecat fugiat ex eiusmod amet veniam enim eiusmod tempor. Do proident magna nisi dolore eiusmod. Anim amet voluptate pariatur laboris mollit nostrud excepteur sunt amet voluptate ad officia duis.\r\n", "registered": "2015-03-10T09:25:39 -01:00", "latitude": 64.853821, "longitude": 105.790905, "tags": [ "adipisicing", "dolore", "aute", "mollit", "id", "fugiat", "in", "Lorem", "quis", "voluptate" ], "friends": [ { "id": 0, "name": "Terra Cortez" }, { "id": 1, "name": "Livingston Kelly" }, { "id": 2, "name": "Ashley Shaffer" }, { "id": 3, "name": "Natalie Walters" }, { "id": 4, "name": "Ware English" } ], "greeting": "Hello, Little Barnes! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826bd912c1b464bbded", "index": 390, "guid": "d0f4f63a-45d1-4bb4-8aa9-23f398c0f0c6", "isActive": true, "balance": "$3,178.73", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Middleton Osborne", "gender": "male", "company": "AQUASURE", "email": "middletonosborne@aquasure.com", "phone": "+1 (854) 524-2840", "address": "200 Madeline Court, Breinigsville, Virginia, 7464", "about": "Labore eu sit ad ea. Do irure tempor deserunt in aliqua irure officia. Deserunt irure excepteur velit officia aute proident laboris. Sunt duis dolor ut dolore amet. Proident reprehenderit sunt excepteur ex excepteur aliquip cupidatat. Id aute aliqua nisi reprehenderit nisi commodo ex consectetur.\r\n", "registered": "2015-10-12T08:12:51 -02:00", "latitude": -78.866104, "longitude": -97.351506, "tags": [ "Lorem", "mollit", "aliquip", "enim", "nostrud", "nisi", "incididunt", "qui", "proident", "minim" ], "friends": [ { "id": 0, "name": "Alexandra Schultz" }, { "id": 1, "name": "Hendrix Sullivan" }, { "id": 2, "name": "Greene Gomez" }, { "id": 3, "name": "Stein Maxwell" }, { "id": 4, "name": "Malinda Cash" } ], "greeting": "Hello, Middleton Osborne! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826dedf887e8b1ddc16", "index": 391, "guid": "9c360f48-9398-49f6-b424-2d098b767292", "isActive": true, "balance": "$3,430.13", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "blue", "name": "Thompson Rich", "gender": "male", "company": "SUPPORTAL", "email": "thompsonrich@supportal.com", "phone": "+1 (866) 597-3537", "address": "707 Ditmas Avenue, Beaverdale, New Mexico, 3625", "about": "Esse in laborum ut veniam qui dolore occaecat ullamco excepteur consectetur. In non occaecat aliqua cillum ut tempor cillum sit et culpa eu consequat velit. Enim elit pariatur ullamco do exercitation aliquip consectetur et laboris.\r\n", "registered": "2016-06-11T10:51:10 -02:00", "latitude": 0.776671, "longitude": 132.515332, "tags": [ "exercitation", "cupidatat", "Lorem", "aliquip", "eu", "est", "laborum", "cupidatat", "ea", "sit" ], "friends": [ { "id": 0, "name": "Gayle Gibbs" }, { "id": 1, "name": "Geraldine Stephenson" }, { "id": 2, "name": "Lidia Hopkins" }, { "id": 3, "name": "Isabelle Strickland" }, { "id": 4, "name": "Henrietta Lee" } ], "greeting": "Hello, Thompson Rich! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482646c684af07ac2a43", "index": 392, "guid": "9d3aa8e5-055e-4205-835e-5e6f70469ff6", "isActive": false, "balance": "$2,223.44", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "brown", "name": "Annette Meyers", "gender": "female", "company": "SYNTAC", "email": "annettemeyers@syntac.com", "phone": "+1 (852) 519-3632", "address": "385 Rutledge Street, Whipholt, Hawaii, 7591", "about": "Enim duis enim in id ullamco. Nisi adipisicing laboris eiusmod est cillum aliqua tempor laboris commodo non tempor aliquip. Esse voluptate elit nostrud ea reprehenderit reprehenderit exercitation. Elit cillum do id mollit. Nulla ut Lorem veniam esse ad ipsum esse dolore veniam.\r\n", "registered": "2014-09-10T05:10:16 -02:00", "latitude": -2.91429, "longitude": 65.699846, "tags": [ "irure", "velit", "id", "ullamco", "consequat", "cillum", "ullamco", "aliqua", "sint", "ea" ], "friends": [ { "id": 0, "name": "Sonya Casey" }, { "id": 1, "name": "Warren Sanchez" }, { "id": 2, "name": "Christine Moreno" }, { "id": 3, "name": "Woodward Schwartz" }, { "id": 4, "name": "Wall Munoz" } ], "greeting": "Hello, Annette Meyers! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826913435d0b2384cfa", "index": 393, "guid": "a1a3d5a5-717b-4cb0-b834-436eab81eec6", "isActive": false, "balance": "$3,176.73", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Sofia Terry", "gender": "female", "company": "RECRISYS", "email": "sofiaterry@recrisys.com", "phone": "+1 (992) 574-2638", "address": "369 Love Lane, Bath, Nebraska, 9837", "about": "Pariatur consequat ut incididunt nulla tempor culpa. Esse non esse ex ad eiusmod elit duis non voluptate eiusmod dolore officia est. Officia exercitation aliquip et non excepteur amet dolore nisi eu pariatur. Nisi ad cupidatat exercitation nulla nulla magna cupidatat amet eiusmod in. Minim incididunt pariatur laborum anim nisi.\r\n", "registered": "2017-03-01T05:54:45 -01:00", "latitude": 29.698203, "longitude": -25.817259, "tags": [ "incididunt", "officia", "labore", "proident", "aute", "id", "amet", "irure", "tempor", "enim" ], "friends": [ { "id": 0, "name": "Pickett Thornton" }, { "id": 1, "name": "Whitley Collins" }, { "id": 2, "name": "Pamela Welch" }, { "id": 3, "name": "Angeline Fuentes" }, { "id": 4, "name": "Lorrie Carlson" } ], "greeting": "Hello, Sofia Terry! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826bce8af0248e295dd", "index": 394, "guid": "e9ce0402-7000-40f9-866e-6063af0c0bd5", "isActive": false, "balance": "$2,110.58", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Griffin Hawkins", "gender": "male", "company": "ECLIPSENT", "email": "griffinhawkins@eclipsent.com", "phone": "+1 (840) 430-2694", "address": "326 Hooper Street, Lindisfarne, New York, 7660", "about": "Dolor mollit eu minim mollit dolor ad tempor do occaecat mollit veniam et qui. Quis irure incididunt ullamco laborum nisi duis voluptate sint nulla. Ullamco minim fugiat proident quis velit. Ea officia enim ea culpa mollit ullamco tempor sint sunt ut incididunt quis minim eu. Irure laborum sit proident officia incididunt labore occaecat consectetur mollit consequat ut.\r\n", "registered": "2016-03-06T07:13:42 -01:00", "latitude": 29.55541, "longitude": 80.957285, "tags": [ "ad", "adipisicing", "magna", "cupidatat", "tempor", "pariatur", "amet", "pariatur", "est", "nostrud" ], "friends": [ { "id": 0, "name": "Hays Brown" }, { "id": 1, "name": "Dianne Holt" }, { "id": 2, "name": "Leticia Moon" }, { "id": 3, "name": "Jenny Hull" }, { "id": 4, "name": "Tanya Holder" } ], "greeting": "Hello, Griffin Hawkins! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826a437c7c33f9c3a3b", "index": 395, "guid": "f542bde1-f26f-4ef3-8ef2-01ea03e53b7b", "isActive": true, "balance": "$1,078.30", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Maynard Burns", "gender": "male", "company": "BOLAX", "email": "maynardburns@bolax.com", "phone": "+1 (841) 466-3045", "address": "581 Rodney Street, Clinton, Marshall Islands, 8939", "about": "Officia officia fugiat voluptate proident excepteur magna sunt. Consectetur Lorem cillum aliquip ipsum deserunt pariatur commodo excepteur. Incididunt labore proident ex sit voluptate laboris consequat exercitation eiusmod dolore ipsum commodo. Ex dolor exercitation cillum incididunt ullamco mollit aute amet ullamco. Officia sit ad consectetur pariatur. Aute dolor veniam elit consequat amet sint excepteur cupidatat consequat minim consequat officia proident.\r\n", "registered": "2016-09-10T01:49:05 -02:00", "latitude": 88.396107, "longitude": -72.750263, "tags": [ "Lorem", "fugiat", "exercitation", "magna", "labore", "amet", "commodo", "commodo", "et", "deserunt" ], "friends": [ { "id": 0, "name": "Preston Porter" }, { "id": 1, "name": "Pacheco Hale" }, { "id": 2, "name": "Velma Atkinson" }, { "id": 3, "name": "Paul Jones" }, { "id": 4, "name": "Newman Melendez" } ], "greeting": "Hello, Maynard Burns! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c978251d81a04598", "index": 396, "guid": "da7db1ae-9ce7-4254-ae99-e8344ffdd993", "isActive": true, "balance": "$2,628.35", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "blue", "name": "Dale Boyle", "gender": "male", "company": "UTARA", "email": "daleboyle@utara.com", "phone": "+1 (895) 418-2556", "address": "641 Elm Avenue, Johnsonburg, Oregon, 3310", "about": "Fugiat adipisicing nostrud cillum exercitation exercitation duis fugiat dolor sint velit labore labore tempor sit. Non dolor sit fugiat fugiat deserunt aute cupidatat proident. Adipisicing aliqua sunt incididunt tempor ea cillum esse irure aliquip excepteur adipisicing. Eu anim adipisicing aliqua fugiat ea ullamco tempor reprehenderit elit anim nulla. Ullamco exercitation magna Lorem tempor nisi.\r\n", "registered": "2016-04-27T04:33:58 -02:00", "latitude": -45.005063, "longitude": 84.838893, "tags": [ "excepteur", "est", "pariatur", "dolore", "incididunt", "dolor", "proident", "laborum", "veniam", "fugiat" ], "friends": [ { "id": 0, "name": "Guthrie Padilla" }, { "id": 1, "name": "Fitzpatrick Travis" }, { "id": 2, "name": "Imelda Malone" }, { "id": 3, "name": "Cotton Mccray" }, { "id": 4, "name": "Rivas Whitney" } ], "greeting": "Hello, Dale Boyle! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826f9714d206b4834c3", "index": 397, "guid": "964593b7-ce3f-4295-9b03-16743d8a7e5f", "isActive": false, "balance": "$1,096.33", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Jackson Ward", "gender": "male", "company": "EMPIRICA", "email": "jacksonward@empirica.com", "phone": "+1 (828) 570-3972", "address": "608 Trucklemans Lane, Cleary, Tennessee, 6523", "about": "Reprehenderit incididunt anim magna exercitation aliquip. Officia tempor anim aliqua sit amet fugiat ullamco quis commodo. Irure minim eu laboris excepteur.\r\n", "registered": "2015-04-14T07:05:46 -02:00", "latitude": 50.280837, "longitude": 20.329378, "tags": [ "sint", "deserunt", "sit", "consectetur", "nulla", "id", "Lorem", "labore", "minim", "ipsum" ], "friends": [ { "id": 0, "name": "Aguirre Nolan" }, { "id": 1, "name": "Dodson Burnett" }, { "id": 2, "name": "Ashley Poole" }, { "id": 3, "name": "Louise Calderon" }, { "id": 4, "name": "Perkins Chapman" } ], "greeting": "Hello, Jackson Ward! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482659f8300e3fd49975", "index": 398, "guid": "007f4f90-4e8b-4996-8f00-3a53dde1350d", "isActive": false, "balance": "$2,427.88", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Knapp Russo", "gender": "male", "company": "AQUOAVO", "email": "knapprusso@aquoavo.com", "phone": "+1 (828) 539-3112", "address": "219 Brighton Court, Fairfield, Nevada, 6228", "about": "Amet ex laboris aliqua amet ullamco veniam ad. Cillum amet ullamco reprehenderit eiusmod laboris. Dolor ex ullamco consectetur tempor quis eiusmod in.\r\n", "registered": "2016-05-16T04:04:10 -02:00", "latitude": 71.385192, "longitude": -144.22222, "tags": [ "eiusmod", "sint", "culpa", "aute", "adipisicing", "minim", "et", "officia", "duis", "laboris" ], "friends": [ { "id": 0, "name": "Evelyn Baker" }, { "id": 1, "name": "Lang Hays" }, { "id": 2, "name": "Deann Madden" }, { "id": 3, "name": "Sandra Keller" }, { "id": 4, "name": "Kerr Kim" } ], "greeting": "Hello, Knapp Russo! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482647d70723de1db730", "index": 399, "guid": "414a50ae-b159-4f2e-ab7e-1d5c1cee4e48", "isActive": false, "balance": "$2,214.52", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "brown", "name": "Beth Hood", "gender": "female", "company": "ROCKYARD", "email": "bethhood@rockyard.com", "phone": "+1 (996) 428-3893", "address": "947 Porter Avenue, Hondah, Alaska, 773", "about": "Aliquip ex amet qui magna enim ut qui occaecat laboris. Id non irure sit ex. Excepteur sit fugiat non ipsum proident ullamco aliquip anim anim laborum dolore ut culpa. Exercitation est duis voluptate ullamco in. Occaecat do ipsum eiusmod anim sit. Reprehenderit esse aliqua fugiat mollit. Officia id consectetur reprehenderit aliqua ex laboris aliqua.\r\n", "registered": "2014-03-21T09:04:57 -01:00", "latitude": -47.659376, "longitude": -26.978249, "tags": [ "sit", "deserunt", "veniam", "velit", "velit", "incididunt", "do", "nostrud", "ullamco", "non" ], "friends": [ { "id": 0, "name": "Marks Patterson" }, { "id": 1, "name": "Gardner Patel" }, { "id": 2, "name": "Serrano Knapp" }, { "id": 3, "name": "Russell Sanford" }, { "id": 4, "name": "Pearlie Rodriquez" } ], "greeting": "Hello, Beth Hood! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ca2c5367ebe8fff4", "index": 400, "guid": "c1bfa605-1759-441a-99d0-083451ecc1fb", "isActive": true, "balance": "$1,314.22", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Sullivan Berger", "gender": "male", "company": "LUMBREX", "email": "sullivanberger@lumbrex.com", "phone": "+1 (841) 413-2727", "address": "780 Russell Street, Biehle, Illinois, 9055", "about": "Voluptate reprehenderit minim nostrud nisi aliquip et elit. Fugiat deserunt deserunt mollit mollit voluptate magna ad Lorem dolore ea officia ex velit. Dolore anim pariatur dolore voluptate amet ea in. Incididunt in ex fugiat enim irure nostrud excepteur veniam veniam id et aliqua occaecat ut.\r\n", "registered": "2015-07-24T01:35:59 -02:00", "latitude": -74.789459, "longitude": -18.719706, "tags": [ "esse", "eiusmod", "ex", "veniam", "dolor", "amet", "ut", "ipsum", "deserunt", "voluptate" ], "friends": [ { "id": 0, "name": "Jessie Snyder" }, { "id": 1, "name": "Mcmahon Kirby" }, { "id": 2, "name": "James Gray" }, { "id": 3, "name": "Maxine Jacobson" }, { "id": 4, "name": "Avery Patton" } ], "greeting": "Hello, Sullivan Berger! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48266b3802454771ba4b", "index": 401, "guid": "a5ef2b9e-47d7-4c3e-a003-181fe042e739", "isActive": true, "balance": "$2,302.96", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "green", "name": "Lyons Parks", "gender": "male", "company": "ZAGGLE", "email": "lyonsparks@zaggle.com", "phone": "+1 (928) 558-2077", "address": "867 Prescott Place, Springville, Oklahoma, 6652", "about": "Non et irure laboris veniam officia veniam elit irure mollit enim est aute. Sunt do labore incididunt est et duis reprehenderit nulla ex reprehenderit veniam nisi ut ut. Est nostrud amet officia quis aute laborum ea pariatur sit sunt excepteur eu ullamco nostrud.\r\n", "registered": "2016-03-24T02:41:40 -01:00", "latitude": 77.850985, "longitude": -136.794154, "tags": [ "velit", "nisi", "fugiat", "culpa", "amet", "sit", "nulla", "in", "aute", "officia" ], "friends": [ { "id": 0, "name": "Schwartz Howard" }, { "id": 1, "name": "Davis Black" }, { "id": 2, "name": "April Hardin" }, { "id": 3, "name": "Elsa Griffin" }, { "id": 4, "name": "Ola Lopez" } ], "greeting": "Hello, Lyons Parks! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f38ce21b5a8e2776", "index": 402, "guid": "eee61cb1-4f7f-4eb8-b35e-dcd46aafbebd", "isActive": true, "balance": "$1,037.15", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "green", "name": "Carmella Walls", "gender": "female", "company": "XIIX", "email": "carmellawalls@xiix.com", "phone": "+1 (813) 432-3296", "address": "472 Lombardy Street, Dawn, Delaware, 4809", "about": "Voluptate ut ea veniam quis enim aute. Minim proident incididunt aute pariatur reprehenderit adipisicing. Quis in ex mollit enim sunt excepteur.\r\n", "registered": "2016-04-27T01:30:43 -02:00", "latitude": 41.439649, "longitude": -155.403583, "tags": [ "sunt", "culpa", "cupidatat", "laboris", "dolor", "est", "laboris", "et", "aliquip", "ad" ], "friends": [ { "id": 0, "name": "Hutchinson Bernard" }, { "id": 1, "name": "Spencer Hooper" }, { "id": 2, "name": "Essie Maddox" }, { "id": 3, "name": "Fulton Mccoy" }, { "id": 4, "name": "Barnett Sparks" } ], "greeting": "Hello, Carmella Walls! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826e536c8b4171acec1", "index": 403, "guid": "02d35c8e-b39a-49c3-a671-a28b3bb77f42", "isActive": false, "balance": "$3,573.62", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "blue", "name": "Katrina Albert", "gender": "female", "company": "INTERGEEK", "email": "katrinaalbert@intergeek.com", "phone": "+1 (817) 532-3924", "address": "878 Highland Avenue, Umapine, Federated States Of Micronesia, 1202", "about": "Sunt duis nisi voluptate tempor. Reprehenderit sint pariatur labore ex mollit mollit mollit ipsum tempor. Laboris occaecat veniam magna esse enim consectetur. Voluptate pariatur amet consectetur cillum in irure ipsum proident nulla tempor enim. Aliqua proident non sit cupidatat amet ea elit est elit et esse do pariatur. Enim nisi velit ut mollit. Aliqua incididunt id enim nostrud sit nulla nostrud irure amet.\r\n", "registered": "2014-03-11T11:36:33 -01:00", "latitude": 1.275152, "longitude": 50.727087, "tags": [ "commodo", "velit", "eiusmod", "elit", "minim", "elit", "dolore", "reprehenderit", "id", "occaecat" ], "friends": [ { "id": 0, "name": "Bonita Mejia" }, { "id": 1, "name": "Hillary Riddle" }, { "id": 2, "name": "Shelby Dixon" }, { "id": 3, "name": "David Ortiz" }, { "id": 4, "name": "Diann Dunn" } ], "greeting": "Hello, Katrina Albert! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826961be60456df52d7", "index": 404, "guid": "dcdec6b9-60dd-4a38-8301-0d6c4b2a0f3b", "isActive": false, "balance": "$2,640.40", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "blue", "name": "Marquez Palmer", "gender": "male", "company": "ERSUM", "email": "marquezpalmer@ersum.com", "phone": "+1 (852) 596-2875", "address": "254 Ralph Avenue, Waumandee, Florida, 2264", "about": "Et amet nisi adipisicing culpa. Et consectetur proident sint incididunt labore dolor nisi quis quis officia ad dolore. Magna dolore ipsum laborum aute fugiat esse magna cillum. Excepteur pariatur proident non nostrud.\r\n", "registered": "2015-12-25T06:59:05 -01:00", "latitude": -62.917702, "longitude": 73.77409, "tags": [ "aliquip", "do", "nisi", "exercitation", "reprehenderit", "nisi", "occaecat", "elit", "est", "ea" ], "friends": [ { "id": 0, "name": "Whitfield Ayers" }, { "id": 1, "name": "Imogene Foster" }, { "id": 2, "name": "Burns Merritt" }, { "id": 3, "name": "Burch Allison" }, { "id": 4, "name": "Courtney Clemons" } ], "greeting": "Hello, Marquez Palmer! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48267ce55f471a85b256", "index": 405, "guid": "e07a043f-17b3-4dfd-b703-a6527b55dcba", "isActive": false, "balance": "$3,088.31", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "blue", "name": "Roberta Mcdonald", "gender": "female", "company": "GEEKFARM", "email": "robertamcdonald@geekfarm.com", "phone": "+1 (968) 590-2022", "address": "358 Poplar Street, Wintersburg, Massachusetts, 3357", "about": "Cillum ipsum ad ea voluptate dolor voluptate. Occaecat cupidatat magna commodo sit id consequat proident excepteur pariatur esse incididunt eiusmod et laboris. Labore aute ea pariatur esse exercitation.\r\n", "registered": "2015-08-05T10:36:17 -02:00", "latitude": -29.005786, "longitude": -122.635201, "tags": [ "ipsum", "consequat", "voluptate", "consequat", "ex", "elit", "proident", "ex", "tempor", "consectetur" ], "friends": [ { "id": 0, "name": "Lloyd Leon" }, { "id": 1, "name": "Elinor Owen" }, { "id": 2, "name": "Pansy Levy" }, { "id": 3, "name": "Liliana Cain" }, { "id": 4, "name": "Shepherd Vance" } ], "greeting": "Hello, Roberta Mcdonald! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482663530759e4488eb5", "index": 406, "guid": "366bf685-173b-4e23-aa07-7e060c1ea014", "isActive": false, "balance": "$3,276.89", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "green", "name": "Corinne Harvey", "gender": "female", "company": "MEDALERT", "email": "corinneharvey@medalert.com", "phone": "+1 (802) 551-3291", "address": "554 Commercial Street, Lopezo, Mississippi, 2730", "about": "Culpa pariatur ex aliquip Lorem non aliquip culpa laboris labore. Officia ea adipisicing nostrud minim voluptate anim est. Non cillum aliquip veniam voluptate. Officia sint aliquip quis labore ut elit do dolore est mollit. Aliqua anim irure proident magna quis culpa esse. Aliquip nulla proident esse do ipsum eiusmod eu. Ipsum non velit anim minim ad.\r\n", "registered": "2016-01-11T02:09:08 -01:00", "latitude": -6.817081, "longitude": 33.779625, "tags": [ "commodo", "deserunt", "et", "nisi", "magna", "sint", "est", "reprehenderit", "cupidatat", "elit" ], "friends": [ { "id": 0, "name": "Jaime Jackson" }, { "id": 1, "name": "Small Rivas" }, { "id": 2, "name": "Robyn Craft" }, { "id": 3, "name": "Waters Carver" }, { "id": 4, "name": "Talley Vasquez" } ], "greeting": "Hello, Corinne Harvey! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482682224c03022dbd46", "index": 407, "guid": "31ac72a4-5f5f-42de-90d5-bfa765091726", "isActive": false, "balance": "$1,688.36", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "brown", "name": "Andrews Pitts", "gender": "male", "company": "UPLINX", "email": "andrewspitts@uplinx.com", "phone": "+1 (968) 440-2172", "address": "168 Fulton Street, Vivian, Guam, 9392", "about": "Aute aliqua esse sunt qui. Labore commodo duis minim aliquip ipsum sint duis id tempor. Incididunt sunt qui elit cillum anim. Aute deserunt Lorem est culpa Lorem fugiat cillum qui est qui commodo exercitation. Qui magna nisi deserunt irure. Exercitation amet adipisicing est nisi ut nostrud exercitation laboris aliquip.\r\n", "registered": "2017-02-08T04:04:31 -01:00", "latitude": 22.347329, "longitude": 37.480019, "tags": [ "aliquip", "aute", "laboris", "sit", "nisi", "deserunt", "sit", "duis", "cupidatat", "cillum" ], "friends": [ { "id": 0, "name": "Owen Harmon" }, { "id": 1, "name": "Kirk Stone" }, { "id": 2, "name": "Karyn Mcdaniel" }, { "id": 3, "name": "Knight Mcmillan" }, { "id": 4, "name": "Magdalena Browning" } ], "greeting": "Hello, Andrews Pitts! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e28e218942e5e84f", "index": 408, "guid": "a1def0a6-94e1-4d7c-8e77-05ff55312fff", "isActive": true, "balance": "$1,879.44", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Gloria Harris", "gender": "female", "company": "TROPOLIS", "email": "gloriaharris@tropolis.com", "phone": "+1 (902) 491-2416", "address": "716 Bay Avenue, Suitland, Louisiana, 1609", "about": "Tempor magna voluptate pariatur consectetur deserunt consectetur excepteur esse pariatur excepteur ea non elit aliqua. Ad dolor mollit commodo fugiat magna. Amet in eiusmod id laborum culpa laboris officia Lorem proident exercitation in. Tempor esse commodo reprehenderit labore ut ipsum.\r\n", "registered": "2014-11-25T04:25:24 -01:00", "latitude": 62.461509, "longitude": -31.875494, "tags": [ "minim", "dolore", "aute", "nostrud", "deserunt", "consequat", "consectetur", "ut", "reprehenderit", "sint" ], "friends": [ { "id": 0, "name": "Rhodes Perez" }, { "id": 1, "name": "Adrienne Oconnor" }, { "id": 2, "name": "Adriana Cooley" }, { "id": 3, "name": "Rosa Clarke" }, { "id": 4, "name": "Jasmine Castro" } ], "greeting": "Hello, Gloria Harris! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482698f254fdc08751b3", "index": 409, "guid": "d3a6c9a6-33a1-4530-8653-8c605cd2529c", "isActive": true, "balance": "$3,841.42", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "brown", "name": "Frederick Diaz", "gender": "male", "company": "GEEKOL", "email": "frederickdiaz@geekol.com", "phone": "+1 (875) 434-3597", "address": "376 School Lane, Montura, South Dakota, 2879", "about": "Duis pariatur eiusmod culpa minim dolore. Deserunt reprehenderit laboris dolor amet consequat ad Lorem. Amet enim pariatur elit veniam et pariatur veniam id exercitation proident consequat excepteur.\r\n", "registered": "2016-01-15T12:00:56 -01:00", "latitude": 22.396991, "longitude": -61.96613, "tags": [ "exercitation", "sit", "ad", "velit", "eu", "ipsum", "sit", "fugiat", "culpa", "cupidatat" ], "friends": [ { "id": 0, "name": "Collins Garrison" }, { "id": 1, "name": "Verna Cantrell" }, { "id": 2, "name": "Salas Farrell" }, { "id": 3, "name": "Lowery Franco" }, { "id": 4, "name": "Lillie Hopper" } ], "greeting": "Hello, Frederick Diaz! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826f33b5bd22a4cfc69", "index": 410, "guid": "8e0e349c-be7b-4014-8449-a95a645ca3a0", "isActive": true, "balance": "$1,256.78", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "blue", "name": "James Dillon", "gender": "female", "company": "MARVANE", "email": "jamesdillon@marvane.com", "phone": "+1 (937) 422-2893", "address": "325 Evans Street, Cartwright, District Of Columbia, 358", "about": "Elit magna minim esse irure excepteur. Aliquip occaecat magna mollit velit sit id enim qui. Lorem cillum minim et nulla in officia occaecat aliqua. Dolore aute cupidatat eiusmod irure culpa mollit. Deserunt eiusmod anim exercitation adipisicing occaecat nisi aute velit.\r\n", "registered": "2017-08-28T07:14:57 -02:00", "latitude": -27.841939, "longitude": 24.121862, "tags": [ "dolor", "exercitation", "adipisicing", "est", "enim", "id", "culpa", "anim", "non", "incididunt" ], "friends": [ { "id": 0, "name": "Dominique York" }, { "id": 1, "name": "Cherry Rodriguez" }, { "id": 2, "name": "Stuart Larson" }, { "id": 3, "name": "Lucille Koch" }, { "id": 4, "name": "Mckinney Gregory" } ], "greeting": "Hello, James Dillon! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48268832eb6967e117e9", "index": 411, "guid": "ad833e8a-433e-48e8-874a-68697629b5a4", "isActive": true, "balance": "$2,345.17", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "blue", "name": "Penelope Salazar", "gender": "female", "company": "PLUTORQUE", "email": "penelopesalazar@plutorque.com", "phone": "+1 (949) 494-2882", "address": "151 Perry Terrace, Belvoir, Puerto Rico, 9961", "about": "Qui proident incididunt in nisi mollit aliqua quis. Mollit aute ex consectetur adipisicing ea veniam proident anim ad sint. Cupidatat elit labore labore exercitation Lorem aute pariatur dolore. Elit consequat ad ipsum aliqua veniam amet est nulla et aliqua occaecat duis. Excepteur incididunt veniam aliquip sit id.\r\n", "registered": "2014-01-09T06:26:54 -01:00", "latitude": -80.610007, "longitude": 25.523495, "tags": [ "mollit", "ea", "dolore", "aute", "et", "adipisicing", "elit", "nostrud", "ea", "cillum" ], "friends": [ { "id": 0, "name": "Mable Becker" }, { "id": 1, "name": "Roberts Byrd" }, { "id": 2, "name": "Wiley Boone" }, { "id": 3, "name": "Coleman Barnett" }, { "id": 4, "name": "Petty Huff" } ], "greeting": "Hello, Penelope Salazar! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f0b688986c187599", "index": 412, "guid": "327cc4df-7bbe-44c6-9853-050360bd2bc2", "isActive": true, "balance": "$1,742.24", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "blue", "name": "Doyle Brady", "gender": "male", "company": "VIRVA", "email": "doylebrady@virva.com", "phone": "+1 (931) 574-2875", "address": "629 Polhemus Place, Garnet, Maine, 4930", "about": "Dolor labore minim pariatur duis in commodo amet ullamco. Sunt occaecat ea amet officia voluptate adipisicing ea elit ea irure exercitation. Est ad quis pariatur quis sint labore do pariatur. Laboris eu laboris velit amet. Aute nisi et consequat elit nisi. Esse fugiat eu ex ipsum officia non do voluptate elit incididunt officia est consectetur eiusmod. Reprehenderit nisi minim pariatur ut pariatur sit duis consectetur.\r\n", "registered": "2016-04-02T08:30:14 -02:00", "latitude": 72.488362, "longitude": -136.122077, "tags": [ "officia", "duis", "pariatur", "esse", "do", "officia", "nostrud", "veniam", "cupidatat", "minim" ], "friends": [ { "id": 0, "name": "Chase Hoover" }, { "id": 1, "name": "Valeria Clay" }, { "id": 2, "name": "Perry Chaney" }, { "id": 3, "name": "Marisa Larsen" }, { "id": 4, "name": "Dana Nicholson" } ], "greeting": "Hello, Doyle Brady! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48265eace15ac71ccd41", "index": 413, "guid": "7a9f4fcd-ec17-4d9a-962e-201ad909e90e", "isActive": true, "balance": "$2,305.86", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "green", "name": "Dolly Mcmahon", "gender": "female", "company": "NEBULEAN", "email": "dollymcmahon@nebulean.com", "phone": "+1 (953) 572-3693", "address": "316 Waldorf Court, Rowe, New Jersey, 2539", "about": "Commodo ipsum reprehenderit laboris consectetur deserunt pariatur irure nostrud dolore ipsum. Ex culpa excepteur ullamco nostrud mollit eiusmod. Mollit eiusmod tempor aliqua dolore irure Lorem. Officia eu tempor Lorem magna proident mollit incididunt mollit cillum proident dolor quis. Culpa elit pariatur nisi sunt aliqua esse eu voluptate deserunt minim. Incididunt aute enim dolor aliqua eiusmod Lorem ex magna ea pariatur exercitation irure qui.\r\n", "registered": "2016-09-10T09:04:26 -02:00", "latitude": -39.033453, "longitude": 88.91707, "tags": [ "non", "enim", "exercitation", "occaecat", "elit", "pariatur", "voluptate", "elit", "reprehenderit", "consectetur" ], "friends": [ { "id": 0, "name": "Graham Wilson" }, { "id": 1, "name": "Riley Galloway" }, { "id": 2, "name": "Blevins Everett" }, { "id": 3, "name": "Elva Meadows" }, { "id": 4, "name": "Louisa Hinton" } ], "greeting": "Hello, Dolly Mcmahon! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48269644536df389b710", "index": 414, "guid": "e4c588da-9215-4bc1-ad47-56e62aa4a49a", "isActive": true, "balance": "$3,197.80", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "blue", "name": "Hodge Sharpe", "gender": "male", "company": "KYAGURU", "email": "hodgesharpe@kyaguru.com", "phone": "+1 (876) 529-2146", "address": "662 McClancy Place, Selma, Michigan, 5160", "about": "Laborum Lorem eu proident cupidatat. Ut enim ad reprehenderit irure culpa anim. Quis duis minim ad enim enim est sint. Do non consequat veniam esse pariatur. Sint adipisicing esse ea commodo cillum esse magna exercitation laborum laborum proident cupidatat. Quis magna deserunt amet anim culpa consequat sint adipisicing fugiat nisi. Mollit velit pariatur Lorem aliqua ad laborum veniam commodo qui consequat.\r\n", "registered": "2016-06-06T04:12:40 -02:00", "latitude": -64.398955, "longitude": 109.424396, "tags": [ "cillum", "veniam", "adipisicing", "nulla", "in", "nisi", "dolore", "eu", "laboris", "sunt" ], "friends": [ { "id": 0, "name": "Kayla Buckner" }, { "id": 1, "name": "Tanner Morris" }, { "id": 2, "name": "Laurie Wilder" }, { "id": 3, "name": "Lottie Olsen" }, { "id": 4, "name": "Kerry Garner" } ], "greeting": "Hello, Hodge Sharpe! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826ff64d5de6628bad3", "index": 415, "guid": "c703c826-81a1-4a54-b5c0-3d88375eb21d", "isActive": false, "balance": "$2,640.70", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "green", "name": "Burnett Walker", "gender": "male", "company": "TALKOLA", "email": "burnettwalker@talkola.com", "phone": "+1 (824) 553-3444", "address": "204 Kane Place, Freeburn, Rhode Island, 3102", "about": "Exercitation occaecat sint ipsum in qui voluptate magna est amet aliqua enim non officia consectetur. Non nisi eu qui nostrud voluptate anim do nisi occaecat enim nulla sit qui. Adipisicing incididunt qui minim ipsum. Exercitation sunt commodo magna qui tempor consequat dolore eu sit magna. Anim occaecat et cillum ad in adipisicing.\r\n", "registered": "2015-08-17T08:01:04 -02:00", "latitude": 44.203274, "longitude": 165.764378, "tags": [ "magna", "do", "minim", "nulla", "occaecat", "veniam", "tempor", "duis", "excepteur", "amet" ], "friends": [ { "id": 0, "name": "Newton Neal" }, { "id": 1, "name": "Vickie Colon" }, { "id": 2, "name": "Sheree Mercer" }, { "id": 3, "name": "Sellers Hicks" }, { "id": 4, "name": "Cook Nguyen" } ], "greeting": "Hello, Burnett Walker! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48264d50ae4664b13bb4", "index": 416, "guid": "46f11754-93a0-4a88-96ae-25f7c1f261f8", "isActive": true, "balance": "$2,709.00", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "brown", "name": "Horton Bell", "gender": "male", "company": "GEEKWAGON", "email": "hortonbell@geekwagon.com", "phone": "+1 (886) 562-3696", "address": "453 Lexington Avenue, Henrietta, Kansas, 1841", "about": "Occaecat pariatur velit tempor cupidatat do. Ullamco deserunt et aute nostrud. Non ipsum quis et qui. Id officia officia laboris nulla et nostrud dolore in. Excepteur excepteur proident tempor Lorem minim nulla. Laborum officia eiusmod duis eu enim laboris.\r\n", "registered": "2015-09-17T05:15:42 -02:00", "latitude": -43.013955, "longitude": -160.668902, "tags": [ "voluptate", "magna", "ea", "qui", "dolor", "cupidatat", "sint", "in", "reprehenderit", "cillum" ], "friends": [ { "id": 0, "name": "Jayne Leonard" }, { "id": 1, "name": "Humphrey Hart" }, { "id": 2, "name": "Sherrie Carr" }, { "id": 3, "name": "Eloise Mcgee" }, { "id": 4, "name": "Dee Smith" } ], "greeting": "Hello, Horton Bell! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482664ed14d40436eff8", "index": 417, "guid": "7b77ae06-a3ec-4a7f-85f7-ffab73725120", "isActive": false, "balance": "$3,258.40", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "brown", "name": "Ingram Riggs", "gender": "male", "company": "GEEKOLA", "email": "ingramriggs@geekola.com", "phone": "+1 (806) 464-2609", "address": "205 Albee Square, Dubois, West Virginia, 232", "about": "Culpa laboris ex fugiat sit sint est fugiat pariatur laboris ea excepteur. Ipsum Lorem amet et proident esse laborum officia in. Nostrud aliqua dolore in veniam sint culpa. Commodo consectetur labore aute aliquip amet aliquip irure deserunt reprehenderit tempor labore culpa. Lorem dolore consequat eu deserunt elit. Nisi esse id incididunt occaecat.\r\n", "registered": "2015-11-25T05:27:45 -01:00", "latitude": 54.281408, "longitude": -13.01947, "tags": [ "sit", "ullamco", "ut", "nulla", "consectetur", "consectetur", "dolor", "sunt", "do", "magna" ], "friends": [ { "id": 0, "name": "Nolan Oneil" }, { "id": 1, "name": "Georgina Cobb" }, { "id": 2, "name": "Wendy Velez" }, { "id": 3, "name": "Franks Wiley" }, { "id": 4, "name": "Adele Doyle" } ], "greeting": "Hello, Ingram Riggs! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826053621447d8acf28", "index": 418, "guid": "69bf8a32-57bb-4f58-83f3-cf771c437b47", "isActive": true, "balance": "$3,190.91", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Hendricks Rogers", "gender": "male", "company": "TETAK", "email": "hendricksrogers@tetak.com", "phone": "+1 (971) 471-3140", "address": "984 Ridgecrest Terrace, Grill, American Samoa, 6601", "about": "Lorem nulla nostrud do ullamco ea mollit irure non deserunt nisi. Eu cillum eiusmod incididunt laboris reprehenderit dolor aliquip commodo elit excepteur aliquip ad aliquip velit. Velit commodo officia eiusmod eu non officia eiusmod exercitation cupidatat. Deserunt do laborum consectetur mollit ullamco eu incididunt ea tempor amet sint. Quis nulla in cupidatat et nostrud adipisicing. Qui minim qui id veniam consequat labore. Esse laboris quis voluptate laboris veniam.\r\n", "registered": "2017-11-01T08:05:20 -01:00", "latitude": 77.494942, "longitude": -153.953697, "tags": [ "elit", "ex", "exercitation", "mollit", "velit", "enim", "sunt", "voluptate", "sit", "nostrud" ], "friends": [ { "id": 0, "name": "Barron Lamb" }, { "id": 1, "name": "Jodie Juarez" }, { "id": 2, "name": "Mendez Duran" }, { "id": 3, "name": "Cooke Rowe" }, { "id": 4, "name": "Conley Roberson" } ], "greeting": "Hello, Hendricks Rogers! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826777944109303bc65", "index": 419, "guid": "e70a514c-16ec-4aab-a9d1-456d391e0a56", "isActive": false, "balance": "$2,490.00", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "blue", "name": "Kelley Beach", "gender": "male", "company": "INVENTURE", "email": "kelleybeach@inventure.com", "phone": "+1 (807) 595-3535", "address": "616 Kermit Place, Bonanza, Maryland, 7654", "about": "Excepteur exercitation mollit in ea labore culpa excepteur cillum fugiat. Consequat ut irure esse aliqua. Dolor nostrud adipisicing esse ullamco aliquip. Exercitation Lorem amet aliqua officia est.\r\n", "registered": "2015-10-30T03:19:09 -01:00", "latitude": -73.059233, "longitude": 50.484882, "tags": [ "minim", "cupidatat", "fugiat", "mollit", "nostrud", "irure", "ipsum", "in", "veniam", "non" ], "friends": [ { "id": 0, "name": "England Schneider" }, { "id": 1, "name": "Townsend Sharp" }, { "id": 2, "name": "Dalton Rocha" }, { "id": 3, "name": "Alford Key" }, { "id": 4, "name": "Stout Barr" } ], "greeting": "Hello, Kelley Beach! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48264ce50f7eb3bcc317", "index": 420, "guid": "b0ce1d88-35fa-406c-9a54-65516fe5a07c", "isActive": true, "balance": "$2,021.82", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "blue", "name": "Charles Valdez", "gender": "male", "company": "ELEMANTRA", "email": "charlesvaldez@elemantra.com", "phone": "+1 (800) 585-3613", "address": "330 Humboldt Street, Blue, California, 1157", "about": "Ipsum dolore commodo consectetur occaecat eu commodo quis id exercitation deserunt. Qui nostrud ex dolor ipsum labore exercitation veniam esse ad irure pariatur. Fugiat elit aliqua pariatur ullamco aute dolor. Qui consequat aute nisi adipisicing culpa velit deserunt incididunt officia exercitation ea pariatur qui enim. Proident cupidatat eiusmod cupidatat veniam occaecat. Eiusmod sint cupidatat velit voluptate excepteur est.\r\n", "registered": "2017-11-21T11:55:47 -01:00", "latitude": 49.192919, "longitude": -36.450213, "tags": [ "enim", "anim", "consectetur", "ullamco", "nostrud", "sit", "cillum", "sint", "ex", "eu" ], "friends": [ { "id": 0, "name": "Stanley Kennedy" }, { "id": 1, "name": "John Marsh" }, { "id": 2, "name": "Mcguire Talley" }, { "id": 3, "name": "Key King" }, { "id": 4, "name": "Herminia Manning" } ], "greeting": "Hello, Charles Valdez! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48269a22812696615afd", "index": 421, "guid": "49869339-661a-442e-b0e7-ac4d833ead50", "isActive": true, "balance": "$1,200.04", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "brown", "name": "Clemons Pittman", "gender": "male", "company": "NAXDIS", "email": "clemonspittman@naxdis.com", "phone": "+1 (839) 534-2848", "address": "648 Jaffray Street, Newcastle, Utah, 3040", "about": "Eu est est adipisicing magna enim voluptate veniam Lorem. Laborum cupidatat enim est tempor ex ut quis. Ea est incididunt exercitation enim. In excepteur elit qui sit fugiat mollit labore tempor est aliqua esse mollit pariatur ad. Dolor cillum veniam in nostrud incididunt ipsum ut duis magna incididunt. Ex adipisicing officia amet aute enim sunt occaecat ullamco commodo consequat sunt. Laboris eiusmod labore qui aliqua sint esse est amet aute duis veniam duis laboris.\r\n", "registered": "2016-10-27T03:56:08 -02:00", "latitude": -11.331594, "longitude": -178.909147, "tags": [ "mollit", "fugiat", "ut", "magna", "exercitation", "sint", "veniam", "eu", "duis", "nulla" ], "friends": [ { "id": 0, "name": "Best Bradford" }, { "id": 1, "name": "Oconnor Kane" }, { "id": 2, "name": "Estes Mendoza" }, { "id": 3, "name": "Gwen Hall" }, { "id": 4, "name": "Barrera Le" } ], "greeting": "Hello, Clemons Pittman! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48265fced3b12bf9626c", "index": 422, "guid": "1a2ba64f-416d-489a-8475-894d3622cf90", "isActive": true, "balance": "$1,573.25", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Melton Anthony", "gender": "male", "company": "SKINSERVE", "email": "meltonanthony@skinserve.com", "phone": "+1 (965) 545-3934", "address": "751 Stillwell Place, Sanborn, Iowa, 4403", "about": "Adipisicing veniam eiusmod irure magna cillum amet ipsum in enim. Incididunt dolor voluptate sint ea est fugiat dolore dolor sint mollit aliquip aliquip. Esse aliquip aliquip deserunt nisi consectetur. Nostrud ea fugiat id magna aliquip aliquip deserunt eiusmod pariatur non ullamco occaecat.\r\n", "registered": "2016-12-07T12:48:35 -01:00", "latitude": 78.121477, "longitude": -0.785598, "tags": [ "laboris", "ex", "dolor", "proident", "excepteur", "do", "incididunt", "adipisicing", "dolore", "dolore" ], "friends": [ { "id": 0, "name": "Henry French" }, { "id": 1, "name": "Lynette Goodman" }, { "id": 2, "name": "Solomon Ashley" }, { "id": 3, "name": "Austin Skinner" }, { "id": 4, "name": "Glenna Woodward" } ], "greeting": "Hello, Melton Anthony! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826941b33cc6c3eb4c6", "index": 423, "guid": "21a2f7d7-dd25-4961-a614-8f6c3de00c5c", "isActive": true, "balance": "$3,705.80", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "blue", "name": "Heath Barry", "gender": "male", "company": "PROVIDCO", "email": "heathbarry@providco.com", "phone": "+1 (825) 414-2466", "address": "658 Turnbull Avenue, Yardville, North Dakota, 8078", "about": "Eiusmod id officia aliquip reprehenderit tempor ut. Pariatur sit Lorem labore in cillum do sit anim incididunt ut aute eiusmod irure. Reprehenderit est qui consectetur velit nisi consequat ad commodo eu dolor incididunt. Lorem commodo sint fugiat nulla culpa nostrud. Exercitation voluptate culpa consequat ipsum ullamco commodo officia ad magna in est cupidatat nisi. Ex Lorem laborum pariatur pariatur quis cillum. Ut dolor officia aliqua sit aliquip excepteur non amet elit.\r\n", "registered": "2016-07-22T11:42:05 -02:00", "latitude": 56.038031, "longitude": -117.349692, "tags": [ "ut", "nulla", "ullamco", "laboris", "eu", "reprehenderit", "qui", "ipsum", "occaecat", "duis" ], "friends": [ { "id": 0, "name": "Laura Mack" }, { "id": 1, "name": "Casey Woods" }, { "id": 2, "name": "Salazar Bishop" }, { "id": 3, "name": "Curtis Sanders" }, { "id": 4, "name": "Sharpe Mcpherson" } ], "greeting": "Hello, Heath Barry! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826fcf023de978244cb", "index": 424, "guid": "37aa5b37-cd78-4f6e-bd09-5831005d638d", "isActive": false, "balance": "$1,972.95", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "brown", "name": "Liza Oneill", "gender": "female", "company": "SEALOUD", "email": "lizaoneill@sealoud.com", "phone": "+1 (801) 514-3401", "address": "743 Bartlett Place, Coloma, Kentucky, 8292", "about": "Proident voluptate culpa elit et consequat. Magna nostrud irure occaecat labore. Magna occaecat excepteur in deserunt qui laboris. Amet et voluptate velit officia amet voluptate ullamco mollit officia labore exercitation ex voluptate. Aliquip elit voluptate pariatur sint minim non occaecat sit mollit nisi duis exercitation.\r\n", "registered": "2014-08-25T08:20:27 -02:00", "latitude": 35.072093, "longitude": -172.716558, "tags": [ "sint", "consequat", "proident", "nostrud", "proident", "non", "non", "et", "cupidatat", "laborum" ], "friends": [ { "id": 0, "name": "Melody Rhodes" }, { "id": 1, "name": "Milagros Ball" }, { "id": 2, "name": "Tate Acosta" }, { "id": 3, "name": "Ann Cox" }, { "id": 4, "name": "Kerri Cleveland" } ], "greeting": "Hello, Liza Oneill! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482617f02e9cbb2dae65", "index": 425, "guid": "b1555f37-60dd-4f10-ad21-35fea194ede4", "isActive": false, "balance": "$3,088.49", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Patti Flynn", "gender": "female", "company": "EARTHWAX", "email": "pattiflynn@earthwax.com", "phone": "+1 (920) 554-3136", "address": "446 Channel Avenue, Greenwich, Colorado, 7687", "about": "Eu irure eiusmod cupidatat cillum in est minim qui sunt magna eiusmod ea. Esse elit adipisicing ex do voluptate aliquip eiusmod eu et. Velit dolore est magna dolor quis duis aliquip.\r\n", "registered": "2014-04-19T01:13:43 -02:00", "latitude": -41.642568, "longitude": 52.647258, "tags": [ "ea", "non", "id", "sint", "nulla", "veniam", "non", "Lorem", "est", "ipsum" ], "friends": [ { "id": 0, "name": "Audrey Martinez" }, { "id": 1, "name": "Deborah Sutton" }, { "id": 2, "name": "Rose Jennings" }, { "id": 3, "name": "Grimes Bender" }, { "id": 4, "name": "Tommie Norton" } ], "greeting": "Hello, Patti Flynn! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826c149a28dbb5c33c8", "index": 426, "guid": "2b894605-a55b-42ef-8c10-b4d751101255", "isActive": true, "balance": "$1,517.45", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "brown", "name": "Priscilla Mosley", "gender": "female", "company": "ZORROMOP", "email": "priscillamosley@zorromop.com", "phone": "+1 (885) 423-2245", "address": "636 Kenmore Terrace, Coultervillle, New Hampshire, 234", "about": "In consectetur qui excepteur occaecat tempor quis. Dolor elit ex cillum qui cupidatat commodo esse aute laboris ut aliqua pariatur. Proident culpa et sit culpa ut ullamco tempor aute in sint voluptate incididunt cupidatat reprehenderit. Anim consequat excepteur ullamco fugiat laborum proident sit labore laborum dolore minim nulla sit Lorem. Velit labore amet eiusmod pariatur quis ut non pariatur ut elit. Voluptate et qui exercitation magna sunt sint nostrud ut officia anim eu pariatur et.\r\n", "registered": "2014-09-26T02:27:15 -02:00", "latitude": -76.762117, "longitude": -137.060119, "tags": [ "excepteur", "anim", "ipsum", "consequat", "officia", "elit", "voluptate", "id", "dolore", "ut" ], "friends": [ { "id": 0, "name": "Coleen Ray" }, { "id": 1, "name": "Lindsay Banks" }, { "id": 2, "name": "Elena Bennett" }, { "id": 3, "name": "Madden Orr" }, { "id": 4, "name": "Terry Stanton" } ], "greeting": "Hello, Priscilla Mosley! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826e75caed64f937138", "index": 427, "guid": "b16f45df-5561-4504-b590-500bb3d9b013", "isActive": false, "balance": "$1,182.59", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "brown", "name": "Floyd Bryant", "gender": "male", "company": "ZILLACON", "email": "floydbryant@zillacon.com", "phone": "+1 (970) 474-3687", "address": "413 Otsego Street, Fairforest, Wisconsin, 9412", "about": "Enim amet mollit incididunt laborum aliquip ex elit et dolore ea aliquip consectetur tempor qui. Sunt exercitation pariatur dolor ad dolor do anim quis ipsum. Duis occaecat Lorem qui qui tempor mollit reprehenderit ipsum. Minim laboris mollit Lorem proident ad officia et enim consectetur non Lorem ad. Sint veniam nostrud aliquip et ea aute non duis. Mollit minim consequat magna qui irure ullamco.\r\n", "registered": "2015-10-12T02:30:30 -02:00", "latitude": -48.710265, "longitude": -63.516458, "tags": [ "deserunt", "minim", "elit", "sunt", "ad", "ex", "cillum", "enim", "tempor", "occaecat" ], "friends": [ { "id": 0, "name": "Cherie Petty" }, { "id": 1, "name": "Rosario Weber" }, { "id": 2, "name": "Holmes Romero" }, { "id": 3, "name": "Casandra Price" }, { "id": 4, "name": "Mai Steele" } ], "greeting": "Hello, Floyd Bryant! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48264a9531026368b679", "index": 428, "guid": "ec02e5ce-0ce5-453e-b86e-5b8c16dde587", "isActive": false, "balance": "$3,023.30", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "brown", "name": "Andrea Stark", "gender": "female", "company": "TERASCAPE", "email": "andreastark@terascape.com", "phone": "+1 (846) 525-2202", "address": "774 Caton Avenue, Mayfair, Idaho, 1513", "about": "Ea qui tempor anim voluptate nostrud tempor laboris voluptate id excepteur culpa mollit excepteur. Sunt officia sunt anim enim sunt qui proident. Nostrud et qui enim veniam et pariatur dolore nisi voluptate mollit. Ut eiusmod Lorem consequat anim qui. Pariatur quis elit quis cillum. Elit labore non deserunt ad voluptate cillum nostrud non adipisicing esse reprehenderit.\r\n", "registered": "2015-04-24T02:39:30 -02:00", "latitude": 29.625089, "longitude": -49.959296, "tags": [ "deserunt", "sunt", "consequat", "do", "enim", "excepteur", "sit", "eu", "sit", "tempor" ], "friends": [ { "id": 0, "name": "Julianne Alston" }, { "id": 1, "name": "Shaw Norman" }, { "id": 2, "name": "Lara Morrow" }, { "id": 3, "name": "Petersen Bowers" }, { "id": 4, "name": "Rowland Crawford" } ], "greeting": "Hello, Andrea Stark! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48265d7eca2cb4623eed", "index": 429, "guid": "2a6c44ef-0ea0-4e38-be58-94c0812c0f6b", "isActive": true, "balance": "$3,269.25", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "brown", "name": "Rosanna Robbins", "gender": "female", "company": "GEEKY", "email": "rosannarobbins@geeky.com", "phone": "+1 (990) 481-3270", "address": "190 Duffield Street, Chestnut, Georgia, 2126", "about": "Culpa sit enim dolor aliqua dolore quis excepteur qui culpa aute aliquip tempor quis. Nostrud reprehenderit officia aliqua voluptate culpa. Excepteur ut ea dolore cupidatat. Ex occaecat elit ad velit consectetur officia labore ullamco laborum non ullamco officia quis. Id qui laboris fugiat velit adipisicing est duis. Ut proident deserunt commodo ea duis sunt exercitation Lorem cupidatat laborum ad enim elit.\r\n", "registered": "2015-09-02T12:31:00 -02:00", "latitude": -46.18084, "longitude": -171.086428, "tags": [ "consectetur", "nostrud", "enim", "amet", "velit", "officia", "consequat", "dolore", "ullamco", "exercitation" ], "friends": [ { "id": 0, "name": "Abby Silva" }, { "id": 1, "name": "Fannie Kaufman" }, { "id": 2, "name": "Mcdaniel Crane" }, { "id": 3, "name": "Stewart Robertson" }, { "id": 4, "name": "Camille Rosa" } ], "greeting": "Hello, Rosanna Robbins! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826511d79ff6775a810", "index": 430, "guid": "2821568f-600c-4ee4-bf09-9e741f6555f3", "isActive": false, "balance": "$1,483.27", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Harmon Mccarthy", "gender": "male", "company": "INQUALA", "email": "harmonmccarthy@inquala.com", "phone": "+1 (901) 529-3670", "address": "731 Montauk Court, Felt, Virgin Islands, 1362", "about": "Eu quis eiusmod minim magna commodo velit voluptate occaecat consequat excepteur id consectetur. Ut ea elit cupidatat magna voluptate est Lorem ad. Ut magna veniam voluptate do eu nisi. Irure duis deserunt labore et aute eiusmod irure culpa labore qui. Culpa laboris nulla ex culpa quis et exercitation irure labore. Eiusmod cillum consectetur pariatur proident excepteur nostrud id officia eu quis voluptate tempor nulla ullamco.\r\n", "registered": "2015-02-17T03:42:20 -01:00", "latitude": -87.615455, "longitude": -4.888133, "tags": [ "quis", "irure", "cillum", "sit", "velit", "pariatur", "pariatur", "id", "elit", "enim" ], "friends": [ { "id": 0, "name": "Shelley Pace" }, { "id": 1, "name": "Allyson Parker" }, { "id": 2, "name": "Bernadette Francis" }, { "id": 3, "name": "Bowen Tyler" }, { "id": 4, "name": "Nikki Dejesus" } ], "greeting": "Hello, Harmon Mccarthy! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826be131e6e2a277d6e", "index": 431, "guid": "8f83641e-fa4a-4e3d-a5db-d26e643afa66", "isActive": false, "balance": "$3,112.33", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "brown", "name": "Boone Bonner", "gender": "male", "company": "SAVVY", "email": "boonebonner@savvy.com", "phone": "+1 (816) 406-3982", "address": "280 Coyle Street, Draper, Minnesota, 2923", "about": "Culpa non incididunt adipisicing aliquip dolor sit Lorem fugiat laborum id eiusmod. Proident in aliquip ea ex excepteur consectetur tempor commodo est et duis deserunt sunt dolore. Laboris ad do in culpa. Tempor eu do cillum aliqua in aliqua officia. Lorem cupidatat in in sint anim pariatur et qui.\r\n", "registered": "2017-11-16T11:48:01 -01:00", "latitude": -89.267498, "longitude": 86.871743, "tags": [ "sunt", "ea", "et", "officia", "ullamco", "ea", "fugiat", "nostrud", "dolore", "eu" ], "friends": [ { "id": 0, "name": "Tammy Macias" }, { "id": 1, "name": "Sawyer Ayala" }, { "id": 2, "name": "Weiss Cherry" }, { "id": 3, "name": "Neva Long" }, { "id": 4, "name": "Roseann Burgess" } ], "greeting": "Hello, Boone Bonner! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48268c10edc069e7546f", "index": 432, "guid": "a26bd655-3ab4-4058-9921-566392672129", "isActive": false, "balance": "$2,491.11", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Maggie Jefferson", "gender": "female", "company": "VALREDA", "email": "maggiejefferson@valreda.com", "phone": "+1 (831) 440-3157", "address": "726 Clermont Avenue, Oneida, South Carolina, 4749", "about": "Sint amet laboris consectetur nisi incididunt commodo occaecat aliquip voluptate Lorem sit anim enim. Deserunt aute ipsum laboris eu eiusmod irure pariatur ea aute veniam ullamco excepteur in. Nulla elit minim in pariatur quis ipsum dolor labore ex exercitation laborum reprehenderit sit.\r\n", "registered": "2015-01-29T12:31:45 -01:00", "latitude": -81.396315, "longitude": -65.730799, "tags": [ "incididunt", "ex", "commodo", "veniam", "sint", "reprehenderit", "anim", "cupidatat", "aute", "exercitation" ], "friends": [ { "id": 0, "name": "Watkins Oliver" }, { "id": 1, "name": "Dillard Barton" }, { "id": 2, "name": "Richard Olson" }, { "id": 3, "name": "Angelica Stephens" }, { "id": 4, "name": "Serena Miller" } ], "greeting": "Hello, Maggie Jefferson! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b69a04b49cc34baa", "index": 433, "guid": "34f06b9f-c643-4c23-92e6-25d370dca2d4", "isActive": false, "balance": "$1,040.67", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Fran Zimmerman", "gender": "female", "company": "COFINE", "email": "franzimmerman@cofine.com", "phone": "+1 (871) 436-2353", "address": "529 Tampa Court, Geyserville, Northern Mariana Islands, 3498", "about": "Qui dolor tempor occaecat labore ad aliqua aliquip qui aliqua. Dolor consectetur culpa ea est consectetur exercitation laborum irure. Eiusmod elit reprehenderit nulla aliqua nulla eiusmod labore reprehenderit excepteur qui in. Laborum minim ea anim dolore.\r\n", "registered": "2015-09-06T03:54:43 -02:00", "latitude": 13.35741, "longitude": 138.552844, "tags": [ "adipisicing", "deserunt", "culpa", "mollit", "labore", "aliquip", "officia", "id", "adipisicing", "in" ], "friends": [ { "id": 0, "name": "Aida Fry" }, { "id": 1, "name": "Genevieve Waters" }, { "id": 2, "name": "Monroe Hayden" }, { "id": 3, "name": "Janet Pennington" }, { "id": 4, "name": "Raquel Donovan" } ], "greeting": "Hello, Fran Zimmerman! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826ed518acc06552428", "index": 434, "guid": "4df8cb9c-3bbb-49b7-bbc2-ee4d883bf759", "isActive": false, "balance": "$2,301.47", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "green", "name": "Rich Carey", "gender": "male", "company": "COMVEYER", "email": "richcarey@comveyer.com", "phone": "+1 (823) 544-3007", "address": "789 Brooklyn Road, Soudan, Pennsylvania, 6121", "about": "Consequat excepteur voluptate dolor eiusmod commodo veniam occaecat incididunt aute consectetur incididunt et laboris. Proident aliqua in irure sint velit. Officia id nulla ullamco laboris duis est fugiat eiusmod. Do sunt elit fugiat dolore nulla est tempor ea eu. Voluptate anim deserunt elit ullamco consectetur quis anim et laboris aliquip. Ea deserunt non consequat est laborum commodo elit excepteur consequat proident. Consequat pariatur aliqua ea velit culpa irure magna non ut.\r\n", "registered": "2014-02-09T04:08:57 -01:00", "latitude": -33.554936, "longitude": -173.453556, "tags": [ "id", "fugiat", "eu", "ipsum", "consectetur", "ipsum", "minim", "occaecat", "veniam", "non" ], "friends": [ { "id": 0, "name": "Jenna Love" }, { "id": 1, "name": "Jessica Frye" }, { "id": 2, "name": "Bruce Callahan" }, { "id": 3, "name": "Dena Winters" }, { "id": 4, "name": "Mcgowan Gilliam" } ], "greeting": "Hello, Rich Carey! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826a0b1b5f6b81a1023", "index": 435, "guid": "73245e06-39a5-4732-9de2-f3eaa1fa821b", "isActive": true, "balance": "$1,601.45", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "brown", "name": "Gilliam Melton", "gender": "male", "company": "MITROC", "email": "gilliammelton@mitroc.com", "phone": "+1 (941) 523-2964", "address": "296 Boerum Street, Floriston, Arkansas, 1690", "about": "Aliquip officia sunt nostrud consectetur proident consectetur cillum sint cupidatat laboris veniam exercitation non voluptate. Elit dolor culpa cupidatat esse in quis nostrud dolor tempor sunt. Tempor tempor sit commodo velit elit commodo commodo reprehenderit sint. Ipsum ea nostrud ullamco ipsum id aliqua exercitation laborum quis qui aute non officia consequat. Voluptate incididunt minim aute ut fugiat non irure aliquip. Qui reprehenderit id exercitation nulla ipsum duis sint sint eu officia.\r\n", "registered": "2017-04-09T08:36:45 -02:00", "latitude": -58.728022, "longitude": 143.596262, "tags": [ "nulla", "cillum", "pariatur", "culpa", "ut", "sint", "veniam", "amet", "minim", "nulla" ], "friends": [ { "id": 0, "name": "Rosemarie Carrillo" }, { "id": 1, "name": "Richmond Warner" }, { "id": 2, "name": "Pugh Alford" }, { "id": 3, "name": "Ortiz Cline" }, { "id": 4, "name": "Atkinson Velasquez" } ], "greeting": "Hello, Gilliam Melton! You have 9 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f40accd505faff08", "index": 436, "guid": "fd378f7f-d68a-4bcc-ba3c-3d89a5409de1", "isActive": true, "balance": "$1,046.89", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "blue", "name": "Brooke Mckee", "gender": "female", "company": "COMVEX", "email": "brookemckee@comvex.com", "phone": "+1 (970) 480-3979", "address": "765 Putnam Avenue, Hatteras, Palau, 6008", "about": "Irure sit minim eiusmod eu id pariatur. Commodo nostrud ipsum dolore esse duis veniam sit dolor Lorem consectetur enim eiusmod aliquip. Adipisicing ex ipsum ex et eiusmod laboris nisi est nostrud mollit nostrud aliqua. Aliqua mollit deserunt aute sunt laboris nulla aliquip.\r\n", "registered": "2016-04-30T04:14:33 -02:00", "latitude": -80.874451, "longitude": 15.684911, "tags": [ "qui", "esse", "voluptate", "ullamco", "Lorem", "aliquip", "labore", "consequat", "consequat", "laborum" ], "friends": [ { "id": 0, "name": "Janell Hebert" }, { "id": 1, "name": "Mathews Sykes" }, { "id": 2, "name": "Herman Blair" }, { "id": 3, "name": "Reva Roach" }, { "id": 4, "name": "Valentine Mitchell" } ], "greeting": "Hello, Brooke Mckee! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482606b2c704f7d8ad17", "index": 437, "guid": "ba060e22-4b88-4a67-954d-da167cd5a966", "isActive": false, "balance": "$3,543.76", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "green", "name": "Padilla Vincent", "gender": "male", "company": "WAAB", "email": "padillavincent@waab.com", "phone": "+1 (914) 581-3097", "address": "403 Lyme Avenue, Eagleville, Connecticut, 2705", "about": "Est do laboris aliqua minim proident adipisicing exercitation veniam veniam Lorem cillum consequat commodo minim. Sint amet mollit dolor veniam quis magna aute. Eu excepteur amet occaecat excepteur laborum pariatur eiusmod ad veniam fugiat. Eiusmod nostrud ut aliqua ea culpa ullamco est officia elit est voluptate.\r\n", "registered": "2016-04-05T05:03:08 -02:00", "latitude": -50.824722, "longitude": 88.664951, "tags": [ "laboris", "anim", "adipisicing", "id", "sit", "non", "dolor", "deserunt", "occaecat", "ea" ], "friends": [ { "id": 0, "name": "Travis Austin" }, { "id": 1, "name": "Julie Glover" }, { "id": 2, "name": "Viola Goodwin" }, { "id": 3, "name": "Green Compton" }, { "id": 4, "name": "Gregory Wooten" } ], "greeting": "Hello, Padilla Vincent! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48269b182d90fdd07f8c", "index": 438, "guid": "31773574-3f55-44a9-b18c-d09551319ffa", "isActive": true, "balance": "$1,022.72", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "brown", "name": "Kim Harding", "gender": "male", "company": "OTHERWAY", "email": "kimharding@otherway.com", "phone": "+1 (946) 536-2540", "address": "528 Mill Road, Bentonville, North Carolina, 1099", "about": "Cupidatat aute cupidatat incididunt eu anim aliquip est. Amet nisi eu dolore est. Do mollit fugiat culpa sit dolore sint non ullamco sint. Duis tempor voluptate laboris esse et dolore anim voluptate occaecat est ut. Ipsum ea officia consectetur cillum adipisicing officia sint. Commodo sint consectetur anim laboris consequat do nisi cillum mollit duis culpa pariatur irure officia. Exercitation eu nostrud do consequat.\r\n", "registered": "2014-11-17T06:28:26 -01:00", "latitude": 5.352883, "longitude": -166.971323, "tags": [ "ad", "minim", "eiusmod", "sunt", "veniam", "aliqua", "dolor", "est", "est", "incididunt" ], "friends": [ { "id": 0, "name": "Earline Spears" }, { "id": 1, "name": "Inez Giles" }, { "id": 2, "name": "Espinoza Branch" }, { "id": 3, "name": "Samantha Mathis" }, { "id": 4, "name": "Jackie Carpenter" } ], "greeting": "Hello, Kim Harding! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826e9a89342479ca46b", "index": 439, "guid": "ad301f79-5bac-4b88-95db-305e1c3aadb1", "isActive": true, "balance": "$1,731.71", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "brown", "name": "Jeannette Blanchard", "gender": "female", "company": "INDEXIA", "email": "jeannetteblanchard@indexia.com", "phone": "+1 (953) 480-2061", "address": "727 Ashford Street, Shrewsbury, Missouri, 1770", "about": "Eiusmod non quis tempor magna elit laboris officia voluptate sunt labore minim esse duis fugiat. Ad in cillum officia sint sit nulla labore proident enim eu fugiat in. Non cillum veniam ipsum ad. Ut adipisicing Lorem ex exercitation dolore eu quis officia cillum mollit proident. Labore quis enim ea ea officia ex elit sit labore commodo minim et. Reprehenderit est et et sunt.\r\n", "registered": "2017-01-15T05:38:37 -01:00", "latitude": 16.184659, "longitude": 153.388184, "tags": [ "aliquip", "mollit", "incididunt", "pariatur", "ea", "Lorem", "quis", "nulla", "exercitation", "voluptate" ], "friends": [ { "id": 0, "name": "Selena Mullen" }, { "id": 1, "name": "Roxanne Howe" }, { "id": 2, "name": "Kristen Decker" }, { "id": 3, "name": "Ella Flowers" }, { "id": 4, "name": "Dixon Britt" } ], "greeting": "Hello, Jeannette Blanchard! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48261f247e766b138898", "index": 440, "guid": "1269ca61-7bb1-47ca-a64f-b25e2e9be2cd", "isActive": true, "balance": "$2,777.13", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "brown", "name": "Price Slater", "gender": "male", "company": "GAPTEC", "email": "priceslater@gaptec.com", "phone": "+1 (829) 525-2081", "address": "744 Bogart Street, Marbury, Ohio, 9093", "about": "Mollit minim magna adipisicing laborum minim deserunt laboris. Duis consectetur ullamco do ex nulla. Exercitation elit ullamco irure adipisicing quis ea. Cillum culpa cillum enim ullamco adipisicing et culpa laborum ut et exercitation cillum est magna.\r\n", "registered": "2014-12-01T01:37:23 -01:00", "latitude": -77.977944, "longitude": 71.766827, "tags": [ "incididunt", "enim", "ex", "ex", "cupidatat", "ut", "cupidatat", "irure", "in", "et" ], "friends": [ { "id": 0, "name": "Leola Whitaker" }, { "id": 1, "name": "Jannie Weeks" }, { "id": 2, "name": "Chrystal Faulkner" }, { "id": 3, "name": "Caroline Morales" }, { "id": 4, "name": "Jennie Schmidt" } ], "greeting": "Hello, Price Slater! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826fb806b5572a1e965", "index": 441, "guid": "ee852f8e-f95f-4cc2-977e-52ae685c6fa7", "isActive": true, "balance": "$1,321.66", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "brown", "name": "Cleveland Mathews", "gender": "male", "company": "NURPLEX", "email": "clevelandmathews@nurplex.com", "phone": "+1 (816) 494-3436", "address": "411 Ocean Court, Aguila, Arizona, 4496", "about": "Ea tempor nulla nisi do labore qui ipsum fugiat ad duis irure. Anim consectetur pariatur eu mollit minim deserunt voluptate. Aliqua Lorem nulla velit aliquip eu dolore. Eiusmod labore ullamco amet ipsum ea culpa Lorem amet reprehenderit laboris sint fugiat.\r\n", "registered": "2018-01-12T07:07:58 -01:00", "latitude": -1.58806, "longitude": -121.400243, "tags": [ "exercitation", "irure", "sunt", "ullamco", "deserunt", "laboris", "magna", "cupidatat", "et", "incididunt" ], "friends": [ { "id": 0, "name": "Brianna Hodge" }, { "id": 1, "name": "Elliott Sheppard" }, { "id": 2, "name": "Meredith Alvarado" }, { "id": 3, "name": "Clara Mckay" }, { "id": 4, "name": "Romero Bradshaw" } ], "greeting": "Hello, Cleveland Mathews! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826487b4c65dd1b91a4", "index": 442, "guid": "3fc6e489-6bd9-46a9-89c4-331915790d78", "isActive": false, "balance": "$3,965.73", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "green", "name": "Fry Owens", "gender": "male", "company": "ZENTHALL", "email": "fryowens@zenthall.com", "phone": "+1 (839) 451-2379", "address": "744 Beverley Road, Blanford, Montana, 6042", "about": "Magna occaecat ullamco sunt eiusmod. Est nisi Lorem mollit pariatur incididunt consectetur cillum in ullamco excepteur ex dolor culpa aliquip. Laboris mollit aute cupidatat esse. Aliqua aute irure tempor minim sit.\r\n", "registered": "2016-01-01T10:01:20 -01:00", "latitude": -1.125302, "longitude": -84.235795, "tags": [ "sit", "amet", "tempor", "quis", "culpa", "labore", "non", "ex", "sit", "deserunt" ], "friends": [ { "id": 0, "name": "Earlene Woodard" }, { "id": 1, "name": "Castillo Miranda" }, { "id": 2, "name": "Ruthie Hamilton" }, { "id": 3, "name": "Greta Matthews" }, { "id": 4, "name": "Wilkins Cohen" } ], "greeting": "Hello, Fry Owens! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f7872b3ce03fe7a4", "index": 443, "guid": "e102a1d8-80fc-4677-afab-fb7871040a21", "isActive": true, "balance": "$3,778.78", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Tamra Trujillo", "gender": "female", "company": "EZENT", "email": "tamratrujillo@ezent.com", "phone": "+1 (871) 534-3912", "address": "708 Gerald Court, Belva, Texas, 4894", "about": "Elit do cillum labore incididunt commodo eiusmod et mollit exercitation. Et aliqua anim mollit ullamco consequat quis laborum. Ex cillum ipsum commodo non incididunt ad dolor. Consectetur sunt qui deserunt nisi excepteur sit proident pariatur nulla. Quis cupidatat in magna aute quis ex amet amet consequat adipisicing.\r\n", "registered": "2015-12-29T06:05:47 -01:00", "latitude": -73.079546, "longitude": -4.529838, "tags": [ "anim", "pariatur", "officia", "consequat", "ut", "tempor", "amet", "id", "nisi", "voluptate" ], "friends": [ { "id": 0, "name": "Velez Calhoun" }, { "id": 1, "name": "Mccray Duffy" }, { "id": 2, "name": "Neal Mcfarland" }, { "id": 3, "name": "Lula Strong" }, { "id": 4, "name": "Wilkinson May" } ], "greeting": "Hello, Tamra Trujillo! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c7c3fc7a8f5a1e92", "index": 444, "guid": "c570b02f-e4b1-4425-b7aa-c76d7ab457c8", "isActive": true, "balance": "$2,892.19", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "brown", "name": "Gracie Lynch", "gender": "female", "company": "SQUISH", "email": "gracielynch@squish.com", "phone": "+1 (851) 407-2998", "address": "697 Coventry Road, Zeba, Washington, 9871", "about": "Proident qui nulla reprehenderit aliquip aliqua sunt id eu ex velit magna nulla proident adipisicing. Laborum Lorem excepteur est do aute consectetur cillum irure fugiat amet do nisi eiusmod aliquip. Laborum aliqua et ipsum eu anim exercitation. Est laboris labore irure sint irure cupidatat. Esse commodo fugiat sit irure nisi culpa aute culpa ipsum nostrud. Laboris non consequat id proident id aute commodo ullamco aliquip nulla nisi. Eu ullamco laboris exercitation pariatur magna.\r\n", "registered": "2017-02-23T01:10:15 -01:00", "latitude": 41.822311, "longitude": 112.569916, "tags": [ "duis", "ullamco", "occaecat", "laboris", "exercitation", "laboris", "deserunt", "excepteur", "incididunt", "nulla" ], "friends": [ { "id": 0, "name": "Colleen Reese" }, { "id": 1, "name": "Lessie Forbes" }, { "id": 2, "name": "Garrett Summers" }, { "id": 3, "name": "Jill Lloyd" }, { "id": 4, "name": "Watts Potter" } ], "greeting": "Hello, Gracie Lynch! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c6a18509ca2df5b9", "index": 445, "guid": "7b927f1f-e642-410c-a039-d375c073643a", "isActive": true, "balance": "$1,888.40", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Nash Aguirre", "gender": "male", "company": "NAMEGEN", "email": "nashaguirre@namegen.com", "phone": "+1 (865) 541-2212", "address": "139 Rockaway Parkway, Kidder, Wyoming, 5171", "about": "Voluptate ad aute aute reprehenderit cillum ullamco et labore magna culpa laborum. Proident nostrud cupidatat adipisicing id sint dolor magna proident. Dolore elit consectetur laboris excepteur sit enim magna voluptate ex adipisicing commodo ut nisi.\r\n", "registered": "2014-01-01T01:24:12 -01:00", "latitude": 61.033032, "longitude": 50.864764, "tags": [ "nulla", "dolore", "laborum", "amet", "quis", "deserunt", "in", "aliqua", "ipsum", "mollit" ], "friends": [ { "id": 0, "name": "Virginia Gallagher" }, { "id": 1, "name": "Carol Rivers" }, { "id": 2, "name": "Madeline Nash" }, { "id": 3, "name": "Mcneil Hahn" }, { "id": 4, "name": "Marissa Kramer" } ], "greeting": "Hello, Nash Aguirre! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826cdf939f8e6b4e0f7", "index": 446, "guid": "fda1564f-57fb-4a39-a9a8-94119cc4d2e2", "isActive": false, "balance": "$1,764.67", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "brown", "name": "Rosetta Estes", "gender": "female", "company": "SPEEDBOLT", "email": "rosettaestes@speedbolt.com", "phone": "+1 (968) 403-2480", "address": "460 Reed Street, Winesburg, Indiana, 9623", "about": "Id officia dolore cillum Lorem. Magna tempor fugiat ex incididunt reprehenderit est anim ut irure elit mollit velit tempor. Do culpa deserunt irure ut ex ipsum nulla labore non. Laboris duis quis amet aliquip voluptate laborum. Commodo minim irure consequat tempor proident commodo dolor irure laboris.\r\n", "registered": "2015-07-31T05:41:45 -02:00", "latitude": -22.883805, "longitude": -157.133292, "tags": [ "laborum", "occaecat", "dolore", "et", "et", "occaecat", "quis", "Lorem", "exercitation", "ut" ], "friends": [ { "id": 0, "name": "Geneva Hensley" }, { "id": 1, "name": "Cathleen Barrera" }, { "id": 2, "name": "Katelyn Franklin" }, { "id": 3, "name": "Mccarty Tran" }, { "id": 4, "name": "Mercado Gonzalez" } ], "greeting": "Hello, Rosetta Estes! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482656400e12dcfe67ad", "index": 447, "guid": "2fd5df64-4d8f-4856-89d5-f747e241c876", "isActive": false, "balance": "$3,088.19", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Cooper Knowles", "gender": "male", "company": "VISALIA", "email": "cooperknowles@visalia.com", "phone": "+1 (900) 537-3487", "address": "540 Hanson Place, Jacksonburg, Alabama, 1853", "about": "Est fugiat consequat pariatur dolore laboris ad nulla elit voluptate aliqua aliqua. Dolore dolor ullamco consectetur pariatur tempor consequat non pariatur quis aliqua non consequat sunt Lorem. Tempor ut occaecat velit sunt veniam. Sunt ut nisi amet quis consequat sunt aliquip eiusmod officia aliquip mollit eiusmod dolor pariatur. Qui qui non sint mollit est ex ad dolor culpa irure nisi deserunt. Aliqua reprehenderit ad amet minim.\r\n", "registered": "2017-11-08T11:56:16 -01:00", "latitude": -74.396495, "longitude": 97.552698, "tags": [ "nisi", "adipisicing", "consequat", "non", "occaecat", "nisi", "dolor", "officia", "adipisicing", "nostrud" ], "friends": [ { "id": 0, "name": "Rene Cannon" }, { "id": 1, "name": "Deloris Sampson" }, { "id": 2, "name": "Aimee Case" }, { "id": 3, "name": "Edwina Dean" }, { "id": 4, "name": "Manuela Bond" } ], "greeting": "Hello, Cooper Knowles! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826be10481abbfa099b", "index": 448, "guid": "ddf26d2e-d4c6-4c28-b3a6-8da3f1e51fb9", "isActive": true, "balance": "$3,422.56", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "brown", "name": "Gladys Keith", "gender": "female", "company": "OZEAN", "email": "gladyskeith@ozean.com", "phone": "+1 (922) 403-2244", "address": "757 Scholes Street, Stollings, Virginia, 1195", "about": "Laboris ad do amet ullamco proident. Quis aute id qui reprehenderit aliquip id consectetur tempor commodo sint aliqua laboris. Est do magna minim ea ad consectetur est. Voluptate sit do ad deserunt laboris mollit sint cillum anim reprehenderit commodo velit.\r\n", "registered": "2016-11-05T06:02:05 -01:00", "latitude": 68.737148, "longitude": 30.155813, "tags": [ "anim", "officia", "id", "officia", "ipsum", "cillum", "quis", "pariatur", "irure", "minim" ], "friends": [ { "id": 0, "name": "Molina Vaughan" }, { "id": 1, "name": "Hartman Ryan" }, { "id": 2, "name": "Avis Kelley" }, { "id": 3, "name": "Baldwin Swanson" }, { "id": 4, "name": "Lynda Roth" } ], "greeting": "Hello, Gladys Keith! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826900af7ffa97c54c1", "index": 449, "guid": "51ea9ebe-3406-4dd4-9dd6-636308e871be", "isActive": false, "balance": "$3,471.08", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "green", "name": "Nanette Powers", "gender": "female", "company": "APEXIA", "email": "nanettepowers@apexia.com", "phone": "+1 (980) 596-3417", "address": "141 Elizabeth Place, Rivereno, New Mexico, 6219", "about": "Minim Lorem laborum esse aliquip sint dolor ullamco anim fugiat in nisi laborum. Sit occaecat cupidatat commodo ad proident deserunt ipsum eiusmod mollit incididunt. Labore cillum aliqua et laborum irure dolor pariatur fugiat officia veniam minim consectetur.\r\n", "registered": "2014-12-17T05:27:23 -01:00", "latitude": 34.649932, "longitude": 124.50597, "tags": [ "anim", "cillum", "reprehenderit", "eiusmod", "elit", "velit", "exercitation", "aliquip", "cupidatat", "eiusmod" ], "friends": [ { "id": 0, "name": "Browning Gould" }, { "id": 1, "name": "Blackwell Dotson" }, { "id": 2, "name": "Grant Rice" }, { "id": 3, "name": "Faulkner Clark" }, { "id": 4, "name": "Puckett Stein" } ], "greeting": "Hello, Nanette Powers! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826dd982d9cc351ca7d", "index": 450, "guid": "b85a3195-6ac0-424d-a2d1-25ccd9427185", "isActive": false, "balance": "$1,189.86", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Suzanne Mooney", "gender": "female", "company": "BOILCAT", "email": "suzannemooney@boilcat.com", "phone": "+1 (982) 415-3747", "address": "405 Adams Street, Kenmar, Hawaii, 3329", "about": "Quis est eu mollit in exercitation nostrud Lorem. Ipsum reprehenderit dolore occaecat proident aute nulla minim quis anim laborum Lorem. Quis anim eu adipisicing voluptate ipsum id anim in velit sunt occaecat eiusmod deserunt ullamco. Ea consectetur Lorem irure consequat mollit aliquip id. Reprehenderit pariatur nostrud pariatur tempor.\r\n", "registered": "2016-10-15T09:50:24 -02:00", "latitude": 58.968667, "longitude": -173.868272, "tags": [ "irure", "deserunt", "ipsum", "cillum", "consectetur", "eu", "ipsum", "aliqua", "nostrud", "laborum" ], "friends": [ { "id": 0, "name": "Bowers Fisher" }, { "id": 1, "name": "Welch Hester" }, { "id": 2, "name": "Kaitlin Potts" }, { "id": 3, "name": "Felecia Hardy" }, { "id": 4, "name": "Terry Ellis" } ], "greeting": "Hello, Suzanne Mooney! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c9637034c8f2b087", "index": 451, "guid": "9bc81a11-4fcb-46ac-b955-2030a75763af", "isActive": false, "balance": "$1,367.39", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "blue", "name": "Copeland Wilkerson", "gender": "male", "company": "MANUFACT", "email": "copelandwilkerson@manufact.com", "phone": "+1 (801) 591-2361", "address": "145 Taaffe Place, Chapin, Nebraska, 3480", "about": "Cupidatat minim enim labore reprehenderit dolor voluptate veniam duis. Commodo nostrud ad laboris excepteur ea cupidatat et consequat labore. Nulla ad Lorem non magna et.\r\n", "registered": "2014-02-02T09:39:03 -01:00", "latitude": 76.492819, "longitude": 84.644881, "tags": [ "magna", "voluptate", "aliqua", "nulla", "amet", "laborum", "esse", "ipsum", "est", "nisi" ], "friends": [ { "id": 0, "name": "Macdonald Meyer" }, { "id": 1, "name": "Terrie Mcfadden" }, { "id": 2, "name": "Duke Garrett" }, { "id": 3, "name": "Lowe Erickson" }, { "id": 4, "name": "Valarie Small" } ], "greeting": "Hello, Copeland Wilkerson! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48268cb6a384ea9b285b", "index": 452, "guid": "26a42689-b324-4aca-9fd7-021e766e38e1", "isActive": false, "balance": "$2,861.41", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "brown", "name": "Lindsay Fitzgerald", "gender": "female", "company": "VELOS", "email": "lindsayfitzgerald@velos.com", "phone": "+1 (926) 427-3503", "address": "994 Seagate Avenue, Deseret, New York, 8443", "about": "Laboris laborum consequat excepteur velit. Aliquip do fugiat sit dolore enim culpa. Consectetur laboris quis eiusmod excepteur. Tempor eu sint cillum ad consequat ullamco sit minim et consectetur.\r\n", "registered": "2016-05-12T09:04:58 -02:00", "latitude": -19.372964, "longitude": -110.778693, "tags": [ "sunt", "non", "ea", "elit", "ea", "duis", "mollit", "eu", "ea", "culpa" ], "friends": [ { "id": 0, "name": "Elise Hodges" }, { "id": 1, "name": "Freeman Lara" }, { "id": 2, "name": "Virgie Blankenship" }, { "id": 3, "name": "Weber Church" }, { "id": 4, "name": "Rose Moses" } ], "greeting": "Hello, Lindsay Fitzgerald! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826ca88569d16389cc0", "index": 453, "guid": "3aed65d3-4e8b-4ad7-91ca-585ae038c2f6", "isActive": false, "balance": "$1,947.21", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "green", "name": "Tammie Benjamin", "gender": "female", "company": "PROWASTE", "email": "tammiebenjamin@prowaste.com", "phone": "+1 (892) 467-2480", "address": "870 Gerry Street, Wright, Marshall Islands, 6083", "about": "Consectetur aliqua culpa proident officia. Fugiat eiusmod dolor labore voluptate cillum adipisicing qui ullamco dolore ea tempor laborum. Amet ullamco occaecat culpa aliqua enim aute.\r\n", "registered": "2016-12-21T07:18:52 -01:00", "latitude": -20.600831, "longitude": -154.905883, "tags": [ "fugiat", "ea", "elit", "minim", "anim", "laborum", "exercitation", "duis", "occaecat", "aliquip" ], "friends": [ { "id": 0, "name": "Hattie Mcintosh" }, { "id": 1, "name": "Dotson Townsend" }, { "id": 2, "name": "Bright Chen" }, { "id": 3, "name": "Jolene Freeman" }, { "id": 4, "name": "Marisol Willis" } ], "greeting": "Hello, Tammie Benjamin! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826f6e8356952bf4999", "index": 454, "guid": "e9eef9c7-8001-4e4b-af0a-a9d1ad3b5165", "isActive": true, "balance": "$1,072.65", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Chandler Baldwin", "gender": "male", "company": "GYNK", "email": "chandlerbaldwin@gynk.com", "phone": "+1 (851) 453-3345", "address": "590 Vista Place, Kylertown, Oregon, 1660", "about": "Fugiat deserunt laborum laborum magna Lorem exercitation nulla irure nisi laborum mollit cupidatat sunt. Excepteur ex enim reprehenderit ullamco ad voluptate. Dolor reprehenderit commodo pariatur incididunt aute labore anim qui aute minim aute aute.\r\n", "registered": "2014-08-04T04:09:52 -02:00", "latitude": 49.699536, "longitude": 86.732592, "tags": [ "nulla", "dolore", "minim", "sit", "dolor", "ea", "enim", "amet", "tempor", "occaecat" ], "friends": [ { "id": 0, "name": "Amber Blackwell" }, { "id": 1, "name": "Wilder Fletcher" }, { "id": 2, "name": "Maureen Camacho" }, { "id": 3, "name": "Rasmussen Curtis" }, { "id": 4, "name": "Shelia Mckinney" } ], "greeting": "Hello, Chandler Baldwin! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48266efab2b6b2d5c5a6", "index": 455, "guid": "80f2c4fb-9e6d-49f0-bf7a-5a75fdf18831", "isActive": false, "balance": "$3,281.58", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "blue", "name": "Hunter Mays", "gender": "male", "company": "EXIAND", "email": "huntermays@exiand.com", "phone": "+1 (864) 505-3524", "address": "317 Schenck Court, Edmund, Tennessee, 498", "about": "Magna deserunt dolore mollit fugiat nulla. Non aliqua tempor adipisicing nisi sunt velit amet commodo velit. Ea cupidatat cillum elit ad id labore ea. Officia ad excepteur ex sit eiusmod officia veniam aute reprehenderit elit voluptate nulla. Adipisicing eu occaecat consequat labore aute nulla occaecat labore cupidatat nostrud id incididunt eu et. Irure eiusmod non exercitation nulla pariatur deserunt commodo proident officia ea cupidatat.\r\n", "registered": "2016-05-17T12:29:51 -02:00", "latitude": -23.933395, "longitude": -84.8325, "tags": [ "cillum", "laboris", "ex", "cillum", "et", "et", "cillum", "do", "est", "aliqua" ], "friends": [ { "id": 0, "name": "Juanita Baxter" }, { "id": 1, "name": "Teri Blevins" }, { "id": 2, "name": "Annmarie Daniel" }, { "id": 3, "name": "Vonda Battle" }, { "id": 4, "name": "Merritt Ellison" } ], "greeting": "Hello, Hunter Mays! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e9edcb6371fe2fb1", "index": 456, "guid": "f4aa9af6-4ed7-462a-8089-49ccbafeaf9f", "isActive": true, "balance": "$1,820.10", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Deleon Bright", "gender": "male", "company": "GADTRON", "email": "deleonbright@gadtron.com", "phone": "+1 (860) 530-2962", "address": "669 Cass Place, Southmont, Nevada, 6054", "about": "Dolor ut aliquip ipsum amet excepteur mollit. Velit velit tempor in velit aute tempor duis. Enim reprehenderit quis consequat dolor magna tempor anim duis non occaecat anim aliquip. Exercitation proident nulla est sit amet. Incididunt elit consequat Lorem commodo.\r\n", "registered": "2017-03-10T11:49:09 -01:00", "latitude": -76.093068, "longitude": -163.995614, "tags": [ "proident", "anim", "qui", "ad", "dolor", "tempor", "adipisicing", "velit", "consectetur", "non" ], "friends": [ { "id": 0, "name": "Ayala Valentine" }, { "id": 1, "name": "Meghan Levine" }, { "id": 2, "name": "Manning Hill" }, { "id": 3, "name": "Olivia Gentry" }, { "id": 4, "name": "Helene Anderson" } ], "greeting": "Hello, Deleon Bright! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826946a71f547dc9208", "index": 457, "guid": "8aa4ab0c-5002-4bef-98c7-2ee789a67027", "isActive": false, "balance": "$3,176.99", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "brown", "name": "Augusta Horne", "gender": "female", "company": "REALMO", "email": "augustahorne@realmo.com", "phone": "+1 (971) 421-2743", "address": "557 Dunham Place, Retsof, Alaska, 8794", "about": "Anim aliquip esse ad officia ea enim in dolor ea. Amet Lorem esse amet quis. Veniam deserunt sunt nulla ex proident aliquip occaecat culpa enim veniam ullamco.\r\n", "registered": "2014-08-21T04:46:38 -02:00", "latitude": -76.620002, "longitude": 38.260139, "tags": [ "nulla", "et", "labore", "deserunt", "ex", "culpa", "proident", "ullamco", "fugiat", "ad" ], "friends": [ { "id": 0, "name": "Darla Edwards" }, { "id": 1, "name": "Sandy Macdonald" }, { "id": 2, "name": "Avila Aguilar" }, { "id": 3, "name": "King Rosales" }, { "id": 4, "name": "Lori Saunders" } ], "greeting": "Hello, Augusta Horne! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826d716a2e2fd1d9ab6", "index": 458, "guid": "ebb80867-0217-4f2e-a9a3-d8c2ee28cd97", "isActive": true, "balance": "$3,710.44", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "brown", "name": "Blackburn Gaines", "gender": "male", "company": "ICOLOGY", "email": "blackburngaines@icology.com", "phone": "+1 (874) 513-3957", "address": "914 Quay Street, Emory, Illinois, 7658", "about": "Pariatur amet excepteur qui consequat excepteur excepteur elit officia nostrud ut. Eiusmod dolor in aute ea officia. Laboris laboris elit voluptate voluptate aliqua excepteur reprehenderit dolor amet minim in ad culpa aliquip. Excepteur in in elit laborum reprehenderit officia quis nulla. Incididunt id anim proident Lorem dolor consectetur. Ea eu culpa anim adipisicing nostrud velit ullamco sit occaecat irure cupidatat. Nulla adipisicing duis occaecat aliqua reprehenderit cupidatat qui in aute excepteur labore.\r\n", "registered": "2016-01-11T12:27:35 -01:00", "latitude": -16.845185, "longitude": 105.109593, "tags": [ "eiusmod", "aliquip", "dolor", "irure", "enim", "dolore", "cillum", "ad", "est", "Lorem" ], "friends": [ { "id": 0, "name": "Ramos Richardson" }, { "id": 1, "name": "Cristina Mueller" }, { "id": 2, "name": "Bobbie Chavez" }, { "id": 3, "name": "Sherry Pruitt" }, { "id": 4, "name": "Anastasia Monroe" } ], "greeting": "Hello, Blackburn Gaines! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48267089269b8f4f83a9", "index": 459, "guid": "cb3cc5c0-f12b-4b2f-a049-90ca885c911a", "isActive": true, "balance": "$3,613.45", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "blue", "name": "Reilly Rodgers", "gender": "male", "company": "BOVIS", "email": "reillyrodgers@bovis.com", "phone": "+1 (902) 485-2134", "address": "905 Kensington Walk, Staples, Oklahoma, 8323", "about": "Ad et id minim aute in. Nostrud magna ipsum ut in nostrud cupidatat consectetur et ad. Voluptate anim ullamco velit aliqua reprehenderit. Duis fugiat in Lorem eiusmod. Laborum laboris est aute aliquip commodo nostrud. Dolore minim ea aute sit consequat Lorem ea anim ut proident labore adipisicing non.\r\n", "registered": "2017-02-01T11:28:53 -01:00", "latitude": 37.110607, "longitude": 2.059182, "tags": [ "sunt", "ea", "proident", "do", "dolore", "ea", "et", "occaecat", "velit", "ad" ], "friends": [ { "id": 0, "name": "Kathy Solomon" }, { "id": 1, "name": "Nieves Herrera" }, { "id": 2, "name": "Crane Valencia" }, { "id": 3, "name": "Stokes Booth" }, { "id": 4, "name": "Campos Blackburn" } ], "greeting": "Hello, Reilly Rodgers! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826e92e0602eab485c3", "index": 460, "guid": "149e0609-5fad-463e-9502-9650db62af06", "isActive": true, "balance": "$2,834.02", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Jacobs House", "gender": "male", "company": "EPLODE", "email": "jacobshouse@eplode.com", "phone": "+1 (977) 529-2633", "address": "298 Church Avenue, Castleton, Delaware, 7634", "about": "Nulla qui id fugiat ex magna adipisicing mollit consectetur dolore consequat amet dolor consectetur tempor. Ad cupidatat do nisi ad qui pariatur fugiat reprehenderit exercitation occaecat. Ad sint anim voluptate cillum magna. Sunt nisi pariatur enim sit ut.\r\n", "registered": "2014-04-27T02:15:17 -02:00", "latitude": -14.735654, "longitude": 152.592058, "tags": [ "excepteur", "esse", "ut", "in", "non", "amet", "aliquip", "Lorem", "aliquip", "adipisicing" ], "friends": [ { "id": 0, "name": "Adams Kirkland" }, { "id": 1, "name": "Elizabeth Ford" }, { "id": 2, "name": "Luella Justice" }, { "id": 3, "name": "Rochelle Watkins" }, { "id": 4, "name": "Hester Valenzuela" } ], "greeting": "Hello, Jacobs House! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826bf902ba5b8d1539e", "index": 461, "guid": "7081c2e2-e6ac-4070-80f4-ed45cafd5300", "isActive": false, "balance": "$3,693.36", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "brown", "name": "Carole Dennis", "gender": "female", "company": "DIGIFAD", "email": "caroledennis@digifad.com", "phone": "+1 (823) 482-3230", "address": "363 Kings Hwy, Helen, Federated States Of Micronesia, 7240", "about": "Ullamco eu laborum ad nisi exercitation et. Magna ex exercitation deserunt aliqua laborum sint consequat pariatur ea. Nisi sint aliqua proident laboris qui. Minim consectetur deserunt cupidatat ullamco occaecat pariatur. Ea sit qui aliquip ipsum ad ut laboris ipsum adipisicing veniam.\r\n", "registered": "2015-07-05T07:25:31 -02:00", "latitude": -39.910609, "longitude": 112.004195, "tags": [ "officia", "enim", "deserunt", "ad", "ex", "dolore", "consequat", "culpa", "elit", "deserunt" ], "friends": [ { "id": 0, "name": "Bender Alexander" }, { "id": 1, "name": "Sallie Hutchinson" }, { "id": 2, "name": "Carey Simmons" }, { "id": 3, "name": "Mavis Obrien" }, { "id": 4, "name": "Lea Contreras" } ], "greeting": "Hello, Carole Dennis! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826607e64d44577b4ae", "index": 462, "guid": "41c5b9f0-9c08-4ce8-9cbf-2287f8077c45", "isActive": true, "balance": "$1,261.02", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Leonor Lambert", "gender": "female", "company": "IDETICA", "email": "leonorlambert@idetica.com", "phone": "+1 (841) 481-3876", "address": "756 Estate Road, Bradenville, Florida, 6587", "about": "Ex anim aliquip incididunt pariatur adipisicing. Veniam sit adipisicing commodo ut. Labore culpa veniam anim qui cillum veniam ad sit Lorem.\r\n", "registered": "2017-09-12T09:38:53 -02:00", "latitude": -6.832549, "longitude": 100.398955, "tags": [ "reprehenderit", "sint", "enim", "proident", "est", "veniam", "nulla", "et", "eiusmod", "excepteur" ], "friends": [ { "id": 0, "name": "Susie Lynn" }, { "id": 1, "name": "Fox Mcintyre" }, { "id": 2, "name": "Britt Sherman" }, { "id": 3, "name": "Angie Phillips" }, { "id": 4, "name": "Hewitt Boyer" } ], "greeting": "Hello, Leonor Lambert! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826f3a16cbf4c76a2da", "index": 463, "guid": "e4b0a689-936c-4bc6-a3b0-0905ac3c9729", "isActive": false, "balance": "$1,744.86", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Buchanan Burke", "gender": "male", "company": "QUONATA", "email": "buchananburke@quonata.com", "phone": "+1 (819) 453-2244", "address": "736 Sands Street, Cashtown, Massachusetts, 7013", "about": "In quis ex reprehenderit non ex ipsum laborum reprehenderit. Dolor pariatur aliquip magna anim. Sit consectetur reprehenderit nulla cupidatat nulla nisi ad anim. Pariatur cillum sit dolore minim exercitation mollit eiusmod sint in. Adipisicing sit ut esse non tempor ad magna ex nulla sit nostrud cillum.\r\n", "registered": "2017-10-28T03:03:16 -02:00", "latitude": 44.906382, "longitude": 99.801866, "tags": [ "nulla", "exercitation", "eu", "ullamco", "labore", "deserunt", "nisi", "aliquip", "deserunt", "consectetur" ], "friends": [ { "id": 0, "name": "Arline Daniels" }, { "id": 1, "name": "Joan Graham" }, { "id": 2, "name": "Randi Wright" }, { "id": 3, "name": "Bertha Holland" }, { "id": 4, "name": "Morrison Campbell" } ], "greeting": "Hello, Buchanan Burke! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482619c07491a943d6cc", "index": 464, "guid": "b751f514-c6dc-4bd6-ac0d-a77f9d29fa0c", "isActive": true, "balance": "$3,424.80", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "green", "name": "Burris Gilbert", "gender": "male", "company": "LOTRON", "email": "burrisgilbert@lotron.com", "phone": "+1 (932) 443-3189", "address": "940 Christopher Avenue, Keller, Mississippi, 4799", "about": "Magna sit anim ut voluptate magna in fugiat aliqua tempor cillum. Aute aute duis reprehenderit excepteur consectetur exercitation culpa ad id officia ullamco sunt ipsum. Minim minim proident eiusmod irure laborum incididunt. Incididunt in dolore Lorem commodo. Eu consequat mollit veniam quis aute amet laboris veniam.\r\n", "registered": "2015-03-21T07:34:58 -01:00", "latitude": -43.774294, "longitude": 89.410718, "tags": [ "amet", "nisi", "commodo", "laborum", "anim", "esse", "mollit", "id", "do", "aliqua" ], "friends": [ { "id": 0, "name": "Maricela Bryan" }, { "id": 1, "name": "Mathis Snow" }, { "id": 2, "name": "Brennan Ewing" }, { "id": 3, "name": "Haley Pacheco" }, { "id": 4, "name": "Parsons James" } ], "greeting": "Hello, Burris Gilbert! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482627f5b348cad4b6ee", "index": 465, "guid": "2f811e44-c8f3-466d-ad69-f82f8a57ff3a", "isActive": true, "balance": "$3,382.98", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "brown", "name": "Justice Cooper", "gender": "male", "company": "PLASTO", "email": "justicecooper@plasto.com", "phone": "+1 (819) 420-3585", "address": "543 Aberdeen Street, Moraida, Guam, 9414", "about": "Ut sint et anim enim voluptate Lorem deserunt consectetur aliquip duis nisi ad. Amet non cillum velit qui labore consequat nostrud commodo cillum ea dolor enim cillum dolor. Sit laborum sit est magna officia anim nisi occaecat sit pariatur in. Officia anim id ea cupidatat.\r\n", "registered": "2014-12-04T07:14:05 -01:00", "latitude": 82.174914, "longitude": -48.11418, "tags": [ "est", "quis", "id", "eu", "aute", "duis", "consequat", "esse", "cupidatat", "deserunt" ], "friends": [ { "id": 0, "name": "Cynthia Peters" }, { "id": 1, "name": "Justine Drake" }, { "id": 2, "name": "Clare Salinas" }, { "id": 3, "name": "Roman Carroll" }, { "id": 4, "name": "Yolanda Bradley" } ], "greeting": "Hello, Justice Cooper! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826a12db11828c574fb", "index": 466, "guid": "b69c88cc-feb5-4012-b1b1-8510eb62af22", "isActive": false, "balance": "$2,399.23", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Doris Castaneda", "gender": "female", "company": "ROUGHIES", "email": "doriscastaneda@roughies.com", "phone": "+1 (953) 583-3710", "address": "643 Richmond Street, Wanship, Louisiana, 1289", "about": "Voluptate ipsum ut duis labore laboris id nulla duis labore cupidatat. Do dolor excepteur incididunt consequat. Aute nisi excepteur labore aute deserunt quis ullamco voluptate et et excepteur. Proident duis ipsum nisi dolore fugiat aliquip proident aliquip culpa.\r\n", "registered": "2017-05-16T01:02:51 -02:00", "latitude": 28.634105, "longitude": -178.830775, "tags": [ "adipisicing", "est", "aute", "id", "proident", "voluptate", "minim", "nisi", "aute", "tempor" ], "friends": [ { "id": 0, "name": "Chen Morrison" }, { "id": 1, "name": "Spears Pratt" }, { "id": 2, "name": "Hogan Hammond" }, { "id": 3, "name": "Gibbs Nixon" }, { "id": 4, "name": "Norton Maldonado" } ], "greeting": "Hello, Doris Castaneda! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826da392f83c98987c6", "index": 467, "guid": "e768e4c1-fa7b-4d47-ad04-2a69c3d7812d", "isActive": true, "balance": "$1,748.11", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Cara Fleming", "gender": "female", "company": "OVOLO", "email": "carafleming@ovolo.com", "phone": "+1 (834) 503-2010", "address": "387 Seacoast Terrace, Jardine, South Dakota, 7371", "about": "Incididunt veniam irure elit anim eiusmod. Irure sunt ad est nulla deserunt eu qui qui laboris. Duis velit Lorem mollit elit tempor dolore consectetur fugiat ut aute adipisicing quis. Commodo incididunt deserunt magna excepteur ex non adipisicing velit enim quis dolor. Qui consequat voluptate quis ullamco culpa exercitation quis minim tempor commodo tempor. Ex duis anim magna cupidatat commodo.\r\n", "registered": "2014-08-30T11:01:45 -02:00", "latitude": -35.305613, "longitude": -179.070247, "tags": [ "qui", "velit", "elit", "dolor", "in", "cillum", "anim", "exercitation", "nulla", "duis" ], "friends": [ { "id": 0, "name": "Jana Wheeler" }, { "id": 1, "name": "Jewell Durham" }, { "id": 2, "name": "Garza Frank" }, { "id": 3, "name": "Paula Wilkins" }, { "id": 4, "name": "Clarice Gibson" } ], "greeting": "Hello, Cara Fleming! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b1c433b40c3c39b2", "index": 468, "guid": "4c6a1d6a-bb98-47b9-aa94-d7f39386eb5e", "isActive": true, "balance": "$1,699.28", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "green", "name": "Wolf Parsons", "gender": "male", "company": "BRISTO", "email": "wolfparsons@bristo.com", "phone": "+1 (983) 546-3258", "address": "953 Bergen Avenue, Dundee, District Of Columbia, 7154", "about": "Aliqua aute elit qui elit proident nisi ad ad culpa eu ut proident. Laboris proident eiusmod commodo nostrud qui. Sunt minim magna reprehenderit veniam occaecat ex voluptate laboris Lorem. Do id sint nisi qui adipisicing esse aliqua eiusmod sunt consequat mollit dolore.\r\n", "registered": "2014-10-13T07:36:11 -02:00", "latitude": 3.568731, "longitude": 165.346627, "tags": [ "velit", "ipsum", "non", "est", "commodo", "in", "id", "quis", "cupidatat", "ea" ], "friends": [ { "id": 0, "name": "Cassie Tucker" }, { "id": 1, "name": "Chapman Tillman" }, { "id": 2, "name": "Gomez Henson" }, { "id": 3, "name": "Carmen Lawrence" }, { "id": 4, "name": "Melisa Puckett" } ], "greeting": "Hello, Wolf Parsons! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482633963676a17aac75", "index": 469, "guid": "3e446ca0-2cc8-4544-930d-1db141aa1380", "isActive": true, "balance": "$3,466.04", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Candice Bolton", "gender": "female", "company": "COMTOUR", "email": "candicebolton@comtour.com", "phone": "+1 (816) 522-2899", "address": "804 Garnet Street, Highland, Puerto Rico, 7929", "about": "Exercitation dolor officia et ex ad sit anim in velit laboris voluptate elit laboris. Minim excepteur consequat proident exercitation. Aliquip consectetur enim tempor cupidatat sit irure dolore exercitation sunt occaecat commodo exercitation ut anim. Occaecat elit est adipisicing aliquip ullamco voluptate et commodo. Nisi adipisicing cupidatat ex reprehenderit Lorem aliquip pariatur id. Veniam dolore magna elit sunt esse deserunt. Qui aute Lorem do in non dolor aliqua ut reprehenderit.\r\n", "registered": "2015-01-08T11:38:59 -01:00", "latitude": 75.500869, "longitude": -34.75644, "tags": [ "velit", "exercitation", "officia", "sunt", "occaecat", "veniam", "consectetur", "ullamco", "et", "esse" ], "friends": [ { "id": 0, "name": "Christie Nunez" }, { "id": 1, "name": "Florine Hartman" }, { "id": 2, "name": "Barbara Velazquez" }, { "id": 3, "name": "Berta Petersen" }, { "id": 4, "name": "Henderson Fitzpatrick" } ], "greeting": "Hello, Candice Bolton! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826fc421ee977bc7363", "index": 470, "guid": "5961e033-7c28-4362-bc04-9d430ebb14ed", "isActive": false, "balance": "$1,817.72", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "brown", "name": "Gutierrez Johns", "gender": "male", "company": "NEXGENE", "email": "gutierrezjohns@nexgene.com", "phone": "+1 (994) 539-3757", "address": "617 Roder Avenue, Ernstville, Maine, 5868", "about": "Enim irure adipisicing duis velit officia veniam sint enim tempor culpa. Deserunt ipsum amet proident officia reprehenderit consectetur ut sit nisi ea officia eu eiusmod aliqua. Mollit exercitation ipsum enim deserunt cillum pariatur mollit consectetur dolor minim in aliqua. Commodo irure occaecat elit ut nostrud pariatur laboris proident culpa sit ea.\r\n", "registered": "2017-01-06T12:48:51 -01:00", "latitude": 16.989903, "longitude": -10.358117, "tags": [ "sint", "anim", "occaecat", "Lorem", "voluptate", "incididunt", "ullamco", "tempor", "mollit", "in" ], "friends": [ { "id": 0, "name": "Hammond Ware" }, { "id": 1, "name": "Phelps David" }, { "id": 2, "name": "Eaton Rios" }, { "id": 3, "name": "Shepard Evans" }, { "id": 4, "name": "Leigh Huber" } ], "greeting": "Hello, Gutierrez Johns! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826b86d6c99e8521507", "index": 471, "guid": "0252fef6-d40e-4d31-87df-5300468d1e64", "isActive": false, "balance": "$3,518.59", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Earnestine Donaldson", "gender": "female", "company": "ZENTILITY", "email": "earnestinedonaldson@zentility.com", "phone": "+1 (978) 526-3020", "address": "230 Gilmore Court, Klondike, New Jersey, 7808", "about": "Deserunt amet occaecat culpa eu est aute sint laborum et voluptate aliqua excepteur exercitation aliqua. In aliquip est ad exercitation quis occaecat esse velit tempor magna incididunt cupidatat incididunt excepteur. Ullamco eu reprehenderit cillum non proident do enim id irure consequat reprehenderit.\r\n", "registered": "2015-11-11T03:19:04 -01:00", "latitude": -53.583577, "longitude": -10.277336, "tags": [ "incididunt", "ex", "sit", "elit", "dolor", "irure", "veniam", "qui", "Lorem", "aute" ], "friends": [ { "id": 0, "name": "Roth Moore" }, { "id": 1, "name": "Finch Rollins" }, { "id": 2, "name": "Melba Grimes" }, { "id": 3, "name": "Jan Stevens" }, { "id": 4, "name": "Marietta Blake" } ], "greeting": "Hello, Earnestine Donaldson! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482666a5fe4abacaa3d1", "index": 472, "guid": "d9fec134-65c7-48f4-9ef4-c1fad0feaf02", "isActive": true, "balance": "$1,569.68", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Fanny Cunningham", "gender": "female", "company": "NSPIRE", "email": "fannycunningham@nspire.com", "phone": "+1 (832) 489-3735", "address": "442 Dodworth Street, Courtland, Michigan, 1067", "about": "Voluptate aliquip ex veniam ut voluptate eu. Ipsum tempor cillum aute laboris sunt cupidatat voluptate Lorem excepteur incididunt. Veniam mollit culpa commodo laborum ad magna ad amet eu aliquip adipisicing. Nostrud veniam consectetur dolore nulla consectetur cillum nisi cillum mollit officia. Ut minim aliqua et sint irure occaecat. Et consequat nisi ad ipsum tempor. Ut sit ut et et veniam nisi est mollit mollit aute.\r\n", "registered": "2017-07-23T09:32:50 -02:00", "latitude": -22.71582, "longitude": 50.411994, "tags": [ "nulla", "non", "labore", "ipsum", "culpa", "elit", "incididunt", "laborum", "velit", "consequat" ], "friends": [ { "id": 0, "name": "Morris Gallegos" }, { "id": 1, "name": "Minnie Zamora" }, { "id": 2, "name": "Alisa Kerr" }, { "id": 3, "name": "Hollie Hickman" }, { "id": 4, "name": "Roslyn Johnston" } ], "greeting": "Hello, Fanny Cunningham! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ad45277e22319797", "index": 473, "guid": "ba0a17d0-011d-4780-8263-df59859929bf", "isActive": true, "balance": "$2,429.46", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "green", "name": "Lela Delgado", "gender": "female", "company": "FOSSIEL", "email": "leladelgado@fossiel.com", "phone": "+1 (853) 548-2978", "address": "434 Mermaid Avenue, Wildwood, Rhode Island, 8773", "about": "Velit officia eu voluptate pariatur anim id commodo velit reprehenderit in. Commodo commodo incididunt duis dolore cillum enim cillum. Duis ipsum in ipsum veniam ut aliqua nisi. Deserunt tempor quis aliquip eiusmod quis ad proident magna cupidatat ullamco ex. Esse eu duis sunt mollit. Enim consectetur adipisicing sit ipsum deserunt ipsum nostrud in mollit incididunt adipisicing deserunt. Elit officia excepteur duis qui cillum incididunt enim culpa quis.\r\n", "registered": "2015-11-29T12:11:51 -01:00", "latitude": 19.590962, "longitude": -169.102728, "tags": [ "sit", "adipisicing", "duis", "sunt", "labore", "est", "nulla", "quis", "qui", "eu" ], "friends": [ { "id": 0, "name": "Eileen Dunlap" }, { "id": 1, "name": "Cain Bush" }, { "id": 2, "name": "Witt Rowland" }, { "id": 3, "name": "Cline Walter" }, { "id": 4, "name": "Madge Dawson" } ], "greeting": "Hello, Lela Delgado! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826325598e76014a5f3", "index": 474, "guid": "7dc3c21c-51f0-4e7e-bec1-93f3701b9ae2", "isActive": false, "balance": "$2,416.23", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Compton Bass", "gender": "male", "company": "IPLAX", "email": "comptonbass@iplax.com", "phone": "+1 (830) 544-2144", "address": "216 Williamsburg Street, Stagecoach, Kansas, 3783", "about": "Quis esse et velit id labore velit aute qui ullamco adipisicing minim dolore in ut. Cupidatat nisi voluptate nisi quis eu ad dolor do elit minim ad minim consectetur sint. Eiusmod consectetur aliquip occaecat mollit. Officia laboris ad pariatur voluptate esse eu.\r\n", "registered": "2017-10-23T09:16:47 -02:00", "latitude": -68.637739, "longitude": 6.239222, "tags": [ "adipisicing", "cillum", "ex", "labore", "est", "ea", "ad", "aliquip", "laborum", "minim" ], "friends": [ { "id": 0, "name": "Rojas Brewer" }, { "id": 1, "name": "Noel Wallace" }, { "id": 2, "name": "Deanne Mcconnell" }, { "id": 3, "name": "Goodman Bates" }, { "id": 4, "name": "Burt Johnson" } ], "greeting": "Hello, Compton Bass! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48267c07267290c4e91e", "index": 475, "guid": "a36cddff-8c05-4f08-9532-f5819c4ef365", "isActive": false, "balance": "$2,805.33", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Joni Acevedo", "gender": "female", "company": "GINK", "email": "joniacevedo@gink.com", "phone": "+1 (810) 491-3602", "address": "380 Jamison Lane, Veguita, West Virginia, 9900", "about": "Aliqua deserunt sit laboris anim ad enim nisi laboris sit dolor ad consequat. Deserunt consectetur incididunt consectetur ea esse nostrud duis veniam labore in ex sint. Enim cupidatat non duis deserunt non.\r\n", "registered": "2016-11-05T03:33:10 -01:00", "latitude": -55.781705, "longitude": -59.257593, "tags": [ "ipsum", "eu", "mollit", "commodo", "eiusmod", "pariatur", "dolor", "mollit", "occaecat", "velit" ], "friends": [ { "id": 0, "name": "Tonia Foreman" }, { "id": 1, "name": "Sykes Crosby" }, { "id": 2, "name": "Charmaine Day" }, { "id": 3, "name": "Turner Reilly" }, { "id": 4, "name": "Cecelia Horton" } ], "greeting": "Hello, Joni Acevedo! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826ea307193b12e77dd", "index": 476, "guid": "cb00c993-f061-4a46-8e8b-4c7ab2c164dd", "isActive": false, "balance": "$2,649.61", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "brown", "name": "Meyer Chang", "gender": "male", "company": "COMTEST", "email": "meyerchang@comtest.com", "phone": "+1 (817) 469-3475", "address": "712 Moultrie Street, Bellfountain, American Samoa, 4249", "about": "Culpa culpa amet magna sint laboris aliqua. Sint labore proident est ex deserunt. Culpa magna nostrud fugiat dolor.\r\n", "registered": "2017-01-01T04:25:44 -01:00", "latitude": 16.68295, "longitude": -128.818485, "tags": [ "labore", "duis", "commodo", "cillum", "pariatur", "proident", "do", "minim", "eiusmod", "laboris" ], "friends": [ { "id": 0, "name": "Irwin Gonzales" }, { "id": 1, "name": "Holder Rivera" }, { "id": 2, "name": "Gretchen Noble" }, { "id": 3, "name": "Webb Underwood" }, { "id": 4, "name": "Singleton Sandoval" } ], "greeting": "Hello, Meyer Chang! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48269aeafdf46fee008d", "index": 477, "guid": "a7b3b81b-232a-4190-9ab8-0419a64ad7a1", "isActive": true, "balance": "$3,822.61", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "brown", "name": "Pitts Allen", "gender": "male", "company": "ATGEN", "email": "pittsallen@atgen.com", "phone": "+1 (825) 536-3297", "address": "563 Fair Street, Northchase, Maryland, 5498", "about": "Occaecat et veniam laborum non et magna laborum laborum laborum in adipisicing excepteur. Laboris non ex laborum magna mollit mollit labore sunt Lorem tempor. Et fugiat ex mollit nulla enim velit culpa.\r\n", "registered": "2014-12-09T08:57:27 -01:00", "latitude": 76.649726, "longitude": -152.512642, "tags": [ "nisi", "dolore", "eu", "nostrud", "amet", "tempor", "dolore", "fugiat", "eiusmod", "mollit" ], "friends": [ { "id": 0, "name": "Corine Frost" }, { "id": 1, "name": "Martin George" }, { "id": 2, "name": "Sheryl Douglas" }, { "id": 3, "name": "Dudley Ramirez" }, { "id": 4, "name": "Joanna Burris" } ], "greeting": "Hello, Pitts Allen! You have 7 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48267a68d12a0aafb84a", "index": 478, "guid": "79cf2bfa-4b4e-4344-b328-3229c3a4e550", "isActive": false, "balance": "$1,336.50", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "brown", "name": "Hickman Hayes", "gender": "male", "company": "IZZBY", "email": "hickmanhayes@izzby.com", "phone": "+1 (885) 552-2876", "address": "522 Herzl Street, Dellview, California, 8267", "about": "Nisi commodo veniam id in elit in reprehenderit ad veniam quis. Aute occaecat esse nostrud adipisicing do cupidatat duis laboris labore et veniam nisi occaecat sit. Ea ut excepteur labore magna ex eu duis et ex officia Lorem ullamco eu Lorem. Minim deserunt aliquip anim ad anim. Voluptate culpa dolor nostrud consectetur minim dolore.\r\n", "registered": "2016-04-25T01:13:49 -02:00", "latitude": 80.691365, "longitude": -19.587859, "tags": [ "non", "mollit", "adipisicing", "cillum", "do", "elit", "elit", "nostrud", "velit", "reprehenderit" ], "friends": [ { "id": 0, "name": "Charlotte Pope" }, { "id": 1, "name": "Gwendolyn Gutierrez" }, { "id": 2, "name": "Cora Jensen" }, { "id": 3, "name": "Carver Stewart" }, { "id": 4, "name": "Colette Landry" } ], "greeting": "Hello, Hickman Hayes! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482695fef44e89710956", "index": 479, "guid": "1ede24e1-16f9-45ff-a93d-ddc1acf55dde", "isActive": false, "balance": "$2,591.17", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Maryanne Guerra", "gender": "female", "company": "QUOTEZART", "email": "maryanneguerra@quotezart.com", "phone": "+1 (943) 490-3220", "address": "486 Ferry Place, Knowlton, Utah, 4339", "about": "Minim duis esse excepteur aliquip laborum ex anim mollit commodo id culpa. Non ad elit duis ea minim nulla anim deserunt. Deserunt anim anim cupidatat adipisicing. Excepteur occaecat sunt minim in pariatur reprehenderit. Dolore consectetur amet reprehenderit dolore labore. Minim duis exercitation est nisi do aliquip quis.\r\n", "registered": "2016-12-29T09:22:13 -01:00", "latitude": -9.419909, "longitude": -72.789466, "tags": [ "do", "culpa", "dolor", "irure", "voluptate", "cillum", "nostrud", "exercitation", "anim", "ullamco" ], "friends": [ { "id": 0, "name": "Bowman Knight" }, { "id": 1, "name": "Nell Goff" }, { "id": 2, "name": "Twila Fox" }, { "id": 3, "name": "Camacho Foley" }, { "id": 4, "name": "Gilbert Carney" } ], "greeting": "Hello, Maryanne Guerra! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48267adace43ec252434", "index": 480, "guid": "4651dd33-370e-449d-b44d-fa037c5d3e0e", "isActive": true, "balance": "$3,519.81", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "blue", "name": "Saundra Richards", "gender": "female", "company": "ENJOLA", "email": "saundrarichards@enjola.com", "phone": "+1 (927) 464-2173", "address": "758 Throop Avenue, Zortman, Iowa, 4786", "about": "Nisi ad veniam laboris do aliquip ea Lorem magna tempor reprehenderit dolore officia excepteur. Consectetur culpa anim sint id. Culpa ea commodo magna aliqua et magna ut duis proident nostrud quis quis proident Lorem. Esse laboris nisi non ullamco minim consectetur exercitation.\r\n", "registered": "2017-01-22T04:13:18 -01:00", "latitude": -24.431471, "longitude": -63.075964, "tags": [ "labore", "magna", "proident", "et", "consectetur", "commodo", "adipisicing", "dolore", "nisi", "officia" ], "friends": [ { "id": 0, "name": "Chandra Mills" }, { "id": 1, "name": "George Adams" }, { "id": 2, "name": "Sharlene Mccormick" }, { "id": 3, "name": "Ward Estrada" }, { "id": 4, "name": "Santos Craig" } ], "greeting": "Hello, Saundra Richards! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826b44ad021a0a92c22", "index": 481, "guid": "352b9807-f2bf-4251-a3fb-d7846244770d", "isActive": false, "balance": "$1,989.22", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Hall Coffey", "gender": "male", "company": "PORTICO", "email": "hallcoffey@portico.com", "phone": "+1 (828) 428-2594", "address": "943 Homecrest Avenue, Lemoyne, North Dakota, 6834", "about": "Aute consectetur ex culpa velit laboris id cillum in laborum irure eu dolore ut sit. Ad pariatur nostrud pariatur pariatur est quis pariatur enim minim culpa. Ipsum et commodo officia eiusmod dolor.\r\n", "registered": "2017-11-09T02:34:03 -01:00", "latitude": -25.882363, "longitude": 120.363075, "tags": [ "reprehenderit", "cupidatat", "et", "irure", "aliquip", "enim", "occaecat", "labore", "commodo", "culpa" ], "friends": [ { "id": 0, "name": "Hamilton Wiggins" }, { "id": 1, "name": "Hernandez Daugherty" }, { "id": 2, "name": "Harper Hines" }, { "id": 3, "name": "Latoya Brennan" }, { "id": 4, "name": "Ferrell Yates" } ], "greeting": "Hello, Hall Coffey! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482683b58c1dd2cbc44a", "index": 482, "guid": "0041f92c-3595-4f2e-8118-bb9837108092", "isActive": false, "balance": "$2,159.36", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "brown", "name": "Cheryl Jacobs", "gender": "female", "company": "LOVEPAD", "email": "cheryljacobs@lovepad.com", "phone": "+1 (875) 521-2005", "address": "248 Havemeyer Street, Brazos, Kentucky, 1012", "about": "Et ea veniam amet nisi labore enim elit. Mollit eu laborum nulla fugiat qui mollit dolor. Reprehenderit non sint proident deserunt esse incididunt minim. Reprehenderit irure excepteur nisi qui veniam magna. Lorem ipsum est consectetur eu deserunt ullamco dolor labore.\r\n", "registered": "2015-05-02T10:01:05 -02:00", "latitude": -80.231776, "longitude": -105.060731, "tags": [ "aliquip", "velit", "minim", "anim", "nisi", "fugiat", "officia", "elit", "non", "fugiat" ], "friends": [ { "id": 0, "name": "Lilian Best" }, { "id": 1, "name": "Ochoa Morin" }, { "id": 2, "name": "Mcgee Higgins" }, { "id": 3, "name": "Lacy Robinson" }, { "id": 4, "name": "Nita Greer" } ], "greeting": "Hello, Cheryl Jacobs! You have 6 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826861454f7bba507c5", "index": 483, "guid": "7f723131-5d01-4270-ad36-a34a05fcf82d", "isActive": false, "balance": "$1,585.52", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "brown", "name": "Claudine Mcknight", "gender": "female", "company": "GEOFORMA", "email": "claudinemcknight@geoforma.com", "phone": "+1 (840) 504-3311", "address": "990 Norman Avenue, Springdale, Colorado, 3510", "about": "Est adipisicing labore anim elit. Nostrud adipisicing nulla velit enim mollit irure sunt pariatur reprehenderit Lorem. In non eu dolor commodo culpa fugiat. Non consequat tempor consequat cupidatat duis officia est. Ea magna duis voluptate esse cupidatat. Anim aliquip magna ut magna deserunt deserunt voluptate enim officia enim.\r\n", "registered": "2017-11-17T04:36:37 -01:00", "latitude": -15.356244, "longitude": -163.621088, "tags": [ "aute", "nostrud", "quis", "tempor", "excepteur", "incididunt", "tempor", "ad", "dolore", "nisi" ], "friends": [ { "id": 0, "name": "Terri Harper" }, { "id": 1, "name": "Hurley Whitehead" }, { "id": 2, "name": "Flowers Chase" }, { "id": 3, "name": "Kristy Wood" }, { "id": 4, "name": "Dionne Eaton" } ], "greeting": "Hello, Claudine Mcknight! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48268fd6b6a1e8623678", "index": 484, "guid": "19130f42-e318-476b-934a-45f89327cd4a", "isActive": true, "balance": "$1,977.95", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "green", "name": "Odessa Payne", "gender": "female", "company": "BEADZZA", "email": "odessapayne@beadzza.com", "phone": "+1 (885) 518-2760", "address": "123 Highlawn Avenue, Websterville, New Hampshire, 7284", "about": "Ullamco mollit consequat ex id minim Lorem culpa duis. Culpa excepteur ea velit duis esse non velit ullamco consequat ullamco dolore qui est excepteur. Laborum velit Lorem anim et esse nisi velit eiusmod nulla sint enim. Fugiat excepteur enim nulla consequat incididunt esse exercitation est nisi.\r\n", "registered": "2014-07-21T10:23:53 -02:00", "latitude": 28.480944, "longitude": 16.039825, "tags": [ "amet", "dolor", "ex", "consequat", "labore", "aliqua", "officia", "non", "pariatur", "ex" ], "friends": [ { "id": 0, "name": "Hope Barrett" }, { "id": 1, "name": "Latisha Pierce" }, { "id": 2, "name": "Osborn Lester" }, { "id": 3, "name": "Farmer Farley" }, { "id": 4, "name": "Beverley Trevino" } ], "greeting": "Hello, Odessa Payne! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826efe6fa0e35cea3fc", "index": 485, "guid": "f7041a6a-090d-4bbc-8f7d-2a0e80d37b27", "isActive": false, "balance": "$2,595.70", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "blue", "name": "Blanchard Cummings", "gender": "male", "company": "AQUAFIRE", "email": "blanchardcummings@aquafire.com", "phone": "+1 (968) 504-2565", "address": "191 Fuller Place, Wakarusa, Wisconsin, 8701", "about": "Dolor enim qui aliqua veniam duis dolore exercitation esse id adipisicing do aliquip. Minim excepteur nostrud ea enim do reprehenderit nulla pariatur deserunt duis aliquip consectetur adipisicing consectetur. Nisi excepteur eu sunt adipisicing sint sint veniam deserunt minim anim amet. Ullamco aute occaecat ut magna laboris aliqua officia ipsum do. Ipsum eu id pariatur mollit duis dolore et irure excepteur qui laboris sit incididunt.\r\n", "registered": "2018-01-02T11:30:18 -01:00", "latitude": -48.834203, "longitude": -68.436502, "tags": [ "magna", "tempor", "enim", "ipsum", "qui", "veniam", "tempor", "quis", "est", "labore" ], "friends": [ { "id": 0, "name": "Erin Buckley" }, { "id": 1, "name": "Forbes Gilmore" }, { "id": 2, "name": "Bette Curry" }, { "id": 3, "name": "Wilcox Terrell" }, { "id": 4, "name": "Francesca Weiss" } ], "greeting": "Hello, Blanchard Cummings! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48267029d261df51eaaf", "index": 486, "guid": "1a2a4f1e-49b3-4d40-9728-a04ce686710a", "isActive": true, "balance": "$2,183.91", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "brown", "name": "Trisha Huffman", "gender": "female", "company": "ZAPHIRE", "email": "trishahuffman@zaphire.com", "phone": "+1 (943) 498-3899", "address": "329 Haring Street, Campo, Idaho, 9398", "about": "Aliqua nostrud officia voluptate voluptate laborum id proident reprehenderit et elit aliquip pariatur fugiat. Eiusmod officia mollit quis est. Tempor fugiat aliquip voluptate commodo fugiat exercitation ad culpa sit enim.\r\n", "registered": "2015-02-23T12:25:33 -01:00", "latitude": -26.551479, "longitude": 6.990944, "tags": [ "laboris", "aute", "cillum", "ea", "veniam", "velit", "dolor", "ut", "officia", "fugiat" ], "friends": [ { "id": 0, "name": "Cohen Rose" }, { "id": 1, "name": "Ronda Cooke" }, { "id": 2, "name": "Aline Berg" }, { "id": 3, "name": "Clark Wyatt" }, { "id": 4, "name": "Mccall Barron" } ], "greeting": "Hello, Trisha Huffman! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48264db66f4294743c9e", "index": 487, "guid": "1b47bdff-9e9e-4660-8d69-dc665373b40b", "isActive": false, "balance": "$2,108.81", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "brown", "name": "Corina Little", "gender": "female", "company": "TECHADE", "email": "corinalittle@techade.com", "phone": "+1 (979) 469-3624", "address": "678 Montgomery Street, Westwood, Georgia, 7121", "about": "Dolore irure commodo magna excepteur occaecat occaecat. Magna proident ipsum duis ex irure cillum labore id deserunt occaecat nostrud. Est duis voluptate reprehenderit Lorem esse ad pariatur et aute incididunt magna cupidatat mollit nisi. Eiusmod nisi consectetur ad tempor et labore.\r\n", "registered": "2015-05-02T09:20:34 -02:00", "latitude": 21.008001, "longitude": -132.189437, "tags": [ "laboris", "exercitation", "excepteur", "ullamco", "fugiat", "ullamco", "proident", "cupidatat", "esse", "occaecat" ], "friends": [ { "id": 0, "name": "Huffman Villarreal" }, { "id": 1, "name": "Carpenter Franks" }, { "id": 2, "name": "Mccoy Whitley" }, { "id": 3, "name": "Katherine Reed" }, { "id": 4, "name": "Cornelia Shaw" } ], "greeting": "Hello, Corina Little! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826e6cd372c275c1c73", "index": 488, "guid": "150d9552-887f-4f0e-bf74-612fc8dbccd9", "isActive": false, "balance": "$3,696.29", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "brown", "name": "Dyer Brock", "gender": "male", "company": "GRONK", "email": "dyerbrock@gronk.com", "phone": "+1 (883) 579-2434", "address": "730 Lacon Court, Maury, Virgin Islands, 4622", "about": "Excepteur cillum ea consectetur excepteur. Sint ex commodo consequat do. Exercitation elit esse mollit nulla commodo ut adipisicing aliquip. Pariatur sunt mollit sint nostrud ut dolor officia. Esse dolore elit officia nostrud ad esse nisi do ea exercitation ut voluptate quis. Est ullamco occaecat veniam culpa velit occaecat aliquip.\r\n", "registered": "2016-09-06T07:42:18 -02:00", "latitude": -6.180194, "longitude": 167.096978, "tags": [ "adipisicing", "reprehenderit", "culpa", "ea", "nostrud", "ut", "aliqua", "amet", "excepteur", "aliquip" ], "friends": [ { "id": 0, "name": "Clarissa Randall" }, { "id": 1, "name": "Nellie Lindsay" }, { "id": 2, "name": "Louella Waller" }, { "id": 3, "name": "Edna Fischer" }, { "id": 4, "name": "Tasha Sears" } ], "greeting": "Hello, Dyer Brock! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482639b1082f60628526", "index": 489, "guid": "24a89505-13a8-4dc7-aa60-0e62f51af4eb", "isActive": true, "balance": "$3,635.20", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "brown", "name": "Olga Mcclure", "gender": "female", "company": "PHARMACON", "email": "olgamcclure@pharmacon.com", "phone": "+1 (991) 476-3523", "address": "793 Hegeman Avenue, Trexlertown, Minnesota, 7137", "about": "Ad enim culpa cillum anim ut duis exercitation ex. Ad Lorem incididunt consectetur minim culpa labore cupidatat incididunt. Sit veniam et magna voluptate. Aliqua do esse amet dolor occaecat aliquip nostrud amet esse id dolor ut. Nisi sit velit ullamco aliqua aliqua velit anim ullamco Lorem culpa tempor mollit aliqua. Aute fugiat aute sint pariatur dolore in eiusmod ea eiusmod enim officia incididunt.\r\n", "registered": "2016-03-21T01:35:16 -01:00", "latitude": -35.304013, "longitude": 70.564164, "tags": [ "non", "non", "magna", "voluptate", "est", "incididunt", "cillum", "occaecat", "aliqua", "eu" ], "friends": [ { "id": 0, "name": "Juliette Hansen" }, { "id": 1, "name": "Montgomery Vega" }, { "id": 2, "name": "Winters Joyce" }, { "id": 3, "name": "Socorro Ratliff" }, { "id": 4, "name": "Lee Heath" } ], "greeting": "Hello, Olga Mcclure! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48269173826906cf6232", "index": 490, "guid": "cc7a47f8-cd0e-4d03-bc90-b96f5b132025", "isActive": true, "balance": "$3,852.50", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "blue", "name": "Jane Reyes", "gender": "female", "company": "SPACEWAX", "email": "janereyes@spacewax.com", "phone": "+1 (927) 408-2015", "address": "449 Dekoven Court, Muir, South Carolina, 9851", "about": "Minim elit dolor aliqua duis pariatur. Nulla culpa adipisicing non officia eu eu ex nisi voluptate commodo culpa eu. Ad ullamco in minim et ullamco laborum officia. Officia pariatur qui duis culpa consequat amet minim. Id laboris pariatur ut pariatur aute qui fugiat deserunt elit proident.\r\n", "registered": "2015-10-26T02:04:56 -01:00", "latitude": 65.482398, "longitude": 134.046961, "tags": [ "exercitation", "velit", "duis", "quis", "ut", "nisi", "dolor", "nostrud", "sint", "est" ], "friends": [ { "id": 0, "name": "Ellis Christian" }, { "id": 1, "name": "Ayers Shannon" }, { "id": 2, "name": "Savannah Soto" }, { "id": 3, "name": "Bernice Short" }, { "id": 4, "name": "Mooney Downs" } ], "greeting": "Hello, Jane Reyes! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826b9ebb45acce5e9ae", "index": 491, "guid": "a1120aad-90d5-4c1f-a492-979fb03d07ff", "isActive": true, "balance": "$1,934.99", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Combs Hendricks", "gender": "male", "company": "SUPREMIA", "email": "combshendricks@supremia.com", "phone": "+1 (943) 552-3229", "address": "160 Kenilworth Place, Omar, Northern Mariana Islands, 6728", "about": "Deserunt cillum nisi culpa ea duis quis enim consequat nostrud velit irure. Deserunt laborum eiusmod incididunt exercitation ipsum et. Commodo officia eiusmod esse qui incididunt culpa dolore ullamco culpa. Ex magna nulla ipsum consectetur anim labore.\r\n", "registered": "2014-03-24T06:32:31 -01:00", "latitude": -19.373148, "longitude": -120.222576, "tags": [ "culpa", "pariatur", "adipisicing", "minim", "voluptate", "minim", "ex", "amet", "non", "ullamco" ], "friends": [ { "id": 0, "name": "Josie Henry" }, { "id": 1, "name": "Kelly Mckenzie" }, { "id": 2, "name": "Obrien Mason" }, { "id": 3, "name": "Erma Head" }, { "id": 4, "name": "Juana Williamson" } ], "greeting": "Hello, Combs Hendricks! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826cf764e5129448123", "index": 492, "guid": "1a45e810-8296-4018-89e7-b2c6baaf9ebc", "isActive": true, "balance": "$1,981.48", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Simmons Coleman", "gender": "male", "company": "QUONK", "email": "simmonscoleman@quonk.com", "phone": "+1 (913) 507-3470", "address": "934 Minna Street, Villarreal, Pennsylvania, 6449", "about": "Amet amet cillum dolore pariatur reprehenderit nulla nostrud amet Lorem cupidatat duis ea ipsum amet. Aliqua do duis nostrud dolore pariatur ex ut officia ipsum. In eu magna fugiat in esse duis officia veniam dolor pariatur. Magna non ex exercitation non ad. Proident ut do aliqua enim qui dolore ut qui velit dolor reprehenderit occaecat sit anim. Qui elit culpa fugiat minim. Dolor mollit exercitation ex in cillum.\r\n", "registered": "2017-07-14T04:34:29 -02:00", "latitude": -33.056931, "longitude": 128.393759, "tags": [ "eiusmod", "anim", "laborum", "officia", "magna", "do", "do", "deserunt", "magna", "deserunt" ], "friends": [ { "id": 0, "name": "Harrington Nielsen" }, { "id": 1, "name": "Pate Rosario" }, { "id": 2, "name": "Lucinda Livingston" }, { "id": 3, "name": "Mclean Beck" }, { "id": 4, "name": "Miles Williams" } ], "greeting": "Hello, Simmons Coleman! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826116e714695f57324", "index": 493, "guid": "286d1c21-3763-4d4b-bbcf-b09a5d470037", "isActive": false, "balance": "$1,615.90", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "blue", "name": "Mcdowell Buck", "gender": "male", "company": "RAMEON", "email": "mcdowellbuck@rameon.com", "phone": "+1 (990) 525-3757", "address": "670 Stoddard Place, Sattley, Arkansas, 4240", "about": "Reprehenderit esse anim laboris laboris aliqua ullamco irure ullamco pariatur pariatur reprehenderit mollit. Anim nostrud dolore do labore esse adipisicing proident eu. Laborum mollit Lorem ad enim. Nulla exercitation nisi excepteur sint elit sunt ea Lorem.\r\n", "registered": "2017-04-18T08:38:56 -02:00", "latitude": 74.929414, "longitude": 175.318746, "tags": [ "ex", "nulla", "irure", "laboris", "irure", "labore", "ut", "dolor", "nisi", "eiusmod" ], "friends": [ { "id": 0, "name": "Hallie Murphy" }, { "id": 1, "name": "Laurel Bauer" }, { "id": 2, "name": "Annie Whitfield" }, { "id": 3, "name": "Sims Dudley" }, { "id": 4, "name": "Glenn Klein" } ], "greeting": "Hello, Mcdowell Buck! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48267795609d21638488", "index": 494, "guid": "ac021465-c536-4158-9551-a2a24fd9badd", "isActive": true, "balance": "$3,877.59", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "brown", "name": "Connie Simon", "gender": "female", "company": "NETERIA", "email": "conniesimon@neteria.com", "phone": "+1 (886) 511-2823", "address": "184 Albemarle Road, Sylvanite, Palau, 5955", "about": "Nulla aliqua commodo nostrud eu. Enim eiusmod nulla non exercitation laborum pariatur elit velit. Incididunt cupidatat in occaecat ullamco incididunt nisi reprehenderit officia sunt consectetur incididunt enim enim esse. Cupidatat sunt proident exercitation nisi qui. Fugiat occaecat aute fugiat occaecat ex. Irure ex mollit elit aliquip mollit est proident ex proident dolore est qui pariatur voluptate. Esse exercitation pariatur sit proident nulla qui laborum.\r\n", "registered": "2014-05-05T10:26:27 -02:00", "latitude": -29.079516, "longitude": -45.178985, "tags": [ "esse", "sint", "et", "qui", "ad", "incididunt", "ea", "nostrud", "nulla", "eiusmod" ], "friends": [ { "id": 0, "name": "Lancaster Finley" }, { "id": 1, "name": "Walker Fowler" }, { "id": 2, "name": "Mitzi Stanley" }, { "id": 3, "name": "Bray Henderson" }, { "id": 4, "name": "Gena Avila" } ], "greeting": "Hello, Connie Simon! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f717e38c4f0d1d47", "index": 495, "guid": "85e4c38b-fa49-4d62-9b0f-3ffbb3ca6f00", "isActive": true, "balance": "$1,350.71", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "brown", "name": "Valerie Reynolds", "gender": "female", "company": "OVERFORK", "email": "valeriereynolds@overfork.com", "phone": "+1 (960) 425-2407", "address": "881 Terrace Place, Longbranch, Connecticut, 9412", "about": "Mollit deserunt labore ut nostrud excepteur nulla id excepteur sit id. In anim est incididunt velit incididunt laborum officia in occaecat. Ut excepteur dolor reprehenderit adipisicing nisi exercitation ipsum duis minim amet.\r\n", "registered": "2015-06-24T06:42:22 -02:00", "latitude": 41.276199, "longitude": -153.051452, "tags": [ "duis", "velit", "amet", "consequat", "adipisicing", "exercitation", "magna", "cillum", "est", "occaecat" ], "friends": [ { "id": 0, "name": "Maldonado Frederick" }, { "id": 1, "name": "Farley Walsh" }, { "id": 2, "name": "Branch Bowman" }, { "id": 3, "name": "Esther Vargas" }, { "id": 4, "name": "Cabrera Stokes" } ], "greeting": "Hello, Valerie Reynolds! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826fd3a221bbcc69b49", "index": 496, "guid": "f4dcf861-6aa3-4417-a1c7-db02dbc25d30", "isActive": true, "balance": "$3,644.34", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "green", "name": "Marie Lewis", "gender": "female", "company": "QUILCH", "email": "marielewis@quilch.com", "phone": "+1 (800) 453-3199", "address": "763 Locust Street, Dale, North Carolina, 6497", "about": "Voluptate tempor cillum eiusmod officia consectetur consequat duis sint velit velit aliquip culpa veniam. Qui id ad culpa ad do ex ullamco minim in labore ex. In amet ipsum id laborum mollit ullamco ipsum deserunt. Occaecat deserunt ex dolore sit magna eiusmod est magna nostrud laboris. Deserunt quis reprehenderit commodo cillum non cillum do. Commodo cillum laborum exercitation adipisicing ipsum. Cupidatat proident laborum labore cupidatat in id exercitation consectetur in dolor irure.\r\n", "registered": "2016-05-29T11:45:40 -02:00", "latitude": -77.937356, "longitude": -110.103704, "tags": [ "consectetur", "cupidatat", "mollit", "aute", "proident", "excepteur", "adipisicing", "fugiat", "enim", "occaecat" ], "friends": [ { "id": 0, "name": "Flores Vazquez" }, { "id": 1, "name": "Celia Gates" }, { "id": 2, "name": "Lane Espinoza" }, { "id": 3, "name": "Jillian Collier" }, { "id": 4, "name": "Irma Riley" } ], "greeting": "Hello, Marie Lewis! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48268ba88de7f07ddbcd", "index": 497, "guid": "1d9aeb82-eb16-4197-9c19-488c2e131b00", "isActive": true, "balance": "$3,592.77", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Mona Sexton", "gender": "female", "company": "TUBALUM", "email": "monasexton@tubalum.com", "phone": "+1 (943) 421-2167", "address": "244 Grove Street, Brady, Missouri, 2573", "about": "Quis incididunt exercitation eiusmod tempor veniam commodo officia proident aliqua dolore mollit labore. Occaecat minim mollit consectetur qui do eu enim quis ipsum. Non tempor sunt aliqua esse elit sint adipisicing. Nostrud consectetur non minim voluptate enim. Tempor Lorem velit ex elit eiusmod cupidatat consectetur sint non non.\r\n", "registered": "2016-01-04T01:15:36 -01:00", "latitude": 55.341632, "longitude": -127.497529, "tags": [ "consequat", "nostrud", "consectetur", "exercitation", "consectetur", "dolore", "amet", "officia", "exercitation", "elit" ], "friends": [ { "id": 0, "name": "Dorthy Davis" }, { "id": 1, "name": "Cardenas Park" }, { "id": 2, "name": "Frost Kirk" }, { "id": 3, "name": "Torres Mccullough" }, { "id": 4, "name": "Tyler Savage" } ], "greeting": "Hello, Mona Sexton! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482608a1df887390054e", "index": 498, "guid": "8cc801a4-66dc-42c3-94da-00b83d312062", "isActive": true, "balance": "$2,653.81", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Janelle Spencer", "gender": "female", "company": "TURNABOUT", "email": "janellespencer@turnabout.com", "phone": "+1 (840) 438-3818", "address": "338 Woods Place, Orason, Ohio, 9310", "about": "Non sint reprehenderit minim labore ipsum consectetur irure consectetur dolore ipsum. Magna anim magna pariatur elit nisi nostrud deserunt ut Lorem reprehenderit consequat ex deserunt id. Est Lorem laborum velit quis non quis occaecat dolor minim est non aliquip.\r\n", "registered": "2016-07-21T04:39:51 -02:00", "latitude": 8.346471, "longitude": 173.94284, "tags": [ "non", "laboris", "proident", "sint", "in", "excepteur", "cillum", "dolore", "aute", "reprehenderit" ], "friends": [ { "id": 0, "name": "Rosario White" }, { "id": 1, "name": "Cooley Holloway" }, { "id": 2, "name": "Hampton Randolph" }, { "id": 3, "name": "Chan Caldwell" }, { "id": 4, "name": "Petra Paul" } ], "greeting": "Hello, Janelle Spencer! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48264a7e606a8c334594", "index": 499, "guid": "43b9b0c7-1588-4c35-8fdf-b51947e17de3", "isActive": false, "balance": "$1,070.96", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "blue", "name": "Cruz Mann", "gender": "male", "company": "ZILLIDIUM", "email": "cruzmann@zillidium.com", "phone": "+1 (965) 566-3831", "address": "763 Monroe Street, Bison, Arizona, 6337", "about": "Ullamco id in Lorem voluptate dolor. Labore minim proident duis minim laboris enim mollit nostrud consectetur. Consequat do in laborum dolor amet ex minim sunt non. Lorem consequat sit aliquip nostrud anim in minim ex est minim adipisicing. Mollit officia id fugiat Lorem et nisi. Ullamco laborum adipisicing nulla consectetur ullamco dolor ex veniam pariatur ex. Voluptate irure anim exercitation elit do ipsum voluptate ex.\r\n", "registered": "2016-07-30T04:30:45 -02:00", "latitude": 15.089073, "longitude": -68.768151, "tags": [ "velit", "velit", "et", "voluptate", "enim", "do", "do", "aliquip", "esse", "anim" ], "friends": [ { "id": 0, "name": "Barlow Burton" }, { "id": 1, "name": "Kim Haney" }, { "id": 2, "name": "Valenzuela Hudson" }, { "id": 3, "name": "Martha Montgomery" }, { "id": 4, "name": "Peterson Nelson" } ], "greeting": "Hello, Cruz Mann! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826f69153087bd8e0d2", "index": 500, "guid": "12b299b8-fa72-450a-9141-d8e2dc7ec315", "isActive": true, "balance": "$1,714.02", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "blue", "name": "Calderon Patrick", "gender": "male", "company": "ISOLOGICS", "email": "calderonpatrick@isologics.com", "phone": "+1 (968) 536-3734", "address": "193 Hendrickson Place, Norwood, Montana, 1960", "about": "In deserunt velit non occaecat do sint eiusmod culpa proident. Ullamco occaecat nostrud incididunt nulla pariatur. Commodo incididunt exercitation proident veniam. Non sunt qui commodo anim. Fugiat tempor minim quis adipisicing occaecat eu eu Lorem qui aliqua. Ullamco consequat dolor mollit esse consectetur aute proident sint quis laborum tempor ad consequat laboris. Nisi do sit eiusmod id.\r\n", "registered": "2014-11-26T11:25:20 -01:00", "latitude": 74.054234, "longitude": -57.775356, "tags": [ "pariatur", "non", "veniam", "duis", "et", "dolor", "reprehenderit", "enim", "incididunt", "labore" ], "friends": [ { "id": 0, "name": "Iva Burks" }, { "id": 1, "name": "Weaver Dickerson" }, { "id": 2, "name": "Dominguez Ortega" }, { "id": 3, "name": "Rhonda Dominguez" }, { "id": 4, "name": "Tillman Mercado" } ], "greeting": "Hello, Calderon Patrick! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482611b85328f5ddef3d", "index": 501, "guid": "fb635d3e-418f-4dbc-8d98-3ef3e9d4413d", "isActive": false, "balance": "$2,567.24", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "green", "name": "Nettie Conway", "gender": "female", "company": "BEDDER", "email": "nettieconway@bedder.com", "phone": "+1 (905) 410-2244", "address": "309 Hart Place, Vienna, Texas, 6539", "about": "Eiusmod mollit sit cillum anim incididunt sit commodo laborum. Consequat esse enim incididunt adipisicing ea adipisicing ipsum Lorem. Irure Lorem fugiat reprehenderit fugiat nostrud est. Cupidatat cupidatat labore cillum exercitation est pariatur ea occaecat cupidatat. Culpa elit consequat cillum nisi sunt. Deserunt sunt tempor cillum reprehenderit aliqua elit ea cupidatat deserunt. Occaecat ipsum non non cupidatat ea aliqua dolor qui dolor adipisicing voluptate amet proident.\r\n", "registered": "2015-10-05T03:39:30 -02:00", "latitude": 44.114035, "longitude": 179.939932, "tags": [ "Lorem", "sint", "commodo", "esse", "velit", "labore", "in", "aliquip", "eiusmod", "ex" ], "friends": [ { "id": 0, "name": "Jimenez Bean" }, { "id": 1, "name": "Rivers Montoya" }, { "id": 2, "name": "Alba Sellers" }, { "id": 3, "name": "Lindsey Holman" }, { "id": 4, "name": "Pruitt Floyd" } ], "greeting": "Hello, Nettie Conway! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48265dbfe4b3221b3418", "index": 502, "guid": "922d3fcb-b880-42b6-bf9b-1fc403633826", "isActive": true, "balance": "$2,474.14", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "blue", "name": "Swanson Santana", "gender": "male", "company": "STOCKPOST", "email": "swansonsantana@stockpost.com", "phone": "+1 (920) 498-2695", "address": "677 Woodbine Street, Drummond, Washington, 4138", "about": "Pariatur duis non enim amet in irure eiusmod aute officia anim. Commodo eiusmod sit Lorem reprehenderit officia laborum consequat. Est laborum excepteur cupidatat irure sit in ut laboris culpa esse irure officia laborum. Consectetur aliqua consequat veniam consectetur labore nulla proident proident aliqua dolore ipsum in culpa laboris.\r\n", "registered": "2014-02-10T09:10:34 -01:00", "latitude": 65.36818, "longitude": 53.302056, "tags": [ "eiusmod", "irure", "nostrud", "cillum", "occaecat", "ad", "officia", "pariatur", "quis", "in" ], "friends": [ { "id": 0, "name": "Helen Tate" }, { "id": 1, "name": "Francisca Barber" }, { "id": 2, "name": "Sanford Sawyer" }, { "id": 3, "name": "Gilda Harrington" }, { "id": 4, "name": "Park Davenport" } ], "greeting": "Hello, Swanson Santana! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482619c4204b3cbcb152", "index": 503, "guid": "52257ec9-53b0-4cf9-b76b-609d67da6050", "isActive": true, "balance": "$3,128.27", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "brown", "name": "Rita Ferguson", "gender": "female", "company": "QUILITY", "email": "ritaferguson@quility.com", "phone": "+1 (874) 408-3664", "address": "417 Franklin Avenue, Warren, Wyoming, 3469", "about": "Mollit tempor reprehenderit do excepteur occaecat. Do nulla minim sunt quis proident consectetur laborum commodo ullamco. Commodo ut incididunt consectetur dolore cupidatat nulla ullamco consectetur duis qui magna.\r\n", "registered": "2015-08-03T12:54:37 -02:00", "latitude": 86.348393, "longitude": 92.113702, "tags": [ "qui", "in", "tempor", "occaecat", "esse", "est", "minim", "proident", "labore", "consequat" ], "friends": [ { "id": 0, "name": "Jimmie Burch" }, { "id": 1, "name": "Bartlett Maynard" }, { "id": 2, "name": "Jami Andrews" }, { "id": 3, "name": "Polly Lott" }, { "id": 4, "name": "Georgia Rojas" } ], "greeting": "Hello, Rita Ferguson! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48265bc3ead4a59fc103", "index": 504, "guid": "bf6f3c27-e709-406e-9a9a-6c7a17bbbf6d", "isActive": true, "balance": "$1,116.05", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Hawkins Lane", "gender": "male", "company": "IMANT", "email": "hawkinslane@imant.com", "phone": "+1 (998) 459-3157", "address": "368 Poly Place, Coleville, Indiana, 8452", "about": "Id officia sint pariatur ullamco in. Amet nisi pariatur et ad excepteur deserunt ea ut Lorem ea magna. Ut aliqua incididunt quis ex proident anim nulla commodo qui labore excepteur ad. Dolor enim sint esse in consequat magna nulla eiusmod enim do aliqua ullamco in consequat. Adipisicing sunt pariatur pariatur nisi amet.\r\n", "registered": "2014-12-30T08:03:36 -01:00", "latitude": -81.483438, "longitude": -142.84738, "tags": [ "sunt", "irure", "reprehenderit", "veniam", "excepteur", "ex", "irure", "magna", "dolore", "exercitation" ], "friends": [ { "id": 0, "name": "Evangeline Wells" }, { "id": 1, "name": "Amy Mullins" }, { "id": 2, "name": "Ericka Schroeder" }, { "id": 3, "name": "Allie Frazier" }, { "id": 4, "name": "Theresa Robles" } ], "greeting": "Hello, Hawkins Lane! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826eb8d83d41c725aaf", "index": 505, "guid": "79e0a2ef-adc8-4c17-8660-ad681db5ad84", "isActive": false, "balance": "$3,753.77", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "brown", "name": "Munoz Beard", "gender": "male", "company": "CALCULA", "email": "munozbeard@calcula.com", "phone": "+1 (855) 499-3703", "address": "631 Freeman Street, Rose, Alabama, 1132", "about": "Velit quis ut esse adipisicing pariatur. Qui velit id velit labore ex irure deserunt irure sunt magna excepteur. Proident tempor elit non aliquip enim laborum dolor. Voluptate sint non sit sint sunt consectetur cillum quis.\r\n", "registered": "2016-06-30T04:58:49 -02:00", "latitude": 29.505122, "longitude": 89.330319, "tags": [ "duis", "duis", "duis", "laborum", "consectetur", "reprehenderit", "est", "aliquip", "sunt", "est" ], "friends": [ { "id": 0, "name": "Deana Stout" }, { "id": 1, "name": "Jodi Cameron" }, { "id": 2, "name": "Mullen Briggs" }, { "id": 3, "name": "Robertson Dodson" }, { "id": 4, "name": "Estela Gross" } ], "greeting": "Hello, Munoz Beard! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482649023070fa8658b7", "index": 506, "guid": "330d7e7f-5dfb-416f-aa5d-098847437475", "isActive": true, "balance": "$1,084.71", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "blue", "name": "Guy Bridges", "gender": "male", "company": "DRAGBOT", "email": "guybridges@dragbot.com", "phone": "+1 (915) 440-3402", "address": "714 Rutherford Place, Sisquoc, Virginia, 5231", "about": "Esse exercitation labore duis fugiat eiusmod fugiat culpa. Non dolore reprehenderit cillum velit in cillum commodo ullamco sint adipisicing veniam. Magna tempor duis pariatur non in et proident in exercitation qui quis non cillum aliqua.\r\n", "registered": "2016-07-28T02:59:16 -02:00", "latitude": -67.899726, "longitude": 37.727863, "tags": [ "labore", "est", "non", "aute", "Lorem", "voluptate", "excepteur", "fugiat", "anim", "aliquip" ], "friends": [ { "id": 0, "name": "Lynn Todd" }, { "id": 1, "name": "Kaufman Simpson" }, { "id": 2, "name": "Ellison Peck" }, { "id": 3, "name": "Jones Marquez" }, { "id": 4, "name": "Pittman Medina" } ], "greeting": "Hello, Guy Bridges! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48265de4b199683e0d83", "index": 507, "guid": "ba8dcb12-c1f8-42f1-a754-f410999cb0d4", "isActive": true, "balance": "$2,780.67", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Debbie Snider", "gender": "female", "company": "ZINCA", "email": "debbiesnider@zinca.com", "phone": "+1 (888) 405-3448", "address": "255 Sutter Avenue, Sheatown, New Mexico, 3026", "about": "Voluptate sunt duis ut ex velit eiusmod. Cillum laborum anim consectetur aute ullamco fugiat amet ex velit velit pariatur. Ipsum nulla ad nostrud voluptate deserunt est consectetur culpa nisi ex adipisicing occaecat.\r\n", "registered": "2014-07-03T09:58:35 -02:00", "latitude": 80.199647, "longitude": 140.661484, "tags": [ "aliqua", "reprehenderit", "in", "ex", "cillum", "duis", "laborum", "laboris", "in", "ad" ], "friends": [ { "id": 0, "name": "Holcomb Nieves" }, { "id": 1, "name": "Everett Pugh" }, { "id": 2, "name": "Cassandra Young" }, { "id": 3, "name": "Nichols Garza" }, { "id": 4, "name": "Krystal Tyson" } ], "greeting": "Hello, Debbie Snider! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48260e970b99f29aeb8b", "index": 508, "guid": "31391602-9849-4f0a-8c00-5588635d5db7", "isActive": true, "balance": "$2,312.96", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "green", "name": "Lena Dalton", "gender": "female", "company": "ACLIMA", "email": "lenadalton@aclima.com", "phone": "+1 (847) 481-3005", "address": "611 Roosevelt Place, Sidman, Hawaii, 4844", "about": "Nulla enim dolor reprehenderit culpa. Labore do pariatur sit mollit esse consequat sit irure minim. Excepteur amet proident id ut nostrud ea ex nisi est culpa voluptate labore laboris Lorem. Ut incididunt velit mollit excepteur culpa. Duis ut officia ullamco est. Velit incididunt amet proident dolore sit laboris.\r\n", "registered": "2014-01-30T04:02:01 -01:00", "latitude": -25.632586, "longitude": 88.906811, "tags": [ "cillum", "commodo", "nostrud", "et", "id", "voluptate", "quis", "ipsum", "do", "incididunt" ], "friends": [ { "id": 0, "name": "Chambers Pearson" }, { "id": 1, "name": "Lucile Sloan" }, { "id": 2, "name": "Yvette Wade" }, { "id": 3, "name": "Rice Burt" }, { "id": 4, "name": "Adeline Shelton" } ], "greeting": "Hello, Lena Dalton! You have 10 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48263a69929e9367bffe", "index": 509, "guid": "548a4b7e-6bfe-4947-b862-dd79c0cba6c4", "isActive": false, "balance": "$1,939.01", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Kemp Combs", "gender": "male", "company": "ZUVY", "email": "kempcombs@zuvy.com", "phone": "+1 (834) 409-3746", "address": "982 Amboy Street, Jacksonwald, Nebraska, 224", "about": "Culpa non do culpa amet aliqua sit esse nostrud. Ipsum id veniam ad eu duis pariatur ut tempor aliquip veniam aliqua. Dolore aliquip occaecat excepteur sit. Eiusmod consequat magna anim non sunt proident quis cillum consequat ut. Amet duis eu pariatur reprehenderit aliqua. Ea nostrud exercitation commodo do reprehenderit duis esse reprehenderit in dolor magna adipisicing cupidatat.\r\n", "registered": "2016-05-25T11:40:04 -02:00", "latitude": -85.833348, "longitude": 117.903284, "tags": [ "fugiat", "nulla", "voluptate", "esse", "id", "officia", "eiusmod", "quis", "cillum", "laboris" ], "friends": [ { "id": 0, "name": "Mullins Duncan" }, { "id": 1, "name": "Malone Holmes" }, { "id": 2, "name": "Sparks Moss" }, { "id": 3, "name": "Della Gill" }, { "id": 4, "name": "Lindsey Roy" } ], "greeting": "Hello, Kemp Combs! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48262c4ef4a433ff4be5", "index": 510, "guid": "dbdcbbb1-5aab-427e-b4b9-bd8a3dc36b88", "isActive": true, "balance": "$1,071.96", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "green", "name": "Mollie Duke", "gender": "female", "company": "THREDZ", "email": "mollieduke@thredz.com", "phone": "+1 (856) 459-2803", "address": "739 Marconi Place, Ryderwood, New York, 1049", "about": "Consequat pariatur deserunt culpa amet laborum adipisicing commodo quis id cupidatat. Commodo ad est eu enim sit sint ut ipsum enim labore excepteur anim commodo. Non duis veniam ad ad laboris ad mollit esse labore ullamco et exercitation. Pariatur et laborum et excepteur do elit proident aliquip. Fugiat magna velit velit eiusmod aliquip anim est et amet. Eu sunt velit aliqua cupidatat est consequat occaecat officia nulla esse culpa consectetur. Dolor tempor pariatur labore tempor elit proident.\r\n", "registered": "2016-05-09T10:44:08 -02:00", "latitude": 41.357669, "longitude": -139.308531, "tags": [ "laboris", "aliqua", "et", "velit", "adipisicing", "quis", "ea", "adipisicing", "proident", "consequat" ], "friends": [ { "id": 0, "name": "Huber Rush" }, { "id": 1, "name": "Mccarthy Wall" }, { "id": 2, "name": "Velazquez Cervantes" }, { "id": 3, "name": "Randolph Chan" }, { "id": 4, "name": "Ferguson Hewitt" } ], "greeting": "Hello, Mollie Duke! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826197dd2f488f007d5", "index": 511, "guid": "fd12a43c-e027-4f5f-a5a2-d3fe01292f41", "isActive": true, "balance": "$1,309.20", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "brown", "name": "Misty Witt", "gender": "female", "company": "FLUM", "email": "mistywitt@flum.com", "phone": "+1 (914) 463-2577", "address": "513 Tilden Avenue, Bartley, Marshall Islands, 9198", "about": "Aute esse duis do in irure anim elit. Ut dolore cupidatat elit officia commodo Lorem enim ullamco ea. Ex incididunt id sint id enim minim duis velit. Laborum aliqua nulla aliquip sit ea commodo quis laboris enim sint officia culpa laborum. Minim minim cupidatat minim tempor dolor occaecat non do do. Ut Lorem esse exercitation sit officia duis.\r\n", "registered": "2017-01-23T05:40:38 -01:00", "latitude": 44.220405, "longitude": -17.409532, "tags": [ "aliquip", "officia", "adipisicing", "eu", "enim", "velit", "deserunt", "amet", "laborum", "pariatur" ], "friends": [ { "id": 0, "name": "Whitehead Marshall" }, { "id": 1, "name": "Bernadine Ruiz" }, { "id": 2, "name": "Jeanie Richard" }, { "id": 3, "name": "Schultz Cook" }, { "id": 4, "name": "Greer Alvarez" } ], "greeting": "Hello, Misty Witt! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48268ff809f988a4049d", "index": 512, "guid": "9aade81e-7b65-48ca-8b84-63fff0d99aee", "isActive": true, "balance": "$3,394.30", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Hinton Gardner", "gender": "male", "company": "EVENTIX", "email": "hintongardner@eventix.com", "phone": "+1 (977) 448-2162", "address": "558 Mill Lane, Guthrie, Oregon, 2928", "about": "Fugiat ad eu eu dolor nisi occaecat velit proident velit nostrud enim. Adipisicing aute dolore aute exercitation ut ea irure nulla est velit duis cillum ad cupidatat. Exercitation sit dolore sit id ipsum est sint adipisicing qui dolor cupidatat sunt. Consequat dolore reprehenderit nisi tempor laborum in. Consequat anim do cillum consectetur aliqua sunt Lorem voluptate id eiusmod. Ea et commodo sunt veniam esse mollit proident anim cupidatat eu aute ad ad. Lorem ipsum excepteur id dolor Lorem aliqua labore aliqua consequat amet quis Lorem.\r\n", "registered": "2017-11-06T02:26:21 -01:00", "latitude": -9.3345, "longitude": -72.564303, "tags": [ "proident", "officia", "quis", "non", "esse", "exercitation", "enim", "commodo", "proident", "ad" ], "friends": [ { "id": 0, "name": "Young West" }, { "id": 1, "name": "Madelyn Carter" }, { "id": 2, "name": "Marion Farmer" }, { "id": 3, "name": "Dora Michael" }, { "id": 4, "name": "Amelia Joseph" } ], "greeting": "Hello, Hinton Gardner! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826bd5e82298684810e", "index": 513, "guid": "42685f70-b39c-440e-bddf-d735f03269ae", "isActive": false, "balance": "$1,423.63", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "blue", "name": "Wynn Bird", "gender": "male", "company": "QUADEEBO", "email": "wynnbird@quadeebo.com", "phone": "+1 (975) 418-3176", "address": "510 Lawton Street, Mammoth, Tennessee, 4040", "about": "Fugiat aliquip nisi excepteur amet laborum eu ipsum pariatur duis dolor consectetur. Sint laboris commodo incididunt labore est dolor nostrud. Proident sit nulla est amet ut incididunt velit. Dolore reprehenderit nostrud adipisicing ex quis ex id excepteur esse.\r\n", "registered": "2014-05-02T09:57:00 -02:00", "latitude": -47.818069, "longitude": 78.474979, "tags": [ "sit", "anim", "nostrud", "magna", "est", "minim", "velit", "pariatur", "nostrud", "elit" ], "friends": [ { "id": 0, "name": "Simone Humphrey" }, { "id": 1, "name": "Elisa Bray" }, { "id": 2, "name": "Leanne Moody" }, { "id": 3, "name": "Bryan Hatfield" }, { "id": 4, "name": "Jacquelyn Clayton" } ], "greeting": "Hello, Wynn Bird! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826ba417dd24bd998d3", "index": 514, "guid": "126d6709-b8a0-4a19-90a7-0f30d9f27665", "isActive": true, "balance": "$1,557.40", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "blue", "name": "Summers Mcbride", "gender": "male", "company": "TERRAGEN", "email": "summersmcbride@terragen.com", "phone": "+1 (927) 565-3211", "address": "584 Hendrix Street, Deltaville, Nevada, 1313", "about": "Esse qui consequat labore ea anim occaecat nostrud reprehenderit laboris cillum anim et ex reprehenderit. Voluptate amet excepteur nisi irure est in duis pariatur anim aute ipsum mollit ut culpa. Nostrud ipsum aliquip eu ea exercitation reprehenderit ipsum ut aliqua eiusmod. In ullamco dolore cillum velit cillum id reprehenderit. Pariatur incididunt esse in nisi reprehenderit magna exercitation culpa labore eiusmod.\r\n", "registered": "2014-01-12T05:34:13 -01:00", "latitude": 81.993021, "longitude": -150.820919, "tags": [ "veniam", "nisi", "labore", "nulla", "qui", "voluptate", "non", "labore", "ullamco", "eu" ], "friends": [ { "id": 0, "name": "Noble Barlow" }, { "id": 1, "name": "Zelma Mcgowan" }, { "id": 2, "name": "Bentley Hancock" }, { "id": 3, "name": "Flora Preston" }, { "id": 4, "name": "Alisha Marks" } ], "greeting": "Hello, Summers Mcbride! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482618998ed76069bbbd", "index": 515, "guid": "87a02d98-e14e-45af-836a-4db0b49aa569", "isActive": true, "balance": "$3,126.93", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Edith Carson", "gender": "female", "company": "BUGSALL", "email": "edithcarson@bugsall.com", "phone": "+1 (849) 446-3423", "address": "149 Gerritsen Avenue, Ogema, Alaska, 7601", "about": "Incididunt pariatur culpa quis voluptate mollit nulla excepteur occaecat exercitation. Officia officia nisi minim et aliqua occaecat sunt ex. Duis dolor nostrud culpa consectetur aliqua fugiat consectetur qui incididunt ipsum nulla ullamco in mollit. Elit laborum quis culpa minim eu.\r\n", "registered": "2015-08-22T08:10:14 -02:00", "latitude": 18.716242, "longitude": -12.343993, "tags": [ "et", "occaecat", "excepteur", "pariatur", "ut", "duis", "voluptate", "ex", "labore", "dolore" ], "friends": [ { "id": 0, "name": "Michelle Quinn" }, { "id": 1, "name": "Donaldson Warren" }, { "id": 2, "name": "Dawn Copeland" }, { "id": 3, "name": "Rhea Buchanan" }, { "id": 4, "name": "Melinda Roberts" } ], "greeting": "Hello, Edith Carson! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482618267508bc7ae686", "index": 516, "guid": "30d930d8-2237-4fd4-955f-b64315e8163f", "isActive": false, "balance": "$1,260.86", "picture": "http://placehold.it/32x32", "age": 27, "eyeColor": "blue", "name": "Stark Clements", "gender": "male", "company": "BLUPLANET", "email": "starkclements@bluplanet.com", "phone": "+1 (853) 462-3148", "address": "598 Linden Boulevard, Rosedale, Illinois, 9986", "about": "Incididunt cupidatat enim anim sint duis proident proident minim anim voluptate aliquip ea consectetur aliqua. Pariatur ad irure tempor do minim tempor laboris nisi tempor excepteur ipsum quis. Mollit id reprehenderit id enim ullamco magna do.\r\n", "registered": "2015-09-23T09:57:06 -02:00", "latitude": 28.917056, "longitude": 100.722926, "tags": [ "excepteur", "eiusmod", "quis", "sit", "adipisicing", "consequat", "consectetur", "amet", "deserunt", "ad" ], "friends": [ { "id": 0, "name": "Reyes Figueroa" }, { "id": 1, "name": "Dunn Weaver" }, { "id": 2, "name": "Howell Rasmussen" }, { "id": 3, "name": "Fletcher Hoffman" }, { "id": 4, "name": "Beulah Scott" } ], "greeting": "Hello, Stark Clements! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c53e51815b87e523", "index": 517, "guid": "a987cf8e-dadc-4b71-bc15-9916653c2d02", "isActive": true, "balance": "$1,117.75", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "blue", "name": "Kathleen Raymond", "gender": "female", "company": "QIMONK", "email": "kathleenraymond@qimonk.com", "phone": "+1 (890) 596-2676", "address": "152 Sandford Street, Wells, Oklahoma, 3255", "about": "Non ad sit sit deserunt cupidatat do enim labore consequat mollit ea. Ex commodo fugiat id incididunt minim nulla esse cupidatat veniam elit non. Magna adipisicing adipisicing eu Lorem occaecat quis quis laborum ex Lorem. Reprehenderit velit esse duis minim labore eu voluptate. In magna in anim reprehenderit reprehenderit sit. Eiusmod sit proident fugiat fugiat consectetur reprehenderit est do et excepteur minim.\r\n", "registered": "2014-03-02T01:56:50 -01:00", "latitude": -64.477683, "longitude": 61.973334, "tags": [ "do", "pariatur", "veniam", "aliquip", "ut", "reprehenderit", "amet", "laborum", "sit", "veniam" ], "friends": [ { "id": 0, "name": "Ellen Atkins" }, { "id": 1, "name": "Hurst Dickson" }, { "id": 2, "name": "Hayden Mcguire" }, { "id": 3, "name": "Morrow Osborn" }, { "id": 4, "name": "Johnston Fields" } ], "greeting": "Hello, Kathleen Raymond! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48261bf6f841a3ee2423", "index": 518, "guid": "76f440d9-1286-471a-8516-639920fc8e0d", "isActive": false, "balance": "$2,565.08", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "brown", "name": "Willie Dillard", "gender": "female", "company": "COMTOURS", "email": "williedillard@comtours.com", "phone": "+1 (829) 477-3675", "address": "279 Irving Street, Enlow, Delaware, 4232", "about": "Cillum id incididunt incididunt amet reprehenderit mollit. Eu veniam do laborum est fugiat voluptate anim irure dolore laborum dolor deserunt voluptate. Sint irure esse adipisicing deserunt non incididunt dolor irure adipisicing incididunt aute enim ipsum sunt. Dolor ad commodo et irure incididunt tempor. Minim occaecat dolore elit id enim in officia ullamco laborum officia pariatur. Nisi ut incididunt proident est. Labore non officia ea labore minim cillum cupidatat aliquip deserunt in amet cillum.\r\n", "registered": "2015-02-22T11:56:33 -01:00", "latitude": -24.337589, "longitude": 149.846345, "tags": [ "ipsum", "aute", "minim", "labore", "irure", "cupidatat", "exercitation", "ut", "aute", "consectetur" ], "friends": [ { "id": 0, "name": "Chasity Jarvis" }, { "id": 1, "name": "Vicky Hubbard" }, { "id": 2, "name": "Diane Elliott" }, { "id": 3, "name": "Miranda Davidson" }, { "id": 4, "name": "Horn Cole" } ], "greeting": "Hello, Willie Dillard! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826bc5acc2349b83ad5", "index": 519, "guid": "36484b91-5336-407e-a499-fd89674f87dd", "isActive": false, "balance": "$1,934.62", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "blue", "name": "Johnnie William", "gender": "female", "company": "VORATAK", "email": "johnniewilliam@voratak.com", "phone": "+1 (838) 416-2840", "address": "309 Milton Street, Escondida, Federated States Of Micronesia, 4649", "about": "Et eiusmod cillum nostrud deserunt irure ex aliqua id minim do proident ipsum eu. Do nisi veniam minim esse nisi amet mollit. Velit fugiat sit eiusmod excepteur incididunt ipsum officia. Amet nostrud velit nulla incididunt irure duis duis aute veniam non cillum nisi.\r\n", "registered": "2014-10-30T10:29:22 -01:00", "latitude": 86.672955, "longitude": -137.989325, "tags": [ "commodo", "ex", "deserunt", "sit", "eu", "incididunt", "proident", "adipisicing", "id", "qui" ], "friends": [ { "id": 0, "name": "Sweet Pollard" }, { "id": 1, "name": "Beatriz Green" }, { "id": 2, "name": "Gail Hampton" }, { "id": 3, "name": "Lourdes Abbott" }, { "id": 4, "name": "Horne Campos" } ], "greeting": "Hello, Johnnie William! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48260dbf7c527ffc0ca5", "index": 520, "guid": "fe9c45a6-d4e7-4671-8ad2-51c5ade5da4a", "isActive": false, "balance": "$3,059.93", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "blue", "name": "Erickson Pickett", "gender": "male", "company": "INTRADISK", "email": "ericksonpickett@intradisk.com", "phone": "+1 (882) 453-3623", "address": "455 Beadel Street, Bentley, Florida, 6717", "about": "Sint nisi labore velit sit sint. Sit minim pariatur pariatur eiusmod ea laboris adipisicing consequat. Ipsum elit esse ad velit enim fugiat voluptate reprehenderit excepteur occaecat consectetur aliquip proident. Velit consectetur consectetur do ut amet consequat commodo aliqua officia fugiat dolor anim Lorem. Labore cillum ipsum nisi incididunt in eiusmod sint ullamco ea consequat velit ad.\r\n", "registered": "2014-04-11T11:11:40 -02:00", "latitude": 50.155126, "longitude": 160.741202, "tags": [ "exercitation", "aliqua", "et", "eu", "Lorem", "culpa", "ea", "consectetur", "enim", "magna" ], "friends": [ { "id": 0, "name": "Sybil Ingram" }, { "id": 1, "name": "Amparo Howell" }, { "id": 2, "name": "Aurelia Greene" }, { "id": 3, "name": "Clayton Christensen" }, { "id": 4, "name": "Herrera Miles" } ], "greeting": "Hello, Erickson Pickett! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48268d8d8e4093570588", "index": 521, "guid": "7f854778-5897-4ee1-a60b-ebb7dd137efb", "isActive": true, "balance": "$2,717.51", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Hull Holden", "gender": "male", "company": "OPTICOM", "email": "hullholden@opticom.com", "phone": "+1 (919) 583-3672", "address": "518 Vernon Avenue, Snelling, Massachusetts, 3924", "about": "Mollit sunt anim fugiat aliquip elit proident aute. Eu eu amet cillum aute in ullamco ad aliquip. Velit officia commodo ad do laboris duis Lorem exercitation aliquip. Sint culpa deserunt commodo laborum aliqua tempor minim amet magna. Do aliquip ullamco proident nostrud est sunt ipsum incididunt id. Duis qui nulla in nostrud ut voluptate id incididunt ea velit.\r\n", "registered": "2014-11-19T04:28:57 -01:00", "latitude": -54.215984, "longitude": 44.487224, "tags": [ "cupidatat", "labore", "consequat", "exercitation", "eiusmod", "adipisicing", "laborum", "mollit", "ad", "et" ], "friends": [ { "id": 0, "name": "Christensen Newton" }, { "id": 1, "name": "Josephine Bowen" }, { "id": 2, "name": "Randall Griffith" }, { "id": 3, "name": "Sanders Martin" }, { "id": 4, "name": "Lorene Glass" } ], "greeting": "Hello, Hull Holden! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48268b6261e5e516a11b", "index": 522, "guid": "efb2a9fb-3267-4e04-96db-64ef8cee4664", "isActive": false, "balance": "$2,362.59", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "brown", "name": "Trina Barker", "gender": "female", "company": "TWIIST", "email": "trinabarker@twiist.com", "phone": "+1 (842) 481-2097", "address": "294 Nautilus Avenue, Weogufka, Mississippi, 7813", "about": "Labore irure sunt consequat irure magna magna ut aliquip irure tempor. Dolore esse enim id excepteur nisi ullamco exercitation. Esse mollit sunt in ullamco nulla cillum nulla eu sint elit laboris commodo do. Laboris est minim nostrud quis enim. Consequat voluptate ex sit eiusmod esse tempor.\r\n", "registered": "2017-02-02T07:23:02 -01:00", "latitude": -42.709406, "longitude": 8.932999, "tags": [ "laborum", "adipisicing", "et", "nulla", "est", "deserunt", "ullamco", "aliqua", "in", "aliquip" ], "friends": [ { "id": 0, "name": "Isabel Torres" }, { "id": 1, "name": "Williamson Beasley" }, { "id": 2, "name": "Ortega Roman" }, { "id": 3, "name": "Morgan Powell" }, { "id": 4, "name": "Erna Booker" } ], "greeting": "Hello, Trina Barker! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48262d13997e6fd662ec", "index": 523, "guid": "c58ebe52-977c-444e-bed5-a630adc83180", "isActive": true, "balance": "$1,850.26", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "brown", "name": "Elvira Garcia", "gender": "female", "company": "LETPRO", "email": "elviragarcia@letpro.com", "phone": "+1 (805) 481-2817", "address": "395 Seaview Court, Ebro, Guam, 5396", "about": "Ipsum proident esse minim exercitation cillum consequat deserunt. Dolor esse nisi velit anim. Commodo aute est excepteur do sit eiusmod ea et pariatur officia do id do.\r\n", "registered": "2017-09-21T10:53:48 -02:00", "latitude": 57.844962, "longitude": 104.200081, "tags": [ "adipisicing", "in", "ipsum", "qui", "cillum", "amet", "eiusmod", "sunt", "duis", "adipisicing" ], "friends": [ { "id": 0, "name": "Kasey Grant" }, { "id": 1, "name": "Alana Wilkinson" }, { "id": 2, "name": "Alison Delaney" }, { "id": 3, "name": "Odonnell Logan" }, { "id": 4, "name": "Allison Reid" } ], "greeting": "Hello, Elvira Garcia! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482644831197079c169f", "index": 524, "guid": "6cd141ad-1d69-4d0b-b887-75c919a07827", "isActive": true, "balance": "$1,771.51", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "blue", "name": "Yvonne Kinney", "gender": "female", "company": "OHMNET", "email": "yvonnekinney@ohmnet.com", "phone": "+1 (866) 455-3991", "address": "672 Brevoort Place, Denio, Louisiana, 6925", "about": "Excepteur quis veniam proident consequat esse eiusmod reprehenderit tempor est amet sint deserunt. Consequat aute consectetur cillum eiusmod. Dolor nostrud culpa aliquip occaecat dolor velit qui. Velit mollit nulla laboris sit ullamco qui aliquip non incididunt ut magna amet. Non occaecat excepteur sit ipsum anim quis aliquip. Occaecat elit irure culpa eu laborum dolor eu.\r\n", "registered": "2015-10-05T02:30:03 -02:00", "latitude": -37.241711, "longitude": -0.952132, "tags": [ "eu", "dolor", "fugiat", "amet", "do", "non", "eiusmod", "eu", "exercitation", "est" ], "friends": [ { "id": 0, "name": "Miranda Graves" }, { "id": 1, "name": "Slater Berry" }, { "id": 2, "name": "Harvey Ramsey" }, { "id": 3, "name": "Stacy Richmond" }, { "id": 4, "name": "Maddox Kline" } ], "greeting": "Hello, Yvonne Kinney! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826cf113512a39865b7", "index": 525, "guid": "f3dc30e2-f958-48c8-9f4b-cc1fbe337f57", "isActive": true, "balance": "$3,975.08", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "green", "name": "Hannah Peterson", "gender": "female", "company": "PLEXIA", "email": "hannahpeterson@plexia.com", "phone": "+1 (866) 496-2185", "address": "544 Ash Street, Brantleyville, South Dakota, 668", "about": "Esse laboris commodo dolore deserunt quis adipisicing pariatur proident. Et consequat consectetur dolor in culpa laboris aute voluptate esse voluptate et sit culpa labore. Reprehenderit labore officia ullamco aliquip labore elit ea commodo consectetur magna aute.\r\n", "registered": "2015-06-29T12:35:41 -02:00", "latitude": -44.224628, "longitude": -39.996525, "tags": [ "magna", "eu", "enim", "non", "incididunt", "aliquip", "ex", "tempor", "officia", "amet" ], "friends": [ { "id": 0, "name": "Elsie Bentley" }, { "id": 1, "name": "Carlene Wagner" }, { "id": 2, "name": "Gross Shepard" }, { "id": 3, "name": "Victoria Merrill" }, { "id": 4, "name": "Glass Armstrong" } ], "greeting": "Hello, Hannah Peterson! You have 5 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826aaa24100b0305e76", "index": 526, "guid": "a5dfd37c-659a-4453-bec1-90ed1562328e", "isActive": false, "balance": "$1,009.46", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "brown", "name": "Kidd Shepherd", "gender": "male", "company": "NIPAZ", "email": "kiddshepherd@nipaz.com", "phone": "+1 (840) 417-3449", "address": "647 Harwood Place, Day, District Of Columbia, 7347", "about": "Ullamco incididunt commodo tempor reprehenderit sint nostrud quis deserunt laboris voluptate. Excepteur magna minim velit sunt id duis commodo enim adipisicing voluptate. Quis exercitation culpa anim veniam enim amet sint excepteur.\r\n", "registered": "2015-12-25T01:03:03 -01:00", "latitude": 79.850695, "longitude": -52.25504, "tags": [ "dolore", "Lorem", "ullamco", "ex", "et", "ea", "duis", "ea", "minim", "excepteur" ], "friends": [ { "id": 0, "name": "Flynn Spence" }, { "id": 1, "name": "Ollie Conrad" }, { "id": 2, "name": "Rachel Wolf" }, { "id": 3, "name": "Bradley Myers" }, { "id": 4, "name": "Luz Bullock" } ], "greeting": "Hello, Kidd Shepherd! You have 7 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482672ea2cd952d5c8b5", "index": 527, "guid": "4d287993-1c63-4a44-bd80-bc68cb29e443", "isActive": true, "balance": "$2,359.23", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Antonia Navarro", "gender": "female", "company": "PERKLE", "email": "antonianavarro@perkle.com", "phone": "+1 (974) 475-2789", "address": "238 Belvidere Street, Leeper, Puerto Rico, 6253", "about": "Ad minim excepteur quis elit dolore velit non nostrud quis laboris. In do labore dolor quis aute ea non anim id deserunt consequat sint. Commodo nostrud aliqua ex officia irure sit aute amet Lorem enim adipisicing duis. Magna voluptate est qui anim non irure veniam anim et eu. Est consequat commodo velit sunt ullamco qui do fugiat dolor. Deserunt sint anim mollit minim. In amet do occaecat eu non aute voluptate enim ex qui elit excepteur.\r\n", "registered": "2014-04-09T06:45:33 -02:00", "latitude": -17.25676, "longitude": 150.861219, "tags": [ "dolor", "reprehenderit", "ea", "laborum", "esse", "culpa", "irure", "aliqua", "pariatur", "labore" ], "friends": [ { "id": 0, "name": "Fields Haynes" }, { "id": 1, "name": "Edwards Benson" }, { "id": 2, "name": "Shauna Stuart" }, { "id": 3, "name": "Phillips Sweet" }, { "id": 4, "name": "Luna Watts" } ], "greeting": "Hello, Antonia Navarro! You have 5 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48263aa9a46903e29a07", "index": 528, "guid": "154cc24a-de71-4612-9402-47ce6bc65bb8", "isActive": true, "balance": "$3,090.96", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "green", "name": "Audra Sims", "gender": "female", "company": "CUIZINE", "email": "audrasims@cuizine.com", "phone": "+1 (806) 411-3045", "address": "386 Bainbridge Street, Summerset, Maine, 9839", "about": "Irure elit ut reprehenderit incididunt excepteur consequat esse anim enim. Aliqua aliquip Lorem Lorem aliquip eiusmod ex. Duis ex tempor cupidatat pariatur. Lorem dolore id dolor esse sit nulla mollit sint anim officia ut. Nostrud tempor minim occaecat quis eiusmod ullamco ex consectetur ea fugiat laboris. Fugiat culpa eu officia laborum irure ipsum ipsum labore est exercitation. Irure amet commodo consequat fugiat culpa ut labore dolor.\r\n", "registered": "2017-11-05T05:29:26 -01:00", "latitude": -20.271596, "longitude": -116.344905, "tags": [ "eu", "tempor", "ullamco", "exercitation", "ea", "consequat", "ut", "proident", "mollit", "officia" ], "friends": [ { "id": 0, "name": "Antoinette Hernandez" }, { "id": 1, "name": "Nannie Knox" }, { "id": 2, "name": "Terrell Norris" }, { "id": 3, "name": "Mcbride Cotton" }, { "id": 4, "name": "Leila Guzman" } ], "greeting": "Hello, Audra Sims! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48262090730146bb5468", "index": 529, "guid": "60cbc327-a792-4e93-8c4e-700149a3c437", "isActive": true, "balance": "$3,212.60", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "green", "name": "Stone Ferrell", "gender": "male", "company": "CENTREE", "email": "stoneferrell@centree.com", "phone": "+1 (835) 502-3126", "address": "452 Tennis Court, Barrelville, New Jersey, 5553", "about": "Pariatur officia commodo eu culpa cupidatat elit est consequat. Anim eiusmod sint veniam ut id qui ea consectetur minim cillum ad sit. Aute nisi nostrud aliquip nulla ad. Et enim ut adipisicing ut ex ad Lorem nisi labore. Do duis anim aliquip reprehenderit est Lorem duis voluptate.\r\n", "registered": "2017-11-17T06:07:35 -01:00", "latitude": -59.484171, "longitude": -107.541261, "tags": [ "magna", "deserunt", "proident", "Lorem", "commodo", "ad", "ipsum", "proident", "cupidatat", "in" ], "friends": [ { "id": 0, "name": "Keller Nichols" }, { "id": 1, "name": "Bridgette Flores" }, { "id": 2, "name": "Smith Cabrera" }, { "id": 3, "name": "Katharine Hunter" }, { "id": 4, "name": "Amie Hanson" } ], "greeting": "Hello, Stone Ferrell! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48263243c7f1feb96fce", "index": 530, "guid": "00e1a5fc-3e43-4044-bd50-87f7aead3011", "isActive": true, "balance": "$3,466.15", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Hart Stevenson", "gender": "male", "company": "PASTURIA", "email": "hartstevenson@pasturia.com", "phone": "+1 (829) 523-2250", "address": "868 Keap Street, Convent, Michigan, 1517", "about": "Esse ullamco nisi occaecat do nostrud cillum amet consectetur eu dolor nulla. Pariatur nulla ex officia magna cupidatat nostrud commodo esse officia commodo enim culpa. Anim esse do pariatur mollit qui. Ullamco ea laborum aute cupidatat dolore aliqua deserunt in aliquip consectetur esse aute. Ea incididunt et dolor ipsum exercitation enim occaecat magna occaecat ut ad non velit amet. Ut exercitation quis est adipisicing magna ea occaecat irure labore ut.\r\n", "registered": "2016-09-15T01:27:26 -02:00", "latitude": 71.304085, "longitude": -38.146113, "tags": [ "cupidatat", "amet", "ullamco", "officia", "sint", "veniam", "excepteur", "sint", "velit", "aliquip" ], "friends": [ { "id": 0, "name": "Charity Lowe" }, { "id": 1, "name": "Alberta Wise" }, { "id": 2, "name": "Billie Conner" }, { "id": 3, "name": "Janie Mcdowell" }, { "id": 4, "name": "Elma Middleton" } ], "greeting": "Hello, Hart Stevenson! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826961621351c2f9b91", "index": 531, "guid": "7c2c56bc-057b-4a88-a362-e6550fc43615", "isActive": false, "balance": "$1,504.87", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Larsen Guthrie", "gender": "male", "company": "TELEPARK", "email": "larsenguthrie@telepark.com", "phone": "+1 (862) 556-2215", "address": "411 Rugby Road, Trinway, Rhode Island, 7858", "about": "Consectetur laborum ullamco consequat sunt voluptate dolor sint aliquip ad duis commodo occaecat laborum ullamco. Laborum commodo nostrud sint culpa fugiat est. Incididunt ipsum eu do sint veniam mollit ut reprehenderit incididunt quis. Sint reprehenderit deserunt nisi commodo. Et non excepteur elit cupidatat labore deserunt est reprehenderit ex.\r\n", "registered": "2014-03-16T11:38:28 -01:00", "latitude": -13.263968, "longitude": 161.603165, "tags": [ "irure", "occaecat", "do", "eiusmod", "ad", "consequat", "mollit", "culpa", "labore", "labore" ], "friends": [ { "id": 0, "name": "Alice Chandler" }, { "id": 1, "name": "Lucy Mclaughlin" }, { "id": 2, "name": "Christa Lucas" }, { "id": 3, "name": "Wendi Page" }, { "id": 4, "name": "West Butler" } ], "greeting": "Hello, Larsen Guthrie! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826468eafc506084802", "index": 532, "guid": "e6134937-ec26-4794-b8e2-2a15e8028262", "isActive": true, "balance": "$1,605.58", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "blue", "name": "Ray Prince", "gender": "male", "company": "EXOSPACE", "email": "rayprince@exospace.com", "phone": "+1 (904) 528-2940", "address": "413 Nixon Court, Rosine, Kansas, 4034", "about": "Duis anim nulla proident ullamco est aute laboris ipsum incididunt ullamco. Elit magna deserunt magna elit sit. Consequat laborum do cupidatat ut consectetur non officia sunt anim qui ex exercitation non.\r\n", "registered": "2018-01-08T04:25:57 -01:00", "latitude": 11.07535, "longitude": 75.215602, "tags": [ "sint", "et", "tempor", "id", "exercitation", "labore", "ex", "Lorem", "voluptate", "eiusmod" ], "friends": [ { "id": 0, "name": "English Jordan" }, { "id": 1, "name": "Mccormick Morton" }, { "id": 2, "name": "Sheena Hobbs" }, { "id": 3, "name": "Ruth Deleon" }, { "id": 4, "name": "Teresa Perkins" } ], "greeting": "Hello, Ray Prince! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826c428ac192c283179", "index": 533, "guid": "6db1c35c-cda0-4e4e-a28e-46fb5c1c414c", "isActive": false, "balance": "$3,304.40", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Autumn Kemp", "gender": "female", "company": "SILODYNE", "email": "autumnkemp@silodyne.com", "phone": "+1 (805) 563-2736", "address": "491 Bedford Place, Barclay, West Virginia, 7248", "about": "Nulla aliquip cupidatat minim ipsum mollit ut velit sint. Non deserunt exercitation reprehenderit dolor nostrud enim exercitation qui incididunt pariatur. Deserunt consequat elit quis in sint ipsum labore proident voluptate occaecat labore. Aliquip nulla voluptate nostrud non minim. Nulla eiusmod commodo magna excepteur sit adipisicing excepteur ad qui consectetur laboris sit id. Qui qui in veniam esse proident in.\r\n", "registered": "2014-10-13T01:03:09 -02:00", "latitude": 40.211548, "longitude": 136.971953, "tags": [ "sit", "reprehenderit", "et", "id", "nisi", "duis", "ut", "anim", "ex", "eiusmod" ], "friends": [ { "id": 0, "name": "Corrine Hogan" }, { "id": 1, "name": "Angela Webster" }, { "id": 2, "name": "Barry Hunt" }, { "id": 3, "name": "Sherri Emerson" }, { "id": 4, "name": "Bryant Mcleod" } ], "greeting": "Hello, Autumn Kemp! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48265352800ea69c17ac", "index": 534, "guid": "bca18c84-ab51-429b-a95f-489c14c204e6", "isActive": true, "balance": "$2,889.22", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "brown", "name": "Hansen Hughes", "gender": "male", "company": "SUNCLIPSE", "email": "hansenhughes@sunclipse.com", "phone": "+1 (906) 433-3672", "address": "726 Oriental Court, Needmore, American Samoa, 798", "about": "Amet sint laboris cillum eu id. Ut ex non est ex et quis qui sunt aliqua aliquip aliqua ipsum. Dolore cillum ut velit eiusmod consectetur mollit. Non enim tempor aliqua anim est excepteur ullamco do.\r\n", "registered": "2015-05-01T02:48:13 -02:00", "latitude": -59.368355, "longitude": -145.834955, "tags": [ "aliqua", "sit", "fugiat", "Lorem", "commodo", "ipsum", "cillum", "duis", "quis", "et" ], "friends": [ { "id": 0, "name": "Joy Haley" }, { "id": 1, "name": "Tyson Lyons" }, { "id": 2, "name": "Sharon Walton" }, { "id": 3, "name": "Deena Guy" }, { "id": 4, "name": "Hess Irwin" } ], "greeting": "Hello, Hansen Hughes! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ac375414bee52b64", "index": 535, "guid": "66169ab1-0e13-40e9-b79c-a9c1b4d11f20", "isActive": false, "balance": "$2,884.74", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "blue", "name": "Todd Herring", "gender": "male", "company": "UTARIAN", "email": "toddherring@utarian.com", "phone": "+1 (842) 430-2204", "address": "465 Forest Place, Basye, Maryland, 8661", "about": "Mollit anim laboris voluptate mollit commodo. Ipsum enim occaecat ea excepteur reprehenderit. Nostrud reprehenderit est veniam ex exercitation commodo magna. Ea ea eiusmod tempor quis adipisicing occaecat. Magna ut nisi ullamco labore ut. Non officia commodo duis esse velit veniam esse.\r\n", "registered": "2016-03-19T03:07:20 -01:00", "latitude": -69.796617, "longitude": -61.072474, "tags": [ "mollit", "enim", "dolore", "deserunt", "voluptate", "minim", "elit", "aliquip", "ex", "occaecat" ], "friends": [ { "id": 0, "name": "Murray Solis" }, { "id": 1, "name": "Dina Fuller" }, { "id": 2, "name": "Byers Bruce" }, { "id": 3, "name": "Lorraine Benton" }, { "id": 4, "name": "Merrill Oneal" } ], "greeting": "Hello, Todd Herring! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b0472aad47e986b7", "index": 536, "guid": "d4701a50-b451-4ed0-9ffb-050d0cce198b", "isActive": true, "balance": "$3,353.48", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Eddie Hess", "gender": "female", "company": "UNISURE", "email": "eddiehess@unisure.com", "phone": "+1 (906) 411-2633", "address": "888 Mayfair Drive, Hoehne, California, 1314", "about": "Labore ipsum minim ex aute in irure ex pariatur aute officia commodo eu. Fugiat veniam ullamco ad irure. Cupidatat sint nulla fugiat minim Lorem. Exercitation non esse incididunt ea nulla amet sunt commodo. Eiusmod fugiat dolore adipisicing enim deserunt amet sint dolore fugiat magna anim velit pariatur.\r\n", "registered": "2014-07-10T12:16:54 -02:00", "latitude": 88.65818, "longitude": -41.583575, "tags": [ "nisi", "tempor", "amet", "quis", "anim", "aliqua", "do", "voluptate", "nisi", "velit" ], "friends": [ { "id": 0, "name": "Lesa Leach" }, { "id": 1, "name": "Reese Sargent" }, { "id": 2, "name": "Emerson Leblanc" }, { "id": 3, "name": "Moore Jenkins" }, { "id": 4, "name": "Walsh Gordon" } ], "greeting": "Hello, Eddie Hess! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826254c8f6458410e1f", "index": 537, "guid": "0d417044-fbef-4ebe-8eb9-a17aa5079408", "isActive": true, "balance": "$2,664.36", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Faye Conley", "gender": "female", "company": "COMVENE", "email": "fayeconley@comvene.com", "phone": "+1 (828) 591-2502", "address": "755 Cranberry Street, Elbert, Utah, 6057", "about": "Id duis aute culpa et ullamco nostrud sint. Nulla occaecat ullamco minim adipisicing irure enim cillum id et veniam exercitation duis ex. Veniam fugiat quis officia eiusmod. Dolor sint ad culpa incididunt irure occaecat eu proident culpa sint.\r\n", "registered": "2014-04-30T04:57:38 -02:00", "latitude": 85.093967, "longitude": 103.746252, "tags": [ "laboris", "Lorem", "ex", "cillum", "ipsum", "irure", "eu", "qui", "ad", "aliquip" ], "friends": [ { "id": 0, "name": "Deidre Rutledge" }, { "id": 1, "name": "Robin Baird" }, { "id": 2, "name": "Shanna Finch" }, { "id": 3, "name": "Baxter Cruz" }, { "id": 4, "name": "Johns Bailey" } ], "greeting": "Hello, Faye Conley! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48265057e078f0ddaf45", "index": 538, "guid": "f0552413-e5ab-40cd-bcc2-104e9516d335", "isActive": false, "balance": "$2,212.27", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "green", "name": "May England", "gender": "male", "company": "QUIZKA", "email": "mayengland@quizka.com", "phone": "+1 (826) 412-3958", "address": "713 Fane Court, Sedley, Iowa, 155", "about": "Anim magna laborum esse sit aliquip eu irure dolor in non nulla eiusmod incididunt. Aliqua esse adipisicing esse aute. Dolore do non id voluptate ex laboris est magna. Adipisicing enim et cupidatat voluptate occaecat consequat tempor ad deserunt culpa cupidatat adipisicing. Excepteur do consectetur non Lorem voluptate et ipsum. Laboris nostrud eiusmod deserunt dolor voluptate eu adipisicing nulla est.\r\n", "registered": "2015-08-31T11:24:43 -02:00", "latitude": -25.924145, "longitude": 47.046014, "tags": [ "laborum", "occaecat", "eu", "excepteur", "commodo", "excepteur", "ullamco", "sint", "mollit", "nisi" ], "friends": [ { "id": 0, "name": "Lopez Gamble" }, { "id": 1, "name": "Nielsen Chambers" }, { "id": 2, "name": "Leah Castillo" }, { "id": 3, "name": "Jean Lowery" }, { "id": 4, "name": "Margie Cross" } ], "greeting": "Hello, May England! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482649b1eab18124f0d2", "index": 539, "guid": "571f0f97-ab99-4e4e-aec5-0c48cfa2709a", "isActive": false, "balance": "$3,152.87", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Tran Santos", "gender": "male", "company": "QUORDATE", "email": "transantos@quordate.com", "phone": "+1 (975) 506-3763", "address": "104 Erskine Loop, Frank, North Dakota, 4593", "about": "Irure proident reprehenderit fugiat id magna veniam do labore sint duis duis amet. Nisi culpa aliqua ut sunt sint esse laboris consectetur in. Mollit id nisi officia ad exercitation ad aliqua proident.\r\n", "registered": "2014-11-29T05:45:20 -01:00", "latitude": -43.267151, "longitude": 33.422188, "tags": [ "ex", "commodo", "aliquip", "aute", "cupidatat", "eu", "veniam", "non", "non", "nisi" ], "friends": [ { "id": 0, "name": "Colon Langley" }, { "id": 1, "name": "Lara Good" }, { "id": 2, "name": "Dejesus Jimenez" }, { "id": 3, "name": "Flossie Fernandez" }, { "id": 4, "name": "Klein Parrish" } ], "greeting": "Hello, Tran Santos! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826ed24ff203afa13ad", "index": 540, "guid": "2253e2e8-71f5-41bb-8bb4-b3efd65e8521", "isActive": false, "balance": "$1,163.27", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Alyssa Avery", "gender": "female", "company": "SKYBOLD", "email": "alyssaavery@skybold.com", "phone": "+1 (873) 441-3458", "address": "524 Bills Place, Chical, Kentucky, 4862", "about": "Do magna veniam enim id cupidatat. Lorem minim dolor incididunt exercitation ut et enim officia. Sint do ex laborum commodo pariatur exercitation. Voluptate eu ex fugiat ullamco eiusmod ullamco dolore occaecat adipisicing. Commodo ullamco ipsum pariatur cillum veniam eiusmod exercitation est velit eu ullamco cupidatat tempor. Esse nisi do sit incididunt deserunt sint deserunt duis esse. Officia aliqua laboris voluptate sunt nisi in adipisicing voluptate commodo minim occaecat et.\r\n", "registered": "2017-10-24T07:03:05 -02:00", "latitude": -30.748689, "longitude": -44.915672, "tags": [ "exercitation", "eu", "do", "excepteur", "quis", "qui", "minim", "excepteur", "proident", "occaecat" ], "friends": [ { "id": 0, "name": "Moody Hurst" }, { "id": 1, "name": "Carey Suarez" }, { "id": 2, "name": "Alexis Reeves" }, { "id": 3, "name": "Hebert Mclean" }, { "id": 4, "name": "Warner Guerrero" } ], "greeting": "Hello, Alyssa Avery! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826758d25a6a7d39fb2", "index": 541, "guid": "efdcad16-2643-4781-b52e-828bb08e13c5", "isActive": true, "balance": "$2,739.44", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "brown", "name": "Enid Perry", "gender": "female", "company": "EXOTECHNO", "email": "enidperry@exotechno.com", "phone": "+1 (850) 564-2873", "address": "791 Concord Street, Greenbackville, Colorado, 2229", "about": "Tempor nostrud cupidatat mollit amet mollit. Sunt cupidatat excepteur officia occaecat voluptate esse exercitation cupidatat. Esse esse id anim eu Lorem ad aliqua fugiat.\r\n", "registered": "2017-12-25T02:05:48 -01:00", "latitude": 70.463168, "longitude": -156.609332, "tags": [ "adipisicing", "ipsum", "ut", "enim", "ex", "non", "non", "non", "nostrud", "ex" ], "friends": [ { "id": 0, "name": "Nancy Fulton" }, { "id": 1, "name": "Jacqueline Harrell" }, { "id": 2, "name": "Christina Odom" }, { "id": 3, "name": "Cantrell Newman" }, { "id": 4, "name": "Molly Cote" } ], "greeting": "Hello, Enid Perry! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c0c6b4fa0c8a34aa", "index": 542, "guid": "cea52ff2-5852-43d6-b2dd-afa5f164b2cf", "isActive": true, "balance": "$3,945.19", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "blue", "name": "Consuelo Yang", "gender": "female", "company": "IMAGEFLOW", "email": "consueloyang@imageflow.com", "phone": "+1 (940) 538-2602", "address": "936 Newton Street, Wheatfields, New Hampshire, 6350", "about": "Reprehenderit est laboris cillum magna excepteur eiusmod enim cupidatat in ea consectetur commodo irure. Cupidatat adipisicing laboris quis labore Lorem pariatur ipsum consectetur cupidatat culpa laboris laborum velit. Pariatur laboris ea ea pariatur duis excepteur. Laborum fugiat eiusmod ipsum Lorem enim nostrud culpa qui voluptate. Fugiat aliquip eiusmod aliquip in sint quis veniam laboris aliquip laborum.\r\n", "registered": "2015-05-11T02:13:47 -02:00", "latitude": 76.861963, "longitude": 21.468333, "tags": [ "aliqua", "veniam", "sit", "aute", "anim", "sunt", "reprehenderit", "excepteur", "elit", "veniam" ], "friends": [ { "id": 0, "name": "Aileen Mayer" }, { "id": 1, "name": "Oneill Mendez" }, { "id": 2, "name": "Schneider Watson" }, { "id": 3, "name": "Ofelia Washington" }, { "id": 4, "name": "Patton Lang" } ], "greeting": "Hello, Consuelo Yang! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826a96068e58aad6164", "index": 543, "guid": "0d1584ef-eb2a-4e84-93e5-4738431e9192", "isActive": true, "balance": "$3,888.02", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "green", "name": "Stacie Cardenas", "gender": "female", "company": "HYPLEX", "email": "staciecardenas@hyplex.com", "phone": "+1 (881) 529-2195", "address": "995 Newkirk Placez, Wheaton, Wisconsin, 8525", "about": "Sint Lorem do minim proident culpa commodo ullamco veniam consequat. Duis duis sint ex amet consequat sint nisi labore occaecat. Consectetur commodo esse sunt aute mollit voluptate velit et consequat. Amet enim duis ex anim consequat et qui consequat est aliquip dolor ad laboris. Aliqua ullamco sit labore excepteur anim duis do id aliquip labore do officia.\r\n", "registered": "2016-01-19T06:16:00 -01:00", "latitude": 82.336497, "longitude": 65.943063, "tags": [ "nulla", "anim", "id", "in", "aliqua", "sint", "officia", "Lorem", "tempor", "ad" ], "friends": [ { "id": 0, "name": "Davenport Wynn" }, { "id": 1, "name": "Briggs Golden" }, { "id": 2, "name": "Simon Cantu" }, { "id": 3, "name": "Bailey Morse" }, { "id": 4, "name": "Rebekah Luna" } ], "greeting": "Hello, Stacie Cardenas! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482661d4fd5338ff3fdf", "index": 544, "guid": "922ce0b1-09a3-4b20-a3b8-22bc7e192a38", "isActive": true, "balance": "$3,470.50", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "blue", "name": "Karen Santiago", "gender": "female", "company": "NETBOOK", "email": "karensantiago@netbook.com", "phone": "+1 (967) 402-3505", "address": "655 Tillary Street, Bourg, Idaho, 8044", "about": "Ex ea magna eiusmod occaecat elit irure voluptate aliquip et dolor magna velit. Aute laborum fugiat exercitation dolor cupidatat laborum excepteur incididunt fugiat. Cupidatat consequat proident est quis elit id id cillum. Nostrud anim eiusmod consectetur eiusmod ex eiusmod aute labore id mollit do aliqua culpa.\r\n", "registered": "2014-10-16T05:41:58 -02:00", "latitude": -44.294253, "longitude": 1.053509, "tags": [ "tempor", "nostrud", "fugiat", "anim", "nulla", "tempor", "cillum", "enim", "aliqua", "do" ], "friends": [ { "id": 0, "name": "Dianna Vinson" }, { "id": 1, "name": "Kramer Salas" }, { "id": 2, "name": "Shelton Mayo" }, { "id": 3, "name": "Bernard Herman" }, { "id": 4, "name": "Anna Pena" } ], "greeting": "Hello, Karen Santiago! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826675d6542905a06e8", "index": 545, "guid": "f31cd785-8299-491f-b3bd-1f5d66d533ef", "isActive": true, "balance": "$3,646.63", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Josefa Murray", "gender": "female", "company": "ZOARERE", "email": "josefamurray@zoarere.com", "phone": "+1 (832) 560-2160", "address": "465 Florence Avenue, Stevens, Georgia, 8429", "about": "Eiusmod quis laboris sint eu sunt excepteur qui amet dolore deserunt reprehenderit velit non irure. Nisi in sunt ut occaecat cillum non in deserunt elit dolor. Sit sunt nisi cupidatat labore sint ex nostrud quis veniam reprehenderit commodo. Deserunt est amet veniam culpa magna pariatur et voluptate.\r\n", "registered": "2015-01-06T07:56:00 -01:00", "latitude": -8.049261, "longitude": 52.672172, "tags": [ "consectetur", "officia", "cupidatat", "voluptate", "commodo", "pariatur", "commodo", "elit", "dolor", "ipsum" ], "friends": [ { "id": 0, "name": "Kline Thomas" }, { "id": 1, "name": "Ingrid Phelps" }, { "id": 2, "name": "Rachael Wolfe" }, { "id": 3, "name": "Clay Tanner" }, { "id": 4, "name": "Celeste Turner" } ], "greeting": "Hello, Josefa Murray! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826a8ec9ecdeadf5edb", "index": 546, "guid": "c244e171-ea8d-44fd-bc97-55785fcddb12", "isActive": false, "balance": "$1,476.69", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Dona Horn", "gender": "female", "company": "TYPHONICA", "email": "donahorn@typhonica.com", "phone": "+1 (973) 408-2757", "address": "933 Riverdale Avenue, Gambrills, Virgin Islands, 421", "about": "Tempor et sint esse adipisicing et quis ipsum reprehenderit laborum ad fugiat. Esse ea consequat ut eiusmod id non cillum velit adipisicing labore mollit est. Sint mollit incididunt ipsum anim veniam nisi culpa velit. Velit ullamco ad excepteur tempor. Excepteur proident pariatur sint elit velit officia mollit est id sit enim aliqua.\r\n", "registered": "2015-07-16T09:19:35 -02:00", "latitude": 18.752294, "longitude": -71.551159, "tags": [ "laboris", "magna", "aliquip", "proident", "pariatur", "laboris", "adipisicing", "deserunt", "commodo", "excepteur" ], "friends": [ { "id": 0, "name": "Berg Mcclain" }, { "id": 1, "name": "Marshall Serrano" }, { "id": 2, "name": "Tameka Molina" }, { "id": 3, "name": "Nona Mccarty" }, { "id": 4, "name": "Angelina Workman" } ], "greeting": "Hello, Dona Horn! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48263ef3fadcc8a23236", "index": 547, "guid": "c6f7c265-ac6a-4066-9578-b7aeb5af7d28", "isActive": false, "balance": "$1,335.28", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "blue", "name": "Lakeisha Ross", "gender": "female", "company": "QUIZMO", "email": "lakeishaross@quizmo.com", "phone": "+1 (943) 543-3737", "address": "550 Eastern Parkway, Graniteville, Minnesota, 6094", "about": "Aute sunt ex aliqua anim dolore ea qui nisi laboris fugiat ea. Qui do quis fugiat minim enim dolore. Consequat proident dolor adipisicing esse fugiat sint non in eu dolore esse do. Elit excepteur ea ex occaecat id mollit nisi in officia.\r\n", "registered": "2017-02-10T03:09:20 -01:00", "latitude": -41.541791, "longitude": 97.671945, "tags": [ "Lorem", "sint", "ullamco", "dolore", "fugiat", "irure", "sit", "sit", "dolor", "veniam" ], "friends": [ { "id": 0, "name": "Cross Ramos" }, { "id": 1, "name": "Wilma Russell" }, { "id": 2, "name": "Mary Cochran" }, { "id": 3, "name": "Guadalupe Taylor" }, { "id": 4, "name": "Mendoza Dale" } ], "greeting": "Hello, Lakeisha Ross! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826cf10941400c4bf2a", "index": 548, "guid": "44882bd2-9cd1-44ee-886d-2dff5aea64e2", "isActive": false, "balance": "$3,228.86", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Joann Adkins", "gender": "female", "company": "CIRCUM", "email": "joannadkins@circum.com", "phone": "+1 (831) 419-3330", "address": "442 Himrod Street, Broadlands, South Carolina, 5828", "about": "Sint aute officia occaecat aute irure tempor occaecat magna proident. Exercitation commodo voluptate sit nisi veniam ad ipsum dolor anim reprehenderit sint aliqua. Aliquip duis id officia labore sint mollit amet ullamco ex Lorem sit fugiat exercitation. Anim eiusmod eiusmod dolore id.\r\n", "registered": "2014-08-17T08:23:51 -02:00", "latitude": 59.955272, "longitude": 166.657133, "tags": [ "cillum", "velit", "eiusmod", "quis", "enim", "et", "nulla", "nisi", "nisi", "ullamco" ], "friends": [ { "id": 0, "name": "Elba Noel" }, { "id": 1, "name": "Liz Moran" }, { "id": 2, "name": "Clements Byers" }, { "id": 3, "name": "Muriel Houston" }, { "id": 4, "name": "Koch Lindsey" } ], "greeting": "Hello, Joann Adkins! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826972f7b9f0e922e0d", "index": 549, "guid": "4b925837-6f0b-4bc7-adba-fc6483888118", "isActive": true, "balance": "$2,750.00", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "brown", "name": "Leta Dyer", "gender": "female", "company": "VIAGREAT", "email": "letadyer@viagreat.com", "phone": "+1 (840) 576-2914", "address": "994 Columbus Place, Tooleville, Northern Mariana Islands, 2422", "about": "Irure ex minim adipisicing elit. Non in adipisicing fugiat eiusmod enim consectetur amet cupidatat duis quis sit deserunt. Exercitation officia ea do do culpa amet officia. Ea fugiat sit occaecat excepteur eu labore nisi reprehenderit anim. Sit minim sint magna eu et non aute culpa. Aliquip in enim irure cupidatat culpa consectetur laborum do minim proident cillum enim duis pariatur. Tempor consequat ipsum amet labore sint occaecat.\r\n", "registered": "2015-02-04T06:29:30 -01:00", "latitude": -6.916926, "longitude": -164.120935, "tags": [ "sint", "sunt", "eu", "tempor", "laboris", "velit", "excepteur", "pariatur", "elit", "pariatur" ], "friends": [ { "id": 0, "name": "Elnora Shields" }, { "id": 1, "name": "Heidi Lancaster" }, { "id": 2, "name": "Bird Harrison" }, { "id": 3, "name": "Mcclain Sosa" }, { "id": 4, "name": "Blanca Thompson" } ], "greeting": "Hello, Leta Dyer! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48262f953c240cf210bc", "index": 550, "guid": "23a360d7-13fe-4df0-8a3f-079da1838cec", "isActive": true, "balance": "$2,077.92", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Delgado Kidd", "gender": "male", "company": "OPTYK", "email": "delgadokidd@optyk.com", "phone": "+1 (884) 596-2505", "address": "414 Hamilton Walk, Wakulla, Pennsylvania, 9438", "about": "Dolor aliqua ipsum reprehenderit tempor nulla laboris culpa irure dolore ea culpa. Cillum duis deserunt cillum elit eu enim dolor incididunt deserunt veniam eiusmod quis pariatur nostrud. Tempor laboris ipsum et deserunt nostrud laborum minim. Anim dolore do Lorem tempor sint sunt velit pariatur proident. Sit voluptate id qui ullamco et do sint Lorem anim. Ut eiusmod commodo qui voluptate mollit esse culpa cupidatat laborum pariatur adipisicing non. Sint adipisicing nulla est officia voluptate sit mollit sit.\r\n", "registered": "2017-03-10T04:01:55 -01:00", "latitude": 63.10944, "longitude": 157.239133, "tags": [ "velit", "proident", "non", "exercitation", "sint", "non", "enim", "aliquip", "ut", "occaecat" ], "friends": [ { "id": 0, "name": "Mandy Joyner" }, { "id": 1, "name": "Althea Ochoa" }, { "id": 2, "name": "Eunice Vang" }, { "id": 3, "name": "Gordon Pate" }, { "id": 4, "name": "Leonard Webb" } ], "greeting": "Hello, Delgado Kidd! You have 4 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826b62c6e933364f5e6", "index": 551, "guid": "34085322-905e-494d-9a41-a307e5b7676f", "isActive": true, "balance": "$2,716.57", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Phyllis Mcneil", "gender": "female", "company": "CALLFLEX", "email": "phyllismcneil@callflex.com", "phone": "+1 (853) 486-3180", "address": "395 Furman Street, Harrodsburg, Arkansas, 5606", "about": "Ut Lorem sunt aliqua esse sit irure aliqua ex adipisicing ipsum. Quis cupidatat mollit mollit sint non dolor qui adipisicing. Et sunt cillum anim pariatur eu id anim sint adipisicing. Minim labore mollit et consequat sunt culpa nisi ea incididunt deserunt occaecat aute ut. Sint aute nostrud nulla do et ut laboris elit nostrud tempor deserunt quis excepteur. Fugiat commodo magna mollit qui magna tempor nostrud labore aliquip ad.\r\n", "registered": "2015-04-02T11:44:12 -02:00", "latitude": -76.14702, "longitude": -73.371956, "tags": [ "Lorem", "laborum", "laborum", "do", "culpa", "ipsum", "ipsum", "non", "ad", "cillum" ], "friends": [ { "id": 0, "name": "Harriett Glenn" }, { "id": 1, "name": "Villarreal Hyde" }, { "id": 2, "name": "Walton Hurley" }, { "id": 3, "name": "Lorena Bartlett" }, { "id": 4, "name": "Haynes Boyd" } ], "greeting": "Hello, Phyllis Mcneil! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482696ec7fcf0ba89337", "index": 552, "guid": "4a864319-8587-4759-a324-ae62544754dd", "isActive": false, "balance": "$1,025.83", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "green", "name": "Bobbi Kent", "gender": "female", "company": "ENERVATE", "email": "bobbikent@enervate.com", "phone": "+1 (994) 551-3855", "address": "695 Scott Avenue, Hillsboro, Palau, 777", "about": "Veniam exercitation Lorem laborum reprehenderit. Ut occaecat officia excepteur nulla incididunt. Excepteur eiusmod minim eu dolore occaecat aute ad. Sit fugiat do nostrud esse proident magna ullamco. Aute aliquip reprehenderit laborum enim ex magna ex laborum ut fugiat cupidatat adipisicing amet. Exercitation in elit laboris in laborum laborum. Proident do sunt Lorem esse magna sit pariatur exercitation Lorem ea est.\r\n", "registered": "2015-08-11T07:56:36 -02:00", "latitude": -59.022486, "longitude": -116.708597, "tags": [ "sunt", "ipsum", "mollit", "duis", "qui", "fugiat", "duis", "culpa", "incididunt", "consectetur" ], "friends": [ { "id": 0, "name": "Harriet Gillespie" }, { "id": 1, "name": "Rae Stafford" }, { "id": 2, "name": "Chris Arnold" }, { "id": 3, "name": "Shannon Ballard" }, { "id": 4, "name": "Craig Sweeney" } ], "greeting": "Hello, Bobbi Kent! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482689a68af0ea7817e4", "index": 553, "guid": "a38b7d2f-4f7b-44ec-afa3-6d1573a918bc", "isActive": true, "balance": "$2,778.24", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Sheila Wong", "gender": "female", "company": "MINGA", "email": "sheilawong@minga.com", "phone": "+1 (906) 519-3059", "address": "790 Nelson Street, Takilma, Connecticut, 5292", "about": "Non commodo nisi et id nisi nostrud duis non officia. Deserunt minim dolor eu minim exercitation aliquip mollit veniam. Officia consectetur do occaecat commodo id reprehenderit pariatur ex eiusmod incididunt exercitation ad incididunt. Nisi commodo ipsum aute laboris non. Officia officia ea mollit laboris incididunt occaecat aliquip est et mollit sunt ut irure laborum.\r\n", "registered": "2014-01-05T01:51:21 -01:00", "latitude": 69.877822, "longitude": -33.421163, "tags": [ "duis", "aute", "laboris", "cillum", "pariatur", "aute", "ullamco", "id", "sunt", "consectetur" ], "friends": [ { "id": 0, "name": "Marilyn Delacruz" }, { "id": 1, "name": "Sabrina Singleton" }, { "id": 2, "name": "Ladonna Mccall" }, { "id": 3, "name": "Shari Charles" }, { "id": 4, "name": "Maura Wilcox" } ], "greeting": "Hello, Sheila Wong! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826ab83d886ce456f80", "index": 554, "guid": "97a6adbf-ed8f-41f4-9a71-82de74516ae4", "isActive": true, "balance": "$3,866.66", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "green", "name": "Decker Dorsey", "gender": "male", "company": "BITENDREX", "email": "deckerdorsey@bitendrex.com", "phone": "+1 (931) 505-2770", "address": "233 Woodruff Avenue, Oley, North Carolina, 1679", "about": "Dolore duis cillum dolore eu laboris irure nulla. Tempor esse non consectetur enim ea nostrud labore aute culpa adipisicing commodo adipisicing. Ut eu ex do pariatur minim occaecat dolor non. Minim nisi exercitation elit adipisicing irure occaecat do.\r\n", "registered": "2017-11-01T08:09:24 -01:00", "latitude": -7.368346, "longitude": -35.170203, "tags": [ "enim", "non", "velit", "deserunt", "dolor", "consequat", "officia", "tempor", "est", "culpa" ], "friends": [ { "id": 0, "name": "Trudy Morgan" }, { "id": 1, "name": "Kelley Gay" }, { "id": 2, "name": "Stevenson Odonnell" }, { "id": 3, "name": "Marla Lawson" }, { "id": 4, "name": "Meyers Massey" } ], "greeting": "Hello, Decker Dorsey! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482642e7bf65c75a36d7", "index": 555, "guid": "6d339678-2ca1-41ef-8159-f7be0a027830", "isActive": true, "balance": "$2,338.06", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Callahan Holcomb", "gender": "male", "company": "EXTRAWEAR", "email": "callahanholcomb@extrawear.com", "phone": "+1 (874) 421-2284", "address": "199 Johnson Avenue, Mooresburg, Missouri, 473", "about": "Velit laborum deserunt ea ut. Ea cillum sint duis tempor adipisicing do. Est ipsum sunt aute eu aliquip sunt qui. Duis cupidatat ut minim magna minim ipsum duis laboris.\r\n", "registered": "2014-05-23T08:22:55 -02:00", "latitude": -85.251217, "longitude": 120.86102, "tags": [ "exercitation", "dolore", "veniam", "duis", "laborum", "eu", "sit", "voluptate", "nisi", "ad" ], "friends": [ { "id": 0, "name": "Herring Brooks" }, { "id": 1, "name": "Holman Hendrix" }, { "id": 2, "name": "Murphy Barnes" }, { "id": 3, "name": "Janette Cortez" }, { "id": 4, "name": "Lauri Kelly" } ], "greeting": "Hello, Callahan Holcomb! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482667d129509bf2ca32", "index": 556, "guid": "98bc5400-35cd-42ae-b91a-94707ab1e95b", "isActive": true, "balance": "$1,101.27", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "green", "name": "Alicia Shaffer", "gender": "female", "company": "SLOFAST", "email": "aliciashaffer@slofast.com", "phone": "+1 (890) 552-3005", "address": "995 Chapel Street, Hoagland, Ohio, 5222", "about": "Laboris in duis incididunt cillum laboris. Dolore Lorem anim laborum minim eu nulla incididunt eu irure velit veniam. Veniam ut nulla enim elit eiusmod in amet. Voluptate eiusmod consequat commodo velit minim labore dolor labore minim dolor mollit. Cupidatat sunt veniam amet enim occaecat irure dolore nulla. Do Lorem amet duis sit.\r\n", "registered": "2015-03-30T08:10:02 -02:00", "latitude": 53.005938, "longitude": -166.193409, "tags": [ "dolore", "quis", "incididunt", "aute", "minim", "id", "labore", "irure", "enim", "ea" ], "friends": [ { "id": 0, "name": "Martina Walters" }, { "id": 1, "name": "Crystal English" }, { "id": 2, "name": "Velasquez Osborne" }, { "id": 3, "name": "Saunders Schultz" }, { "id": 4, "name": "Mcconnell Sullivan" } ], "greeting": "Hello, Alicia Shaffer! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826e65578a5fefe5cd4", "index": 557, "guid": "c81d84d1-bfe2-4efb-ae79-e2ca5e871eb1", "isActive": true, "balance": "$3,548.25", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "brown", "name": "Mcfarland Gomez", "gender": "male", "company": "SONGBIRD", "email": "mcfarlandgomez@songbird.com", "phone": "+1 (888) 534-3571", "address": "208 Senator Street, Gulf, Arizona, 4801", "about": "Fugiat labore eu nulla velit tempor qui adipisicing proident eiusmod aliqua dolor tempor. Dolor enim nulla voluptate sit nisi sit aliquip duis consectetur duis labore aute eiusmod. In aliqua consequat minim pariatur nostrud dolor officia labore sunt. Irure excepteur velit pariatur irure incididunt dolore sunt anim duis cillum laborum dolor. Eu mollit laborum consequat in culpa. Laborum tempor mollit magna officia tempor anim irure commodo occaecat ea excepteur ullamco nulla magna. Sunt ut consectetur aute nostrud nostrud ullamco ea nulla est tempor eu reprehenderit deserunt.\r\n", "registered": "2014-01-11T05:30:44 -01:00", "latitude": 7.524481, "longitude": 0.908086, "tags": [ "dolore", "consequat", "Lorem", "do", "ullamco", "nisi", "consectetur", "deserunt", "sunt", "amet" ], "friends": [ { "id": 0, "name": "Pauline Maxwell" }, { "id": 1, "name": "Darlene Cash" }, { "id": 2, "name": "Wooten Rich" }, { "id": 3, "name": "Lila Gibbs" }, { "id": 4, "name": "Shana Stephenson" } ], "greeting": "Hello, Mcfarland Gomez! You have 2 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826c3ca3f2ea17a6f50", "index": 558, "guid": "e995b4fc-c00f-4503-8b68-3dc3051ebc06", "isActive": false, "balance": "$1,547.58", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Hahn Hopkins", "gender": "male", "company": "EMERGENT", "email": "hahnhopkins@emergent.com", "phone": "+1 (840) 561-2746", "address": "128 Dinsmore Place, Mulberry, Montana, 6857", "about": "Dolore voluptate eiusmod do irure. Nostrud velit eu ut enim laborum quis ut consequat. Magna laborum voluptate cupidatat consectetur culpa laborum eiusmod pariatur aliqua occaecat quis cupidatat commodo consectetur. Cillum aute sit ea id anim. Nostrud incididunt exercitation dolore ipsum enim eiusmod magna quis.\r\n", "registered": "2017-09-25T01:31:58 -02:00", "latitude": 77.070428, "longitude": -153.419479, "tags": [ "quis", "id", "anim", "elit", "excepteur", "velit", "reprehenderit", "quis", "eiusmod", "mollit" ], "friends": [ { "id": 0, "name": "Kate Strickland" }, { "id": 1, "name": "Megan Lee" }, { "id": 2, "name": "Elisabeth Meyers" }, { "id": 3, "name": "Kirkland Casey" }, { "id": 4, "name": "Sonia Sanchez" } ], "greeting": "Hello, Hahn Hopkins! You have 6 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48264de373261a12f1c0", "index": 559, "guid": "b0d92c89-e8cd-43dd-ba36-a417c18242a8", "isActive": false, "balance": "$3,641.61", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "blue", "name": "Bennett Moreno", "gender": "male", "company": "ISOPOP", "email": "bennettmoreno@isopop.com", "phone": "+1 (926) 474-3385", "address": "766 Boerum Place, Davenport, Texas, 3644", "about": "Mollit deserunt velit minim ea amet commodo consequat. Irure nulla excepteur tempor velit occaecat eiusmod do. Mollit culpa Lorem est eiusmod cupidatat minim cillum. Excepteur fugiat ipsum et excepteur deserunt.\r\n", "registered": "2016-02-02T02:54:33 -01:00", "latitude": -53.359327, "longitude": -96.630226, "tags": [ "sunt", "eu", "enim", "ex", "deserunt", "fugiat", "adipisicing", "Lorem", "cupidatat", "nisi" ], "friends": [ { "id": 0, "name": "Margery Schwartz" }, { "id": 1, "name": "Lawson Munoz" }, { "id": 2, "name": "Hicks Terry" }, { "id": 3, "name": "Patel Thornton" }, { "id": 4, "name": "Whitney Collins" } ], "greeting": "Hello, Bennett Moreno! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482616cc25d9a495f50c", "index": 560, "guid": "345401aa-c9c7-4d68-9a9b-1c7761c5e97f", "isActive": true, "balance": "$3,786.64", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "blue", "name": "Ursula Welch", "gender": "female", "company": "ACUMENTOR", "email": "ursulawelch@acumentor.com", "phone": "+1 (972) 474-3257", "address": "928 Borinquen Pl, Rockbridge, Washington, 1813", "about": "Ullamco ut ullamco adipisicing qui exercitation mollit sit qui. Voluptate incididunt labore minim mollit sunt sit veniam ea ipsum duis ut laborum amet elit. Aliquip tempor qui sit tempor ex consectetur cupidatat sit dolor proident excepteur. Ipsum ea exercitation veniam commodo velit anim labore ea duis quis tempor consectetur sunt. Laboris nulla fugiat do non deserunt fugiat aute esse elit dolor deserunt non proident elit. Eiusmod eiusmod veniam adipisicing duis officia pariatur.\r\n", "registered": "2014-01-01T09:56:07 -01:00", "latitude": -76.64367, "longitude": -6.56002, "tags": [ "aliquip", "eu", "irure", "duis", "cillum", "eu", "nisi", "duis", "incididunt", "pariatur" ], "friends": [ { "id": 0, "name": "Fuentes Fuentes" }, { "id": 1, "name": "Hilary Carlson" }, { "id": 2, "name": "Susan Hawkins" }, { "id": 3, "name": "Powers Brown" }, { "id": 4, "name": "Katie Holt" } ], "greeting": "Hello, Ursula Welch! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48263d82dea89db84053", "index": 561, "guid": "6bb1f218-03b6-44b4-9de7-d3a5368ac39d", "isActive": false, "balance": "$2,517.45", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "brown", "name": "Young Moon", "gender": "male", "company": "KEENGEN", "email": "youngmoon@keengen.com", "phone": "+1 (825) 410-3299", "address": "811 Ocean Avenue, Bluffview, Wyoming, 9804", "about": "Dolore commodo duis ut do in laboris consequat incididunt voluptate proident aute id. Laborum excepteur anim nostrud id nulla. Deserunt velit id ea culpa nostrud quis in exercitation labore dolore. Minim ipsum labore fugiat in officia exercitation nostrud in aliqua officia irure. Ad labore eu ex labore. Sint laboris voluptate amet incididunt id nulla elit sint aliquip consectetur culpa aliquip culpa. Voluptate minim non proident excepteur labore.\r\n", "registered": "2016-09-23T02:09:13 -02:00", "latitude": -26.806614, "longitude": -62.333652, "tags": [ "laboris", "tempor", "cillum", "sit", "laborum", "amet", "eu", "proident", "elit", "ut" ], "friends": [ { "id": 0, "name": "Wade Hull" }, { "id": 1, "name": "Stella Holder" }, { "id": 2, "name": "Maria Burns" }, { "id": 3, "name": "Guerrero Porter" }, { "id": 4, "name": "Parrish Hale" } ], "greeting": "Hello, Young Moon! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482639fefbe8896734a9", "index": 562, "guid": "09833a09-6d4c-48d6-96e9-46a738a24d18", "isActive": false, "balance": "$2,242.29", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "brown", "name": "Lelia Atkinson", "gender": "female", "company": "CANOPOLY", "email": "leliaatkinson@canopoly.com", "phone": "+1 (845) 570-3842", "address": "610 Granite Street, Gibbsville, Indiana, 9439", "about": "Do exercitation excepteur dolore labore tempor ad commodo minim enim ut aliqua pariatur voluptate. Velit amet mollit veniam aliqua culpa. Aute tempor sit sint proident irure consectetur minim ullamco. Ut magna officia elit fugiat nulla minim ut magna pariatur commodo dolore ut est occaecat. Dolor proident cillum do laboris cupidatat elit tempor officia aliquip consectetur culpa.\r\n", "registered": "2016-12-26T05:01:11 -01:00", "latitude": -42.636186, "longitude": -82.850273, "tags": [ "commodo", "nisi", "laboris", "aute", "dolor", "reprehenderit", "culpa", "reprehenderit", "labore", "labore" ], "friends": [ { "id": 0, "name": "Iris Jones" }, { "id": 1, "name": "Patsy Melendez" }, { "id": 2, "name": "Lynn Boyle" }, { "id": 3, "name": "Allison Padilla" }, { "id": 4, "name": "Marylou Travis" } ], "greeting": "Hello, Lelia Atkinson! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e482668a318d748d391f1", "index": 563, "guid": "1d8f4a4e-c369-4646-a754-c6c8df231d5c", "isActive": true, "balance": "$3,750.29", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Summer Malone", "gender": "female", "company": "LYRICHORD", "email": "summermalone@lyrichord.com", "phone": "+1 (895) 502-3788", "address": "828 Dictum Court, Gila, Alabama, 3089", "about": "Eu do id culpa mollit Lorem deserunt reprehenderit commodo. Id laboris anim magna est ad ea magna reprehenderit eu magna velit eiusmod quis. Qui enim aute do do aliquip reprehenderit exercitation ad voluptate in.\r\n", "registered": "2014-09-26T01:06:06 -02:00", "latitude": 30.240448, "longitude": -140.153431, "tags": [ "culpa", "pariatur", "id", "ea", "pariatur", "nostrud", "incididunt", "veniam", "laboris", "ipsum" ], "friends": [ { "id": 0, "name": "Delores Mccray" }, { "id": 1, "name": "Michele Whitney" }, { "id": 2, "name": "Arlene Ward" }, { "id": 3, "name": "Lou Nolan" }, { "id": 4, "name": "Francine Burnett" } ], "greeting": "Hello, Summer Malone! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48266cf6fa50e573d0fb", "index": 564, "guid": "c2f44e2e-87a2-428e-bf73-ff48a42ace26", "isActive": false, "balance": "$1,418.08", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Eva Poole", "gender": "female", "company": "ISOSPHERE", "email": "evapoole@isosphere.com", "phone": "+1 (954) 450-3959", "address": "124 Carlton Avenue, Deercroft, Virginia, 5062", "about": "Enim consectetur eu aute culpa pariatur culpa quis. Enim tempor est officia ipsum veniam dolore do. Sit ut quis aliqua pariatur. Excepteur id enim ut velit dolor pariatur anim adipisicing adipisicing veniam ex magna.\r\n", "registered": "2017-01-26T11:55:02 -01:00", "latitude": -67.885059, "longitude": -93.089181, "tags": [ "ut", "occaecat", "tempor", "laborum", "fugiat", "pariatur", "qui", "nisi", "anim", "Lorem" ], "friends": [ { "id": 0, "name": "Boyle Calderon" }, { "id": 1, "name": "Stevens Chapman" }, { "id": 2, "name": "Vaughan Russo" }, { "id": 3, "name": "Margo Baker" }, { "id": 4, "name": "Tabatha Hays" } ], "greeting": "Hello, Eva Poole! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48267eb6977a81fdcf24", "index": 565, "guid": "dd776bfe-39d7-4ad4-bbe9-f7ae250a3d04", "isActive": false, "balance": "$2,656.12", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "blue", "name": "Janice Madden", "gender": "female", "company": "SENTIA", "email": "janicemadden@sentia.com", "phone": "+1 (826) 597-3437", "address": "615 Indiana Place, Chloride, New Mexico, 4132", "about": "Nostrud eu dolore tempor in consectetur. Qui laborum est aliquip esse minim culpa qui exercitation labore esse. Deserunt elit sit cillum consequat ut ex anim laboris irure do eiusmod veniam officia minim. In et culpa mollit pariatur ad deserunt proident.\r\n", "registered": "2017-12-18T04:38:26 -01:00", "latitude": -85.810044, "longitude": 0.945917, "tags": [ "fugiat", "veniam", "eu", "commodo", "mollit", "mollit", "incididunt", "ullamco", "occaecat", "nulla" ], "friends": [ { "id": 0, "name": "Bonner Keller" }, { "id": 1, "name": "Kelly Kim" }, { "id": 2, "name": "Baker Hood" }, { "id": 3, "name": "Cervantes Patterson" }, { "id": 4, "name": "Hunt Patel" } ], "greeting": "Hello, Janice Madden! You have 1 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e0da8c8dca218b18", "index": 566, "guid": "9dad1e17-4a5b-434c-a124-e637ec3db8cb", "isActive": false, "balance": "$1,807.46", "picture": "http://placehold.it/32x32", "age": 26, "eyeColor": "green", "name": "Oliver Knapp", "gender": "male", "company": "GENMEX", "email": "oliverknapp@genmex.com", "phone": "+1 (933) 470-3487", "address": "138 Bedell Lane, Gasquet, Hawaii, 2275", "about": "Enim sunt exercitation occaecat incididunt qui ea minim do laboris est ad. Ipsum et esse fugiat excepteur voluptate. Aliquip culpa aliquip proident est est anim fugiat voluptate Lorem cillum nisi nisi. Cillum sit ut irure excepteur nostrud pariatur consectetur ut enim. Velit enim cupidatat sunt amet ex laborum qui pariatur labore voluptate aliqua laborum.\r\n", "registered": "2016-06-02T11:37:38 -02:00", "latitude": -2.822661, "longitude": -72.572229, "tags": [ "irure", "culpa", "est", "magna", "excepteur", "mollit", "est", "id", "consectetur", "incididunt" ], "friends": [ { "id": 0, "name": "Mason Sanford" }, { "id": 1, "name": "Mcmillan Rodriquez" }, { "id": 2, "name": "Drake Berger" }, { "id": 3, "name": "Tracie Snyder" }, { "id": 4, "name": "Valencia Kirby" } ], "greeting": "Hello, Oliver Knapp! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48261c1cd238b8041955", "index": 567, "guid": "0287fd4b-2030-4b27-9cef-102ac4cf873e", "isActive": false, "balance": "$3,244.03", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "green", "name": "Franklin Gray", "gender": "male", "company": "IMPERIUM", "email": "franklingray@imperium.com", "phone": "+1 (816) 499-2014", "address": "188 Willow Place, Tetherow, Nebraska, 8078", "about": "Aliquip veniam enim deserunt minim quis duis ex officia dolor do nulla ea tempor culpa. In duis incididunt nisi occaecat culpa dolore dolore. Ea qui sunt voluptate sit deserunt duis duis reprehenderit nostrud labore ullamco. Mollit consectetur laboris exercitation dolore laborum cillum duis aute proident cillum culpa. Exercitation consequat enim veniam irure magna irure commodo cupidatat qui. Culpa nisi excepteur qui ex laborum minim officia exercitation reprehenderit. Aute dolor ipsum laboris velit aute minim magna nulla adipisicing laboris.\r\n", "registered": "2014-07-07T10:42:26 -02:00", "latitude": 37.378413, "longitude": 44.788428, "tags": [ "non", "aliquip", "laborum", "Lorem", "anim", "ullamco", "mollit", "consectetur", "ea", "sit" ], "friends": [ { "id": 0, "name": "Grace Jacobson" }, { "id": 1, "name": "Julia Patton" }, { "id": 2, "name": "Vargas Parks" }, { "id": 3, "name": "Gill Howard" }, { "id": 4, "name": "Montoya Black" } ], "greeting": "Hello, Franklin Gray! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c95c538173804a56", "index": 568, "guid": "bb4b897f-2d9c-4cd4-8223-56750da14efd", "isActive": false, "balance": "$1,901.61", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Bishop Hardin", "gender": "male", "company": "IMMUNICS", "email": "bishophardin@immunics.com", "phone": "+1 (838) 576-3059", "address": "536 Moore Place, Watchtower, New York, 8497", "about": "Pariatur ex voluptate aliquip eu commodo adipisicing elit est velit consectetur aute velit aliqua incididunt. Ipsum non laborum nulla officia qui consectetur excepteur qui fugiat cupidatat velit dolor ipsum reprehenderit. Sit mollit irure elit enim non id est. Incididunt fugiat amet ex labore. Duis laborum laboris reprehenderit do veniam laborum esse. Eu nisi consequat elit ipsum laborum officia nisi aliquip aliqua est laboris nostrud nulla.\r\n", "registered": "2017-07-12T10:10:25 -02:00", "latitude": -30.200053, "longitude": 67.418356, "tags": [ "aliquip", "esse", "est", "fugiat", "esse", "voluptate", "est", "culpa", "anim", "ut" ], "friends": [ { "id": 0, "name": "Mcfadden Griffin" }, { "id": 1, "name": "Debora Lopez" }, { "id": 2, "name": "Adrian Walls" }, { "id": 3, "name": "Berger Bernard" }, { "id": 4, "name": "Rosalinda Hooper" } ], "greeting": "Hello, Bishop Hardin! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826305db1ed88611db2", "index": 569, "guid": "617773a1-7867-4fa9-9b92-9535a402bbae", "isActive": false, "balance": "$3,510.07", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "green", "name": "Candace Maddox", "gender": "female", "company": "ZOLAVO", "email": "candacemaddox@zolavo.com", "phone": "+1 (912) 437-2188", "address": "337 Pulaski Street, Fairlee, Marshall Islands, 4829", "about": "Non ullamco duis fugiat reprehenderit deserunt est ullamco culpa cillum cillum aute. Sint mollit minim sint est cillum. Occaecat occaecat id anim laboris labore proident enim laborum ipsum officia cupidatat. In dolor est dolore sunt ad nostrud do nulla aliqua qui aliqua. Eiusmod occaecat sunt proident dolore consequat.\r\n", "registered": "2018-01-07T10:42:32 -01:00", "latitude": 3.972701, "longitude": 165.778824, "tags": [ "irure", "aute", "eu", "pariatur", "nulla", "deserunt", "fugiat", "amet", "in", "fugiat" ], "friends": [ { "id": 0, "name": "Janis Mccoy" }, { "id": 1, "name": "Ava Sparks" }, { "id": 2, "name": "Georgette Albert" }, { "id": 3, "name": "Sloan Mejia" }, { "id": 4, "name": "Kinney Riddle" } ], "greeting": "Hello, Candace Maddox! You have 4 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826fe3e9d0b45bbc7e3", "index": 570, "guid": "4311b080-f602-4769-905e-7b580347bad2", "isActive": false, "balance": "$1,949.31", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "brown", "name": "Fowler Dixon", "gender": "male", "company": "BLURRYBUS", "email": "fowlerdixon@blurrybus.com", "phone": "+1 (837) 520-2340", "address": "697 Lewis Avenue, Wollochet, Oregon, 6241", "about": "Sit est duis ipsum excepteur nulla ex do amet dolor ex est officia Lorem commodo. Qui commodo dolor pariatur nostrud cupidatat amet cillum commodo aliqua sunt sunt. Minim proident cillum nostrud commodo ea qui incididunt fugiat.\r\n", "registered": "2016-11-20T02:24:26 -01:00", "latitude": 52.870383, "longitude": -168.338058, "tags": [ "incididunt", "occaecat", "incididunt", "mollit", "ullamco", "non", "sit", "enim", "aliqua", "laborum" ], "friends": [ { "id": 0, "name": "Taylor Ortiz" }, { "id": 1, "name": "Glenda Dunn" }, { "id": 2, "name": "Mckee Palmer" }, { "id": 3, "name": "Cox Ayers" }, { "id": 4, "name": "Katheryn Foster" } ], "greeting": "Hello, Fowler Dixon! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826cef209cb93646b13", "index": 571, "guid": "1f7ebc22-6d3d-408b-8b7f-5fec994d369d", "isActive": true, "balance": "$1,624.32", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "brown", "name": "Barr Merritt", "gender": "male", "company": "MACRONAUT", "email": "barrmerritt@macronaut.com", "phone": "+1 (918) 485-3286", "address": "904 Suydam Place, Torboy, Tennessee, 9415", "about": "Sit consequat quis deserunt consectetur aute ex amet fugiat exercitation deserunt in aliqua nulla eiusmod. Id fugiat do aliquip mollit voluptate aliquip excepteur. Nostrud id Lorem excepteur adipisicing magna veniam eu. Qui culpa fugiat sit ipsum officia dolor non officia. Lorem voluptate et est est aute nostrud excepteur officia dolore ex deserunt. Deserunt consectetur consectetur cillum ipsum voluptate pariatur culpa fugiat ullamco adipisicing velit in consequat. Lorem occaecat laboris elit cillum adipisicing nisi cillum velit dolor sunt.\r\n", "registered": "2015-08-10T05:46:32 -02:00", "latitude": 29.095051, "longitude": 68.612213, "tags": [ "laborum", "commodo", "eiusmod", "tempor", "non", "aliqua", "Lorem", "Lorem", "aliquip", "elit" ], "friends": [ { "id": 0, "name": "Marquita Allison" }, { "id": 1, "name": "Vang Clemons" }, { "id": 2, "name": "Briana Mcdonald" }, { "id": 3, "name": "Evans Leon" }, { "id": 4, "name": "Marianne Owen" } ], "greeting": "Hello, Barr Merritt! You have 8 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826f5b0c3c38c4e8a37", "index": 572, "guid": "d8a758f1-9fac-40d1-89f9-e7c2b85b3525", "isActive": true, "balance": "$2,660.83", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "blue", "name": "Florence Levy", "gender": "female", "company": "COMVOY", "email": "florencelevy@comvoy.com", "phone": "+1 (810) 455-3008", "address": "812 Roebling Street, Glenbrook, Nevada, 4300", "about": "Sunt et ad pariatur adipisicing Lorem ex reprehenderit excepteur minim aliqua. Dolor sint aliquip mollit aliqua do pariatur laboris minim ad nulla. Aliqua ipsum et do incididunt est aliqua id dolor duis enim sit id ad ad. Cupidatat tempor cillum officia nulla deserunt Lorem minim commodo laborum. Eiusmod labore quis excepteur voluptate id esse dolore ad amet in aute pariatur. Ipsum labore est culpa deserunt eiusmod cillum dolor sit. Irure nostrud elit adipisicing pariatur magna sunt nisi.\r\n", "registered": "2016-02-24T01:27:37 -01:00", "latitude": -64.425382, "longitude": -107.027419, "tags": [ "ea", "est", "duis", "anim", "aliquip", "anim", "occaecat", "labore", "sint", "elit" ], "friends": [ { "id": 0, "name": "Marguerite Cain" }, { "id": 1, "name": "Raymond Vance" }, { "id": 2, "name": "Barnes Harvey" }, { "id": 3, "name": "Stephenson Jackson" }, { "id": 4, "name": "Mercedes Rivas" } ], "greeting": "Hello, Florence Levy! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e482654296b4e7d471250", "index": 573, "guid": "6f7959ac-90df-4dcf-92df-4c45d0102027", "isActive": false, "balance": "$1,154.91", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "blue", "name": "Willis Craft", "gender": "male", "company": "ORBOID", "email": "williscraft@orboid.com", "phone": "+1 (905) 426-2391", "address": "163 Stuyvesant Avenue, Remington, Alaska, 3008", "about": "Duis non dolor fugiat deserunt adipisicing ipsum et exercitation elit. Consectetur nulla proident cillum ipsum consectetur non eiusmod dolore est ad eiusmod nulla. Laboris ut sit eu labore eiusmod deserunt eu amet mollit in exercitation excepteur qui.\r\n", "registered": "2015-11-11T09:09:09 -01:00", "latitude": 51.258434, "longitude": -14.607036, "tags": [ "culpa", "esse", "ullamco", "nisi", "quis", "tempor", "fugiat", "exercitation", "aliqua", "dolor" ], "friends": [ { "id": 0, "name": "Penny Carver" }, { "id": 1, "name": "Dorothea Vasquez" }, { "id": 2, "name": "Carly Pitts" }, { "id": 3, "name": "Jaclyn Harmon" }, { "id": 4, "name": "Amanda Stone" } ], "greeting": "Hello, Willis Craft! You have 5 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48267def936574471cbd", "index": 574, "guid": "3d06576e-cb2a-4f0a-bcc9-67e457c452a0", "isActive": true, "balance": "$1,373.51", "picture": "http://placehold.it/32x32", "age": 25, "eyeColor": "blue", "name": "Kimberley Mcdaniel", "gender": "female", "company": "KINETICUT", "email": "kimberleymcdaniel@kineticut.com", "phone": "+1 (987) 404-2811", "address": "268 Bliss Terrace, Vandiver, Illinois, 7796", "about": "Officia esse fugiat enim ad nisi officia quis incididunt nisi sint aliqua ea quis cupidatat. Cupidatat esse officia sint deserunt tempor aliquip fugiat pariatur consectetur cillum in do nisi. Irure anim veniam consequat velit magna laboris ad ad et est amet culpa anim. Duis culpa et adipisicing ad velit aliquip mollit. Elit id et anim et dolore ullamco ad. Voluptate eiusmod velit nulla voluptate culpa laboris.\r\n", "registered": "2014-04-23T12:36:12 -02:00", "latitude": -24.559361, "longitude": 101.480606, "tags": [ "aliquip", "ad", "consequat", "est", "proident", "commodo", "excepteur", "labore", "ut", "ea" ], "friends": [ { "id": 0, "name": "Mariana Mcmillan" }, { "id": 1, "name": "Hardin Browning" }, { "id": 2, "name": "Navarro Harris" }, { "id": 3, "name": "Fischer Perez" }, { "id": 4, "name": "Betsy Oconnor" } ], "greeting": "Hello, Kimberley Mcdaniel! You have 3 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826651f7ed8c8b53af1", "index": 575, "guid": "9046b324-e0f9-42c9-b518-e65512792542", "isActive": false, "balance": "$2,602.76", "picture": "http://placehold.it/32x32", "age": 28, "eyeColor": "brown", "name": "Barker Cooley", "gender": "male", "company": "BESTO", "email": "barkercooley@besto.com", "phone": "+1 (809) 516-2067", "address": "897 Meeker Avenue, Grandview, Oklahoma, 6800", "about": "Dolore nisi qui qui voluptate magna ad excepteur ea officia. Sunt laboris id nulla exercitation duis culpa dolore sit. Cillum anim ea et elit exercitation fugiat sit. Lorem consequat aute ea officia ullamco enim duis exercitation esse. Ipsum culpa cupidatat laboris proident ipsum laboris anim laborum esse ut fugiat ipsum.\r\n", "registered": "2017-09-27T01:28:58 -02:00", "latitude": -31.899983, "longitude": -131.042942, "tags": [ "magna", "anim", "quis", "ad", "esse", "ipsum", "ex", "cupidatat", "enim", "nostrud" ], "friends": [ { "id": 0, "name": "Sandoval Clarke" }, { "id": 1, "name": "Albert Castro" }, { "id": 2, "name": "Dickson Diaz" }, { "id": 3, "name": "Simpson Garrison" }, { "id": 4, "name": "Nichole Cantrell" } ], "greeting": "Hello, Barker Cooley! You have 2 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48262349a178276bc929", "index": 576, "guid": "bd57afe1-aec1-4fbd-a4ad-ad80a7d72fde", "isActive": false, "balance": "$1,508.46", "picture": "http://placehold.it/32x32", "age": 39, "eyeColor": "brown", "name": "Orr Farrell", "gender": "male", "company": "SKYPLEX", "email": "orrfarrell@skyplex.com", "phone": "+1 (872) 583-3002", "address": "358 Catherine Street, Newry, Delaware, 3487", "about": "Adipisicing laborum et et et esse minim ea ea. Laborum sint officia est minim tempor voluptate cupidatat. Nisi ex dolor esse aliqua eu magna anim officia ut labore cupidatat.\r\n", "registered": "2017-04-14T09:52:11 -02:00", "latitude": -88.856584, "longitude": -166.232065, "tags": [ "cupidatat", "in", "culpa", "veniam", "et", "pariatur", "laboris", "ex", "cillum", "esse" ], "friends": [ { "id": 0, "name": "Nelson Franco" }, { "id": 1, "name": "Potts Hopper" }, { "id": 2, "name": "Laverne Dillon" }, { "id": 3, "name": "Chelsea York" }, { "id": 4, "name": "Soto Rodriguez" } ], "greeting": "Hello, Orr Farrell! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826d7f8f32b061b596c", "index": 577, "guid": "0c46c17f-7488-46de-833d-bfae7a010d15", "isActive": false, "balance": "$1,673.23", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "green", "name": "Mayo Larson", "gender": "male", "company": "HAIRPORT", "email": "mayolarson@hairport.com", "phone": "+1 (847) 543-2689", "address": "571 Cheever Place, Nicholson, Federated States Of Micronesia, 7248", "about": "Duis irure quis amet dolore eiusmod deserunt aliquip. Reprehenderit elit excepteur enim laboris adipisicing do. Amet cupidatat consequat ullamco est eu in esse culpa.\r\n", "registered": "2014-08-09T10:59:40 -02:00", "latitude": -88.29757, "longitude": -68.245331, "tags": [ "aliqua", "voluptate", "ea", "adipisicing", "ipsum", "officia", "reprehenderit", "mollit", "cillum", "Lorem" ], "friends": [ { "id": 0, "name": "Benton Koch" }, { "id": 1, "name": "Eugenia Gregory" }, { "id": 2, "name": "Mcpherson Salazar" }, { "id": 3, "name": "Boyer Becker" }, { "id": 4, "name": "Santiago Byrd" } ], "greeting": "Hello, Mayo Larson! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826b9c11ad07645cf87", "index": 578, "guid": "e3682c3c-1cc0-41bb-8b2b-f3882ffe28af", "isActive": true, "balance": "$1,694.10", "picture": "http://placehold.it/32x32", "age": 29, "eyeColor": "green", "name": "Sosa Boone", "gender": "male", "company": "TRASOLA", "email": "sosaboone@trasola.com", "phone": "+1 (836) 597-3578", "address": "538 Emerald Street, Bennett, Florida, 8522", "about": "Minim minim Lorem fugiat est in aute amet non aute in Lorem. Ut Lorem deserunt adipisicing laborum incididunt elit. Enim tempor mollit occaecat incididunt laboris tempor consequat eiusmod irure laborum occaecat officia proident. Fugiat dolore ea labore ullamco.\r\n", "registered": "2015-03-21T01:07:49 -01:00", "latitude": -67.679661, "longitude": 160.222899, "tags": [ "sint", "consequat", "ut", "veniam", "magna", "cupidatat", "occaecat", "aliqua", "sint", "qui" ], "friends": [ { "id": 0, "name": "Weeks Barnett" }, { "id": 1, "name": "Mccullough Huff" }, { "id": 2, "name": "Knowles Brady" }, { "id": 3, "name": "Melendez Hoover" }, { "id": 4, "name": "Richards Clay" } ], "greeting": "Hello, Sosa Boone! You have 6 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e3c64b907c643cbf", "index": 579, "guid": "9ef211c8-162d-4900-8398-5b4ced4828b4", "isActive": true, "balance": "$2,037.10", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Rosalind Chaney", "gender": "female", "company": "RUBADUB", "email": "rosalindchaney@rubadub.com", "phone": "+1 (920) 466-3092", "address": "329 Vanderbilt Street, Belgreen, Massachusetts, 2834", "about": "Esse nulla eiusmod ea exercitation amet incididunt excepteur ullamco officia. Sit do do laborum labore est deserunt anim nulla ipsum non dolore labore irure. Nisi adipisicing exercitation proident cillum. Exercitation voluptate tempor consequat consectetur labore velit aute nulla eu sit reprehenderit dolor. Esse magna id id ut reprehenderit duis eu qui incididunt nostrud officia est laboris. Quis consectetur aute do id laborum id do irure labore ex enim voluptate.\r\n", "registered": "2014-12-16T01:00:24 -01:00", "latitude": -73.604727, "longitude": -39.116927, "tags": [ "eiusmod", "esse", "esse", "nostrud", "non", "qui", "pariatur", "et", "ea", "consectetur" ], "friends": [ { "id": 0, "name": "Gray Larsen" }, { "id": 1, "name": "Porter Nicholson" }, { "id": 2, "name": "Underwood Mcmahon" }, { "id": 3, "name": "Campbell Wilson" }, { "id": 4, "name": "Melanie Galloway" } ], "greeting": "Hello, Rosalind Chaney! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826d5ca09d3fcb8df0b", "index": 580, "guid": "443560e5-9a0c-4a49-8bf1-ca5d6e87cb86", "isActive": false, "balance": "$2,723.28", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Mcintyre Everett", "gender": "male", "company": "GLUID", "email": "mcintyreeverett@gluid.com", "phone": "+1 (923) 493-3374", "address": "725 Dennett Place, Collins, Mississippi, 3527", "about": "In anim dolor ullamco commodo culpa consectetur consequat veniam. Eu esse sit nisi reprehenderit esse magna elit esse laboris amet labore id reprehenderit. Elit ipsum ex cillum voluptate irure ex officia cupidatat nostrud labore sit aliqua non. Veniam exercitation cillum commodo culpa Lorem sunt ex veniam labore id ea. Tempor aute in et cillum ad ex qui magna deserunt eu eu quis.\r\n", "registered": "2016-11-17T07:22:39 -01:00", "latitude": 53.289027, "longitude": 161.984047, "tags": [ "tempor", "dolor", "do", "irure", "nulla", "mollit", "consectetur", "cillum", "laboris", "proident" ], "friends": [ { "id": 0, "name": "Jamie Meadows" }, { "id": 1, "name": "Beard Hinton" }, { "id": 2, "name": "Leslie Sharpe" }, { "id": 3, "name": "Nadine Buckner" }, { "id": 4, "name": "Juliana Morris" } ], "greeting": "Hello, Mcintyre Everett! You have 8 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482674aeed8a305c51d8", "index": 581, "guid": "ad23c14e-f321-4f0a-bd58-24cd4a863390", "isActive": true, "balance": "$1,623.21", "picture": "http://placehold.it/32x32", "age": 31, "eyeColor": "blue", "name": "Lucas Wilder", "gender": "male", "company": "ECRATER", "email": "lucaswilder@ecrater.com", "phone": "+1 (904) 414-2555", "address": "995 Dewey Place, Valmy, Guam, 5061", "about": "Dolore enim sint fugiat esse ullamco amet amet laborum esse magna et voluptate non duis. Nisi in anim ex occaecat ut. Veniam nisi ut esse magna aliqua excepteur tempor reprehenderit fugiat laborum anim. Veniam culpa tempor ut in laborum.\r\n", "registered": "2016-06-06T11:26:23 -02:00", "latitude": 65.629651, "longitude": -79.982177, "tags": [ "pariatur", "mollit", "fugiat", "proident", "ut", "est", "eiusmod", "labore", "mollit", "ex" ], "friends": [ { "id": 0, "name": "Christi Olsen" }, { "id": 1, "name": "Burks Garner" }, { "id": 2, "name": "Lina Walker" }, { "id": 3, "name": "Judith Neal" }, { "id": 4, "name": "Duncan Colon" } ], "greeting": "Hello, Lucas Wilder! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482643e3a60bb12a0f7f", "index": 582, "guid": "8a85a18a-4676-46f9-83a2-a48ef3a847e8", "isActive": false, "balance": "$2,532.59", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "brown", "name": "Mildred Mercer", "gender": "female", "company": "MAGMINA", "email": "mildredmercer@magmina.com", "phone": "+1 (901) 522-2331", "address": "743 Sedgwick Place, Greensburg, Louisiana, 2554", "about": "Tempor sunt occaecat nostrud non sit. Ullamco pariatur sit sint et pariatur id ad occaecat quis cillum ut. Et laborum pariatur qui sint laborum laborum commodo velit excepteur laborum quis.\r\n", "registered": "2015-06-14T01:43:06 -02:00", "latitude": -50.032668, "longitude": 115.943101, "tags": [ "dolor", "commodo", "aute", "proident", "eu", "deserunt", "ullamco", "cillum", "laborum", "consectetur" ], "friends": [ { "id": 0, "name": "Rachelle Hicks" }, { "id": 1, "name": "Eleanor Nguyen" }, { "id": 2, "name": "Marcella Bell" }, { "id": 3, "name": "Sheri Leonard" }, { "id": 4, "name": "Nelda Hart" } ], "greeting": "Hello, Mildred Mercer! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826c1c89faf53cc021e", "index": 583, "guid": "6333b683-a665-4bd5-8589-9d2b52e5b948", "isActive": false, "balance": "$2,522.43", "picture": "http://placehold.it/32x32", "age": 33, "eyeColor": "blue", "name": "Fitzgerald Carr", "gender": "male", "company": "XYQAG", "email": "fitzgeraldcarr@xyqag.com", "phone": "+1 (817) 525-3108", "address": "121 Highland Boulevard, Cecilia, South Dakota, 4198", "about": "Quis aliquip est quis cillum voluptate fugiat consequat officia culpa non laborum. Ex incididunt Lorem sit labore deserunt cillum nisi excepteur. Aliqua amet ex nulla cupidatat ut ut aute dolor aliqua reprehenderit ea. Pariatur ex exercitation anim cillum mollit nisi deserunt do cillum voluptate sint sint.\r\n", "registered": "2014-07-13T03:26:10 -02:00", "latitude": 18.566308, "longitude": 88.913801, "tags": [ "ut", "exercitation", "dolore", "deserunt", "fugiat", "dolor", "nostrud", "exercitation", "anim", "Lorem" ], "friends": [ { "id": 0, "name": "Crosby Mcgee" }, { "id": 1, "name": "Bianca Smith" }, { "id": 2, "name": "Schroeder Riggs" }, { "id": 3, "name": "Agnes Oneil" }, { "id": 4, "name": "Carlson Cobb" } ], "greeting": "Hello, Fitzgerald Carr! You have 8 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48263e1b2e2eb8886e1e", "index": 584, "guid": "1499ced2-da64-4d55-8510-76b6bc2c814e", "isActive": false, "balance": "$3,031.16", "picture": "http://placehold.it/32x32", "age": 30, "eyeColor": "green", "name": "Araceli Velez", "gender": "female", "company": "LIQUICOM", "email": "aracelivelez@liquicom.com", "phone": "+1 (956) 536-3088", "address": "230 Wortman Avenue, Brandywine, District Of Columbia, 9568", "about": "Non adipisicing esse laborum sit eiusmod do amet ea adipisicing occaecat tempor cupidatat. In amet consectetur consequat in non. Eiusmod laborum fugiat est anim velit velit id adipisicing labore enim officia minim. Aliqua et nulla aute nostrud incididunt nisi nisi culpa amet aliqua excepteur fugiat laboris sunt. Sunt non dolor qui occaecat consectetur voluptate nulla labore consectetur. Dolore non qui exercitation ipsum ullamco mollit. Quis minim proident quis quis laborum.\r\n", "registered": "2017-07-26T12:35:04 -02:00", "latitude": -17.543941, "longitude": 163.488608, "tags": [ "incididunt", "duis", "Lorem", "enim", "irure", "non", "ullamco", "aliquip", "reprehenderit", "ea" ], "friends": [ { "id": 0, "name": "Dolores Wiley" }, { "id": 1, "name": "Suarez Doyle" }, { "id": 2, "name": "Etta Rogers" }, { "id": 3, "name": "Strong Lamb" }, { "id": 4, "name": "Prince Juarez" } ], "greeting": "Hello, Araceli Velez! You have 2 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826c61623d0748e79eb", "index": 585, "guid": "c4a5fd2d-2c8c-47a1-91c0-cf5286c8943f", "isActive": true, "balance": "$3,648.39", "picture": "http://placehold.it/32x32", "age": 20, "eyeColor": "green", "name": "Mara Duran", "gender": "female", "company": "PYRAMI", "email": "maraduran@pyrami.com", "phone": "+1 (850) 514-3082", "address": "983 Campus Place, Tyhee, Puerto Rico, 1282", "about": "Adipisicing adipisicing cillum consequat velit exercitation. Nulla magna do magna exercitation Lorem enim elit sunt sint excepteur enim adipisicing sint sunt. Ut veniam eiusmod officia occaecat consequat ad reprehenderit aliquip laboris esse ea ipsum Lorem non.\r\n", "registered": "2016-12-11T08:39:17 -01:00", "latitude": 30.5086, "longitude": 36.120084, "tags": [ "fugiat", "pariatur", "nulla", "dolore", "nulla", "non", "nulla", "aliqua", "laborum", "aute" ], "friends": [ { "id": 0, "name": "Rosanne Rowe" }, { "id": 1, "name": "Joyce Roberson" }, { "id": 2, "name": "Gibson Beach" }, { "id": 3, "name": "Riggs Schneider" }, { "id": 4, "name": "Ashlee Sharp" } ], "greeting": "Hello, Mara Duran! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826170eb1f828b62b4e", "index": 586, "guid": "469d79fd-60df-4b75-a616-fd1aae2167b1", "isActive": true, "balance": "$3,751.91", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "blue", "name": "Lilia Rocha", "gender": "female", "company": "EARWAX", "email": "liliarocha@earwax.com", "phone": "+1 (949) 425-2932", "address": "884 Wakeman Place, Crawfordsville, Maine, 4553", "about": "Lorem qui do fugiat dolor aliquip minim voluptate ut elit irure consequat. Velit voluptate labore et commodo eu sit officia duis deserunt duis. Nostrud cillum pariatur cillum pariatur ullamco aliquip amet aliqua irure incididunt sint aute fugiat. Nostrud irure aute quis consequat id consectetur dolore. Commodo duis do dolore anim consequat cupidatat. Do in veniam cupidatat ex. Sunt velit reprehenderit qui duis sint fugiat esse velit ullamco deserunt.\r\n", "registered": "2017-03-02T10:36:27 -01:00", "latitude": -69.500523, "longitude": 19.526922, "tags": [ "exercitation", "deserunt", "veniam", "id", "minim", "ex", "fugiat", "Lorem", "nisi", "enim" ], "friends": [ { "id": 0, "name": "Osborne Key" }, { "id": 1, "name": "Higgins Barr" }, { "id": 2, "name": "Morgan Valdez" }, { "id": 3, "name": "Patricia Kennedy" }, { "id": 4, "name": "Sexton Marsh" } ], "greeting": "Hello, Lilia Rocha! You have 7 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826546e72a55fda0326", "index": 587, "guid": "f6c32c04-be45-48b7-ac34-bd261539bd01", "isActive": true, "balance": "$2,229.21", "picture": "http://placehold.it/32x32", "age": 38, "eyeColor": "blue", "name": "Garner Talley", "gender": "male", "company": "URBANSHEE", "email": "garnertalley@urbanshee.com", "phone": "+1 (937) 559-2820", "address": "638 Metropolitan Avenue, Callaghan, New Jersey, 2397", "about": "Irure anim sit culpa aliqua. Irure consectetur ex qui est. Laboris mollit duis sint eiusmod proident eiusmod esse voluptate anim. Pariatur ex et fugiat deserunt. Adipisicing do voluptate irure magna adipisicing est nisi quis ea nostrud reprehenderit do mollit. Pariatur ad ad deserunt voluptate.\r\n", "registered": "2017-11-15T12:02:06 -01:00", "latitude": -9.161601, "longitude": -171.535959, "tags": [ "incididunt", "aute", "eu", "dolore", "consectetur", "laborum", "dolor", "pariatur", "incididunt", "consequat" ], "friends": [ { "id": 0, "name": "Reeves King" }, { "id": 1, "name": "Susanna Manning" }, { "id": 2, "name": "Angelique Pittman" }, { "id": 3, "name": "Mcknight Bradford" }, { "id": 4, "name": "Day Kane" } ], "greeting": "Hello, Garner Talley! You have 9 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826c7a922e3c116e973", "index": 588, "guid": "035a8fe9-d692-41ef-bffe-d123152daf7e", "isActive": false, "balance": "$1,664.42", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "green", "name": "Mckay Mendoza", "gender": "male", "company": "NAVIR", "email": "mckaymendoza@navir.com", "phone": "+1 (916) 403-2969", "address": "443 Bergen Street, Camptown, Michigan, 3294", "about": "Commodo reprehenderit aute dolor deserunt nostrud sint velit labore est tempor. Exercitation fugiat laborum dolore culpa elit fugiat laborum elit consectetur dolor aute cillum. Ad culpa fugiat sit ad sint ad occaecat ea ex veniam cupidatat veniam sit est. Mollit enim nostrud pariatur anim dolore fugiat ut consectetur nisi. Nulla labore nulla anim cupidatat laboris mollit. Consectetur et labore non irure.\r\n", "registered": "2014-03-11T08:27:19 -01:00", "latitude": -42.417082, "longitude": -172.788326, "tags": [ "dolore", "magna", "velit", "mollit", "commodo", "ullamco", "quis", "ipsum", "fugiat", "sunt" ], "friends": [ { "id": 0, "name": "Rosa Hall" }, { "id": 1, "name": "Jeannine Le" }, { "id": 2, "name": "Wells Anthony" }, { "id": 3, "name": "Chaney French" }, { "id": 4, "name": "Castaneda Goodman" } ], "greeting": "Hello, Mckay Mendoza! You have 9 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e48263d569c782bd3c8c7", "index": 589, "guid": "15631ac8-b903-416a-811c-1f611e96d9a6", "isActive": false, "balance": "$2,174.17", "picture": "http://placehold.it/32x32", "age": 24, "eyeColor": "brown", "name": "Woodard Ashley", "gender": "male", "company": "ORBIN", "email": "woodardashley@orbin.com", "phone": "+1 (867) 506-2650", "address": "910 Dare Court, Gadsden, Rhode Island, 9142", "about": "Esse ut consectetur irure aute duis ullamco aute. Exercitation elit aute eiusmod pariatur irure non. Quis voluptate consequat amet esse adipisicing officia proident ut enim velit do ea. Est fugiat do tempor labore excepteur eiusmod. Cupidatat occaecat occaecat elit minim occaecat eu nulla officia dolor enim.\r\n", "registered": "2014-12-17T10:41:16 -01:00", "latitude": 7.390884, "longitude": -96.485103, "tags": [ "proident", "cupidatat", "ullamco", "dolor", "aute", "culpa", "deserunt", "mollit", "eiusmod", "quis" ], "friends": [ { "id": 0, "name": "Galloway Skinner" }, { "id": 1, "name": "Adkins Woodward" }, { "id": 2, "name": "Vanessa Barry" }, { "id": 3, "name": "Leona Mack" }, { "id": 4, "name": "Rosemary Woods" } ], "greeting": "Hello, Woodard Ashley! You have 1 unread messages.", "favoriteFruit": "banana" }, { "_id": "5a5e4826a15a0f84b42f8dc3", "index": 590, "guid": "bdf56277-7b3b-4a87-8b54-507d87197b1b", "isActive": false, "balance": "$2,299.42", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "blue", "name": "Kane Bishop", "gender": "male", "company": "DYMI", "email": "kanebishop@dymi.com", "phone": "+1 (859) 560-2818", "address": "982 Wythe Avenue, Fedora, Kansas, 1394", "about": "Officia commodo non exercitation tempor ullamco nisi. Dolor reprehenderit Lorem excepteur sunt in. Nisi consequat cillum fugiat anim sint elit. Occaecat tempor aliquip dolore magna eu ut.\r\n", "registered": "2014-09-29T03:08:16 -02:00", "latitude": -27.030399, "longitude": 171.986362, "tags": [ "do", "ipsum", "ad", "cupidatat", "cupidatat", "duis", "aliquip", "commodo", "excepteur", "culpa" ], "friends": [ { "id": 0, "name": "Trujillo Sanders" }, { "id": 1, "name": "Rosalyn Mcpherson" }, { "id": 2, "name": "Wilson Oneill" }, { "id": 3, "name": "Giles Rhodes" }, { "id": 4, "name": "Marta Ball" } ], "greeting": "Hello, Kane Bishop! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48268994e15ff6c9bb19", "index": 591, "guid": "04f34bba-dce6-449c-8e0a-a8b606fa45e6", "isActive": true, "balance": "$3,285.74", "picture": "http://placehold.it/32x32", "age": 32, "eyeColor": "brown", "name": "Lola Acosta", "gender": "female", "company": "TEMORAK", "email": "lolaacosta@temorak.com", "phone": "+1 (835) 478-3293", "address": "842 Bush Street, Fontanelle, West Virginia, 230", "about": "Cupidatat minim labore incididunt reprehenderit non do non sint velit laboris incididunt. Adipisicing minim fugiat labore pariatur. Minim duis aliquip enim anim qui voluptate qui ut occaecat. In nostrud veniam occaecat exercitation cupidatat irure et incididunt sit elit occaecat. Ex aute voluptate ad amet est aliqua ipsum tempor ullamco. Amet exercitation velit sint Lorem non in cupidatat et irure labore qui. Pariatur sit occaecat amet laborum ad velit occaecat aute mollit voluptate aute.\r\n", "registered": "2014-01-13T04:31:27 -01:00", "latitude": -51.178831, "longitude": -26.042132, "tags": [ "laborum", "magna", "anim", "fugiat", "est", "sint", "cillum", "laboris", "esse", "sint" ], "friends": [ { "id": 0, "name": "Patrick Cox" }, { "id": 1, "name": "Kara Cleveland" }, { "id": 2, "name": "Britney Flynn" }, { "id": 3, "name": "Guerra Martinez" }, { "id": 4, "name": "Wise Sutton" } ], "greeting": "Hello, Lola Acosta! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48262609104247e4026d", "index": 592, "guid": "7f234378-9904-4038-9b7c-56528e21b701", "isActive": true, "balance": "$3,555.48", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "green", "name": "Johnson Jennings", "gender": "male", "company": "ZILIDIUM", "email": "johnsonjennings@zilidium.com", "phone": "+1 (895) 569-2200", "address": "686 Osborn Street, Shelby, American Samoa, 2826", "about": "Aliqua consequat magna officia ullamco cillum. Exercitation magna magna ipsum non fugiat ad consectetur labore dolore excepteur sit sint. Occaecat minim ea eu amet anim. Aliqua ad voluptate cupidatat eu incididunt occaecat sit ut. Fugiat incididunt pariatur anim aliqua do aute in amet fugiat aute mollit. Ullamco eu elit reprehenderit do officia deserunt. Laborum ea in qui velit deserunt tempor incididunt voluptate magna occaecat deserunt laboris irure.\r\n", "registered": "2017-02-07T04:57:25 -01:00", "latitude": -35.98246, "longitude": 131.914486, "tags": [ "amet", "incididunt", "cillum", "id", "aute", "in", "et", "do", "consequat", "eu" ], "friends": [ { "id": 0, "name": "Brady Bender" }, { "id": 1, "name": "Mcclure Norton" }, { "id": 2, "name": "Marcia Mosley" }, { "id": 3, "name": "Hubbard Ray" }, { "id": 4, "name": "Pollard Banks" } ], "greeting": "Hello, Johnson Jennings! You have 1 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e48268cc48256d7b82693", "index": 593, "guid": "91613421-0a3c-4a91-8ae1-c92de2c556c4", "isActive": true, "balance": "$1,572.26", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "green", "name": "Williams Bennett", "gender": "male", "company": "PROGENEX", "email": "williamsbennett@progenex.com", "phone": "+1 (911) 555-2468", "address": "350 Euclid Avenue, Corinne, Maryland, 2257", "about": "Eu elit dolor fugiat officia voluptate. Veniam et incididunt consequat enim qui tempor fugiat deserunt est consectetur eiusmod. Excepteur aliquip occaecat occaecat aliquip duis.\r\n", "registered": "2014-06-04T12:54:49 -02:00", "latitude": -18.433185, "longitude": -7.428643, "tags": [ "tempor", "eiusmod", "id", "reprehenderit", "non", "cillum", "aute", "magna", "et", "nulla" ], "friends": [ { "id": 0, "name": "Betty Orr" }, { "id": 1, "name": "Bradford Stanton" }, { "id": 2, "name": "Robbins Bryant" }, { "id": 3, "name": "Tara Petty" }, { "id": 4, "name": "Sherman Weber" } ], "greeting": "Hello, Williams Bennett! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e48263d8a58955c8862e0", "index": 594, "guid": "a4aa552c-ce42-48de-9fc1-71af534735cf", "isActive": false, "balance": "$3,666.42", "picture": "http://placehold.it/32x32", "age": 22, "eyeColor": "blue", "name": "Palmer Romero", "gender": "male", "company": "ORONOKO", "email": "palmerromero@oronoko.com", "phone": "+1 (950) 538-2624", "address": "912 Beach Place, Canoochee, California, 9522", "about": "Laborum Lorem magna sint in magna in ut. Fugiat cupidatat excepteur eiusmod eiusmod irure veniam amet qui incididunt enim irure labore occaecat occaecat. Enim anim duis nostrud mollit reprehenderit. Tempor irure culpa reprehenderit proident elit consequat tempor exercitation. Ipsum elit dolor cillum duis. Cillum dolor duis ipsum qui magna magna irure esse aliqua irure velit elit veniam.\r\n", "registered": "2014-12-16T06:57:55 -01:00", "latitude": -37.25509, "longitude": -51.780911, "tags": [ "consectetur", "pariatur", "eiusmod", "mollit", "et", "do", "Lorem", "dolore", "deserunt", "est" ], "friends": [ { "id": 0, "name": "Alissa Price" }, { "id": 1, "name": "Riddle Steele" }, { "id": 2, "name": "Hatfield Stark" }, { "id": 3, "name": "Booker Alston" }, { "id": 4, "name": "Hancock Norman" } ], "greeting": "Hello, Palmer Romero! You have 3 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482693e4d055a68bc37e", "index": 595, "guid": "68c1da9e-e8e5-470b-9662-9dfce618fd5d", "isActive": false, "balance": "$1,766.61", "picture": "http://placehold.it/32x32", "age": 21, "eyeColor": "brown", "name": "Long Morrow", "gender": "male", "company": "MIRACLIS", "email": "longmorrow@miraclis.com", "phone": "+1 (893) 590-2887", "address": "822 Little Street, Canby, Utah, 8575", "about": "Aute exercitation nostrud ea ex ea consequat velit commodo. Dolor velit id elit aliqua occaecat adipisicing nulla consequat est. Nisi est pariatur ullamco aliqua incididunt. Dolor commodo fugiat ipsum sunt cupidatat enim do. Adipisicing dolore esse non anim.\r\n", "registered": "2014-03-14T12:57:43 -01:00", "latitude": 34.288808, "longitude": -77.263211, "tags": [ "cupidatat", "enim", "excepteur", "eiusmod", "cupidatat", "dolor", "deserunt", "consequat", "do", "commodo" ], "friends": [ { "id": 0, "name": "Isabella Bowers" }, { "id": 1, "name": "Ernestine Crawford" }, { "id": 2, "name": "Payne Robbins" }, { "id": 3, "name": "Ida Silva" }, { "id": 4, "name": "Delia Kaufman" } ], "greeting": "Hello, Long Morrow! You have 10 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826755ed84e5adfbbc4", "index": 596, "guid": "1e983d8e-b98d-4b5c-a058-bb14029d9376", "isActive": false, "balance": "$3,968.77", "picture": "http://placehold.it/32x32", "age": 34, "eyeColor": "brown", "name": "Berry Crane", "gender": "male", "company": "AVIT", "email": "berrycrane@avit.com", "phone": "+1 (940) 576-2188", "address": "747 Pierrepont Place, Lloyd, Iowa, 9926", "about": "Quis ut commodo fugiat in fugiat nisi non cupidatat esse sunt laborum aliqua veniam. Nisi id laborum reprehenderit exercitation sint duis pariatur amet in. Incididunt irure velit elit aliqua laboris consequat sunt irure laborum irure consectetur consectetur adipisicing fugiat. Adipisicing amet magna dolore laboris reprehenderit sint quis minim. Cupidatat ullamco ut non do pariatur in consequat dolore consequat sit labore. Velit exercitation dolor excepteur irure anim eiusmod sit proident adipisicing quis mollit dolor.\r\n", "registered": "2017-08-02T10:15:55 -02:00", "latitude": -41.716963, "longitude": 100.104402, "tags": [ "mollit", "in", "nostrud", "ipsum", "fugiat", "occaecat", "cupidatat", "do", "reprehenderit", "ullamco" ], "friends": [ { "id": 0, "name": "Linda Robertson" }, { "id": 1, "name": "Helena Rosa" }, { "id": 2, "name": "Carson Mccarthy" }, { "id": 3, "name": "Oneil Pace" }, { "id": 4, "name": "Leann Parker" } ], "greeting": "Hello, Berry Crane! You have 4 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e4826e83b126cb17aa56e", "index": 597, "guid": "33c3ed79-094e-41b8-b323-f2e03a7314f6", "isActive": true, "balance": "$2,453.40", "picture": "http://placehold.it/32x32", "age": 23, "eyeColor": "brown", "name": "Hoffman Francis", "gender": "male", "company": "CONCILITY", "email": "hoffmanfrancis@concility.com", "phone": "+1 (889) 505-3410", "address": "537 Pineapple Street, Finzel, North Dakota, 5363", "about": "Ullamco dolore exercitation consequat aute Lorem esse pariatur incididunt occaecat velit nostrud voluptate sint. Eu duis minim voluptate cupidatat nisi elit commodo. Fugiat cillum esse ipsum aliqua tempor id id labore amet enim elit mollit culpa. Dolore minim ea sit duis voluptate non. Fugiat eu esse nostrud mollit qui.\r\n", "registered": "2015-03-05T11:42:56 -01:00", "latitude": -78.393405, "longitude": 74.144848, "tags": [ "in", "adipisicing", "ullamco", "veniam", "adipisicing", "veniam", "sint", "laborum", "exercitation", "officia" ], "friends": [ { "id": 0, "name": "Stanton Tyler" }, { "id": 1, "name": "Pratt Dejesus" }, { "id": 2, "name": "Mack Bonner" }, { "id": 3, "name": "Bridges Macias" }, { "id": 4, "name": "Hopkins Ayala" } ], "greeting": "Hello, Hoffman Francis! You have 10 unread messages.", "favoriteFruit": "strawberry" }, { "_id": "5a5e482645561834debb843f", "index": 598, "guid": "b3143cdc-75bd-41a6-875a-dc1d78be1a39", "isActive": true, "balance": "$1,889.20", "picture": "http://placehold.it/32x32", "age": 35, "eyeColor": "green", "name": "Parker Cherry", "gender": "male", "company": "ISOTRACK", "email": "parkercherry@isotrack.com", "phone": "+1 (852) 568-2145", "address": "211 Eckford Street, Saranap, Kentucky, 9113", "about": "Elit officia Lorem nisi in reprehenderit proident consequat. Ut dolor deserunt irure dolor est. Tempor est cillum dolor culpa quis. Irure sit minim amet aute esse mollit ut officia est non quis culpa. Laborum do cupidatat sint nulla veniam ea ex ex nostrud excepteur aliqua sint amet. Aliquip deserunt cupidatat et adipisicing ipsum nostrud sit ut adipisicing cupidatat commodo duis.\r\n", "registered": "2015-04-11T07:40:22 -02:00", "latitude": 46.649787, "longitude": 87.384361, "tags": [ "qui", "sit", "labore", "velit", "non", "deserunt", "consectetur", "deserunt", "ex", "quis" ], "friends": [ { "id": 0, "name": "Rollins Long" }, { "id": 1, "name": "Lewis Burgess" }, { "id": 2, "name": "Good Jefferson" }, { "id": 3, "name": "Alvarez Oliver" }, { "id": 4, "name": "Mclaughlin Barton" } ], "greeting": "Hello, Parker Cherry! You have 3 unread messages.", "favoriteFruit": "apple" }, { "_id": "5a5e4826d55e88fc6a42e2de", "index": 599, "guid": "2adcf074-a156-4f6d-b2ec-c34b769d0e13", "isActive": true, "balance": "$3,320.30", "picture": "http://placehold.it/32x32", "age": 37, "eyeColor": "green", "name": "Claudette Olson", "gender": "female", "company": "REPETWIRE", "email": "claudetteolson@repetwire.com", "phone": "+1 (956) 585-2192", "address": "334 Ovington Avenue, Manitou, Colorado, 7655", "about": "Sint mollit eiusmod id laborum duis proident elit duis esse id veniam nulla eiusmod sint. Deserunt sit veniam consectetur nisi exercitation non tempor ex aliqua mollit fugiat in dolore non. Nisi Lorem ad consectetur Lorem ea exercitation. Commodo ad aute amet sint excepteur velit dolor ipsum sit. Aliqua aliquip culpa velit enim sit minim ullamco consequat nostrud cupidatat et mollit nisi amet. Nulla quis et et mollit ea laborum deserunt veniam.\r\n", "registered": "2014-05-27T02:40:14 -02:00", "latitude": 13.555204, "longitude": -81.039574, "tags": [ "enim", "quis", "excepteur", "voluptate", "do", "et", "voluptate", "quis", "consequat", "consectetur" ], "friends": [ { "id": 0, "name": "Lydia Stephens" }, { "id": 1, "name": "Olson Miller" }, { "id": 2, "name": "Hughes Zimmerman" }, { "id": 3, "name": "Estrada Fry" }, { "id": 4, "name": "Dillon Waters" } ], "greeting": "Hello, Claudette Olson! You have 6 unread messages.", "favoriteFruit": "apple" } ] ================================================ FILE: __performance_tests__/incremental.mjs ================================================ "use strict" import {measure} from "./measure.mjs" import {produce, setAutoFreeze} from "../dist/immer.mjs" import cloneDeep from "lodash.clonedeep" import Immutable from "immutable" console.log("\n# incremental - lot of small incremental changes\n") function createTestObject() { return { a: 1, b: "Some data here" } } const MAX = 1000 const baseState = { ids: [], map: Object.create(null) } let immutableJsBaseState immutableJsBaseState = { ids: Immutable.List(), map: Immutable.Map() } measure( "just mutate", () => cloneDeep(baseState), draft => { for (let i = 0; i < MAX; i++) { draft.ids.push(i) draft.map[i] = createTestObject() } } ) measure( "handcrafted reducer", () => cloneDeep(baseState), state => { for (let i = 0; i < MAX; i++) { state = { ids: [...state.ids, i], map: { ...state.map, [i]: createTestObject() } } } } ) measure( "immutableJS", () => immutableJsBaseState, state => { for (let i = 0; i < MAX; i++) { state = { ids: state.ids.push(i), map: state.map.set(i, createTestObject()) } } } ) measure( "immer", () => { setAutoFreeze(false) return baseState }, state => { for (let i = 0; i < MAX; i++) { state = produce(state, draft => { draft.ids.push(i) draft.map[i] = createTestObject() }) } } ) measure( "immer - single produce", () => { setAutoFreeze(false) return baseState }, state => { produce(state, draft => { for (let i = 0; i < MAX; i++) { draft.ids.push(i) draft.map[i] = createTestObject() } }) } ) ================================================ FILE: __performance_tests__/large-obj.mjs ================================================ import {measure} from "./measure.mjs" import { produce, setUseStrictShallowCopy } from "../dist/immer.mjs" console.log("\n# large-obj - mutate large object\n") const MAX = 50 const baseState = Object.fromEntries( Array(10000) .fill(0) .map((_, i) => [i, i]) ) measure("immer - with setUseStrictShallowCopy", () => { setUseStrictShallowCopy(true) for (let i = 0; i < MAX; i++) { produce(baseState, draft => { draft[5000]++ }) } }) measure("immer - without setUseStrictShallowCopy", () => { setUseStrictShallowCopy(false) for (let i = 0; i < MAX; i++) { produce(baseState, draft => { draft[5000]++ }) } }) ================================================ FILE: __performance_tests__/measure.mjs ================================================ "use strict" function measureTime(setup, fn) { if (!fn) { fn = setup setup = () => {} } const args = setup() global.gc && global.gc() const startTime = Date.now() fn(args) const endTime = Date.now() return endTime - startTime } export function measure(name, setup, fn) { const times = [...Array(5)].map(() => measureTime(setup, fn)) const medianTime = times.sort()[Math.round(times.length / 2)] console.log(`${name}: ${medianTime}ms`) } ================================================ FILE: __performance_tests__/todo.mjs ================================================ "use strict" import {measure} from "./measure.mjs" import { enablePatches, produce, setAutoFreeze } from "../dist/immer.mjs" import cloneDeep from "lodash.clonedeep" import immutable from "immutable" import Seamless from "seamless-immutable" import deepFreeze from "deep-freeze" const {List, Record} = immutable function freeze(x) { Object.freeze(x) return x } const MAX = 50000 const MODIFY_FACTOR = 0.1 const baseState = [] let frozenBazeState let immutableJsBaseState let seamlessBaseState // produce the base state for (let i = 0; i < MAX; i++) { baseState.push({ todo: "todo_" + i, done: false, someThingCompletelyIrrelevant: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] }) } // Produce the frozen bazeState frozenBazeState = deepFreeze(cloneDeep(baseState)) // generate immutalbeJS base state const todoRecord = Record({ todo: "", done: false, someThingCompletelyIrrelevant: [] }) immutableJsBaseState = List(baseState.map(todo => todoRecord(todo))) // generate seamless-immutable base state seamlessBaseState = Seamless.from(baseState) console.log("\n# todo - performance\n") measure( "just mutate", () => ({draft: cloneDeep(baseState)}), ({draft}) => { for (let i = 0; i < MAX * MODIFY_FACTOR; i++) { draft[i].done = true } } ) measure( "just mutate, freeze", () => ({draft: cloneDeep(baseState)}), ({draft}) => { for (let i = 0; i < MAX * MODIFY_FACTOR; i++) { draft[i].done = true } deepFreeze(draft) } ) measure("deepclone, then mutate", () => { const draft = cloneDeep(baseState) for (let i = 0; i < MAX * MODIFY_FACTOR; i++) { draft[i].done = true } }) measure("deepclone, then mutate, then freeze", () => { const draft = cloneDeep(baseState) for (let i = 0; i < MAX * MODIFY_FACTOR; i++) { draft[i].done = true } deepFreeze(draft) }) measure("handcrafted reducer (no freeze)", () => { const nextState = [ ...baseState.slice(0, MAX * MODIFY_FACTOR).map(todo => ({ ...todo, done: true })), ...baseState.slice(MAX * MODIFY_FACTOR) ] }) measure("handcrafted reducer (with freeze)", () => { const nextState = freeze([ ...baseState.slice(0, MAX * MODIFY_FACTOR).map(todo => freeze({ ...todo, done: true }) ), ...baseState.slice(MAX * MODIFY_FACTOR) ]) }) measure("naive handcrafted reducer (without freeze)", () => { const nextState = baseState.map((todo, index) => { if (index < MAX * MODIFY_FACTOR) return { ...todo, done: true } else return todo }) }) measure("naive handcrafted reducer (with freeze)", () => { const nextState = deepFreeze( baseState.map((todo, index) => { if (index < MAX * MODIFY_FACTOR) return { ...todo, done: true } else return todo }) ) }) measure("immutableJS", () => { let state = immutableJsBaseState state.withMutations(state => { for (let i = 0; i < MAX * MODIFY_FACTOR; i++) { state.setIn([i, "done"], true) } }) }) measure("immutableJS + toJS", () => { let state = immutableJsBaseState .withMutations(state => { for (let i = 0; i < MAX * MODIFY_FACTOR; i++) { state.setIn([i, "done"], true) } }) .toJS() }) measure("seamless-immutable", () => { const state = seamlessBaseState state.map((todo, index) => { if (index < MAX * MODIFY_FACTOR) return todo.set("done", true) else return todo }) }) measure("seamless-immutable + asMutable", () => { const state = seamlessBaseState state .map((todo, index) => { if (index < MAX * MODIFY_FACTOR) return todo.set("done", true) else return todo }) .asMutable({deep: true}) }) measure( "immer - without autofreeze", () => { setAutoFreeze(false) }, () => { produce(baseState, draft => { for (let i = 0; i < MAX * MODIFY_FACTOR; i++) { draft[i].done = true } }) } ) measure( "immer - with autofreeze", () => { setAutoFreeze(true) }, () => { produce(frozenBazeState, draft => { for (let i = 0; i < MAX * MODIFY_FACTOR; i++) { draft[i].done = true } }) } ) measure( "immer - without autofreeze - with patch listener", () => { enablePatches() setAutoFreeze(false) }, () => { produce( baseState, draft => { for (let i = 0; i < MAX * MODIFY_FACTOR; i++) { draft[i].done = true } }, function() {} ) } ) measure( "immer - with autofreeze - with patch listener", () => { enablePatches() setAutoFreeze(true) }, () => { produce( baseState, draft => { for (let i = 0; i < MAX * MODIFY_FACTOR; i++) { draft[i].done = true } }, function() {} ) } ) ================================================ FILE: __tests__/__prod_snapshots__/base.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > set drafts > revokes sets 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > set drafts > revokes sets 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] minified error nr: 11. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] minified error nr: 12. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > set drafts > revokes sets 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > set drafts > revokes sets 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] minified error nr: 11. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] minified error nr: 12. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > map drafts > revokes map proxies 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > map drafts > revokes map proxies 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > set drafts > revokes sets 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > set drafts > revokes sets 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] minified error nr: 11. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] minified error nr: 12. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > map drafts > revokes map proxies 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > map drafts > revokes map proxies 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > set drafts > revokes sets 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > set drafts > revokes sets 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] minified error nr: 11. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] minified error nr: 12. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > map drafts > revokes map proxies 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > map drafts > revokes map proxies 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > set drafts > revokes sets 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > set drafts > revokes sets 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] minified error nr: 11. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] minified error nr: 12. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > set drafts > revokes sets 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > set drafts > revokes sets 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] minified error nr: 11. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] minified error nr: 12. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > map drafts > revokes map proxies 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > map drafts > revokes map proxies 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > set drafts > revokes sets 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > set drafts > revokes sets 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] minified error nr: 11. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] minified error nr: 12. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > map drafts > revokes map proxies 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > map drafts > revokes map proxies 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > set drafts > revokes sets 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > set drafts > revokes sets 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] minified error nr: 11. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] minified error nr: 12. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > map drafts > revokes map proxies 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > map drafts > revokes map proxies 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > set drafts > revokes sets 1`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > set drafts > revokes sets 2`] = `[Error: [Immer] minified error nr: 3. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] minified error nr: 11. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] minified error nr: 12. Full error at: https://bit.ly/3cXEKWf]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] minified error nr: 4. Full error at: https://bit.ly/3cXEKWf]`; exports[`complex nesting map / set / object > modify deep object 1`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 2`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 3`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 4`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 5`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 6`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 7`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 8`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 9`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 10`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 11`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 12`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 13`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 14`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 15`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 16`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 17`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 18`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; ================================================ FILE: __tests__/__prod_snapshots__/curry.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`curry - proxy > should check arguments 1`] = `[Error: [Immer] minified error nr: 6. Full error at: https://bit.ly/3cXEKWf]`; exports[`curry - proxy > should check arguments 2`] = `[Error: [Immer] minified error nr: 6. Full error at: https://bit.ly/3cXEKWf]`; exports[`curry - proxy > should check arguments 3`] = `[Error: [Immer] minified error nr: 6. Full error at: https://bit.ly/3cXEKWf]`; exports[`curry - proxy > should check arguments 4`] = `[Error: [Immer] minified error nr: 7. Full error at: https://bit.ly/3cXEKWf]`; ================================================ FILE: __tests__/__prod_snapshots__/frozen.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`auto freeze - proxy > will freeze maps 1`] = `[Error: [Immer] minified error nr: 2. Full error at: https://bit.ly/3cXEKWf]`; exports[`auto freeze - proxy > will freeze maps 2`] = `[Error: [Immer] minified error nr: 2. Full error at: https://bit.ly/3cXEKWf]`; exports[`auto freeze - proxy > will freeze maps 3`] = `[Error: [Immer] minified error nr: 2. Full error at: https://bit.ly/3cXEKWf]`; exports[`auto freeze - proxy > will freeze sets 1`] = `[Error: [Immer] minified error nr: 2. Full error at: https://bit.ly/3cXEKWf]`; exports[`auto freeze - proxy > will freeze sets 2`] = `[Error: [Immer] minified error nr: 2. Full error at: https://bit.ly/3cXEKWf]`; exports[`auto freeze - proxy > will freeze sets 3`] = `[Error: [Immer] minified error nr: 2. Full error at: https://bit.ly/3cXEKWf]`; ================================================ FILE: __tests__/__prod_snapshots__/manual.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`manual - proxy > cannot finishDraft twice 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`manual - proxy > should check arguments 1`] = `[Error: [Immer] minified error nr: 8. Full error at: https://bit.ly/3cXEKWf]`; exports[`manual - proxy > should check arguments 2`] = `[Error: [Immer] minified error nr: 8. Full error at: https://bit.ly/3cXEKWf]`; exports[`manual - proxy > should check arguments 3`] = `[Error: [Immer] minified error nr: 9. Full error at: https://bit.ly/3cXEKWf]`; exports[`manual - proxy > should not finish twice 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`manual - proxy > should support patches drafts 1`] = ` [ [ [ { "op": "replace", "path": [ "a", ], "value": 2, }, { "op": "add", "path": [ "b", ], "value": 3, }, ], [ { "op": "replace", "path": [ "a", ], "value": 1, }, { "op": "remove", "path": [ "b", ], }, ], ], ] `; ================================================ FILE: __tests__/__prod_snapshots__/patch.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`applyPatches > throws when \`op\` is not "add", "replace", nor "remove" 1`] = `[Error: [Immer] minified error nr: 17. Full error at: https://bit.ly/3cXEKWf]`; exports[`applyPatches > throws when \`path\` cannot be resolved 1`] = `[Error: [Immer] minified error nr: 18. Full error at: https://bit.ly/3cXEKWf]`; exports[`applyPatches > throws when \`path\` cannot be resolved 2`] = `[Error: [Immer] minified error nr: 18. Full error at: https://bit.ly/3cXEKWf]`; ================================================ FILE: __tests__/__prod_snapshots__/plugins.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`error when using Maps 1`] = `[Error: [Immer] minified error nr: 0. Full error at: https://bit.ly/3cXEKWf]`; exports[`error when using patches - 1 1`] = `[Error: [Immer] minified error nr: 0. Full error at: https://bit.ly/3cXEKWf]`; exports[`error when using patches - 2 1`] = `[Error: [Immer] minified error nr: 0. Full error at: https://bit.ly/3cXEKWf]`; exports[`error when using patches - 3 1`] = `[Error: [Immer] minified error nr: 0. Full error at: https://bit.ly/3cXEKWf]`; ================================================ FILE: __tests__/__prod_snapshots__/readme.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`Producers can update Maps 4`] = `[Error: [Immer] minified error nr: 2. Full error at: https://bit.ly/3cXEKWf]`; ================================================ FILE: __tests__/__snapshots__/base.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > array drafts > throws when a non-numeric property is added 1`] = `[Error: [Immer] Immer only supports setting array indices and the 'length' property]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > array drafts > throws when a non-numeric property is deleted 1`] = `[Error: [Immer] Immer only supports deleting array indices]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 2`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 3`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 4`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 5`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 6`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 7`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 8`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > set drafts > revokes sets 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > set drafts > revokes sets 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] Object.defineProperty() cannot be used on an Immer draft]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] Object.setPrototypeOf() cannot be used on an Immer draft]`; exports[`base functionality - array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > array drafts > throws when a non-numeric property is added 1`] = `[Error: [Immer] Immer only supports setting array indices and the 'length' property]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > array drafts > throws when a non-numeric property is deleted 1`] = `[Error: [Immer] Immer only supports deleting array indices]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > revokes the draft once produce returns 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > revokes the draft once produce returns 2`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > revokes the draft once produce returns 3`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > revokes the draft once produce returns 4`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > revokes the draft once produce returns 5`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > revokes the draft once produce returns 6`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > revokes the draft once produce returns 7`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > revokes the draft once produce returns 8`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > set drafts > revokes sets 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > set drafts > revokes sets 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] Object.defineProperty() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] Object.setPrototypeOf() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=false > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > array drafts > throws when a non-numeric property is added 1`] = `[Error: [Immer] Immer only supports setting array indices and the 'length' property]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > array drafts > throws when a non-numeric property is deleted 1`] = `[Error: [Immer] Immer only supports deleting array indices]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > map drafts > revokes map proxies 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > map drafts > revokes map proxies 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > revokes the draft once produce returns 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > revokes the draft once produce returns 2`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > revokes the draft once produce returns 3`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > revokes the draft once produce returns 4`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > revokes the draft once produce returns 5`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > revokes the draft once produce returns 6`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > revokes the draft once produce returns 7`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > revokes the draft once produce returns 8`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > set drafts > revokes sets 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > set drafts > revokes sets 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] Object.defineProperty() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] Object.setPrototypeOf() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=false:shallow-copy=false:use-listener=true > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > array drafts > throws when a non-numeric property is added 1`] = `[Error: [Immer] Immer only supports setting array indices and the 'length' property]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > array drafts > throws when a non-numeric property is deleted 1`] = `[Error: [Immer] Immer only supports deleting array indices]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > map drafts > revokes map proxies 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > map drafts > revokes map proxies 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > revokes the draft once produce returns 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > revokes the draft once produce returns 2`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > revokes the draft once produce returns 3`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > revokes the draft once produce returns 4`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > revokes the draft once produce returns 5`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > revokes the draft once produce returns 6`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > revokes the draft once produce returns 7`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > revokes the draft once produce returns 8`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > set drafts > revokes sets 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > set drafts > revokes sets 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] Object.defineProperty() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] Object.setPrototypeOf() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=false > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > array drafts > throws when a non-numeric property is added 1`] = `[Error: [Immer] Immer only supports setting array indices and the 'length' property]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > array drafts > throws when a non-numeric property is deleted 1`] = `[Error: [Immer] Immer only supports deleting array indices]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > map drafts > revokes map proxies 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > map drafts > revokes map proxies 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > revokes the draft once produce returns 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > revokes the draft once produce returns 2`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > revokes the draft once produce returns 3`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > revokes the draft once produce returns 4`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > revokes the draft once produce returns 5`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > revokes the draft once produce returns 6`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > revokes the draft once produce returns 7`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > revokes the draft once produce returns 8`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > set drafts > revokes sets 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > set drafts > revokes sets 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] Object.defineProperty() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] Object.setPrototypeOf() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=false:shallow-copy=true:use-listener=true > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > array drafts > throws when a non-numeric property is added 1`] = `[Error: [Immer] Immer only supports setting array indices and the 'length' property]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > array drafts > throws when a non-numeric property is deleted 1`] = `[Error: [Immer] Immer only supports deleting array indices]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > map drafts > revokes map proxies 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 2`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 3`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 4`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 5`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 6`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 7`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > revokes the draft once produce returns 8`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > set drafts > revokes sets 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > set drafts > revokes sets 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] Object.defineProperty() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] Object.setPrototypeOf() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=false > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > array drafts > throws when a non-numeric property is added 1`] = `[Error: [Immer] Immer only supports setting array indices and the 'length' property]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > array drafts > throws when a non-numeric property is deleted 1`] = `[Error: [Immer] Immer only supports deleting array indices]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > map drafts > revokes map proxies 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > map drafts > revokes map proxies 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > revokes the draft once produce returns 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > revokes the draft once produce returns 2`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > revokes the draft once produce returns 3`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > revokes the draft once produce returns 4`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > revokes the draft once produce returns 5`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > revokes the draft once produce returns 6`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > revokes the draft once produce returns 7`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > revokes the draft once produce returns 8`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > set drafts > revokes sets 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > set drafts > revokes sets 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] Object.defineProperty() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] Object.setPrototypeOf() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=true:shallow-copy=false:use-listener=true > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > array drafts > throws when a non-numeric property is added 1`] = `[Error: [Immer] Immer only supports setting array indices and the 'length' property]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > array drafts > throws when a non-numeric property is deleted 1`] = `[Error: [Immer] Immer only supports deleting array indices]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > map drafts > revokes map proxies 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > map drafts > revokes map proxies 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > revokes the draft once produce returns 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > revokes the draft once produce returns 2`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > revokes the draft once produce returns 3`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > revokes the draft once produce returns 4`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > revokes the draft once produce returns 5`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > revokes the draft once produce returns 6`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > revokes the draft once produce returns 7`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > revokes the draft once produce returns 8`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > set drafts > revokes sets 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > set drafts > revokes sets 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] Object.defineProperty() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] Object.setPrototypeOf() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=false > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > array drafts > throws when a non-numeric property is added 1`] = `[Error: [Immer] Immer only supports setting array indices and the 'length' property]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > array drafts > throws when a non-numeric property is deleted 1`] = `[Error: [Immer] Immer only supports deleting array indices]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > map drafts > revokes map proxies 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > map drafts > revokes map proxies 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > recipe functions > cannot return a modified child draft 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > revokes the draft once produce returns 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > revokes the draft once produce returns 2`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > revokes the draft once produce returns 3`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > revokes the draft once produce returns 4`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > revokes the draft once produce returns 5`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > revokes the draft once produce returns 6`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > revokes the draft once produce returns 7`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > revokes the draft once produce returns 8`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > set drafts > revokes sets 1`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > set drafts > revokes sets 2`] = `[Error: [Immer] Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? {}]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > throws when Object.defineProperty() is used on drafts 1`] = `[Error: [Immer] Object.defineProperty() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > throws when Object.setPrototypeOf() is used on a draft 1`] = `[Error: [Immer] Object.setPrototypeOf() cannot be used on an Immer draft]`; exports[`base functionality - auto-freeze=true:shallow-copy=true:use-listener=true > throws when the draft is modified and another object is returned 1`] = `[Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.]`; exports[`complex nesting map / set / object > modify deep object 1`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 2`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 3`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 4`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 5`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 6`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 7`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 8`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 9`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 10`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 11`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 12`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 13`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 14`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 15`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 16`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; exports[`complex nesting map / set / object > modify deep object 17`] = ` { "map": Map { "set1" => Set { { "a": 2, }, { "b": 2, }, }, "set2" => Set { { "c": 3, }, }, }, } `; exports[`complex nesting map / set / object > modify deep object 18`] = ` [ { "op": "remove", "path": [ "map", "set1", 0, ], "value": { "a": 1, }, }, { "op": "add", "path": [ "map", "set1", 0, ], "value": { "a": 2, }, }, ] `; ================================================ FILE: __tests__/__snapshots__/curry.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`curry - proxy > should check arguments 1`] = `[Error: [Immer] The first or second argument to \`produce\` must be a function]`; exports[`curry - proxy > should check arguments 2`] = `[Error: [Immer] The first or second argument to \`produce\` must be a function]`; exports[`curry - proxy > should check arguments 3`] = `[Error: [Immer] The first or second argument to \`produce\` must be a function]`; exports[`curry - proxy > should check arguments 4`] = `[Error: [Immer] The third argument to \`produce\` must be a function or undefined]`; ================================================ FILE: __tests__/__snapshots__/frozen.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`auto freeze - proxy > will freeze maps 1`] = `[Error: [Immer] This object has been frozen and should not be mutated]`; exports[`auto freeze - proxy > will freeze maps 2`] = `[Error: [Immer] This object has been frozen and should not be mutated]`; exports[`auto freeze - proxy > will freeze maps 3`] = `[Error: [Immer] This object has been frozen and should not be mutated]`; exports[`auto freeze - proxy > will freeze sets 1`] = `[Error: [Immer] This object has been frozen and should not be mutated]`; exports[`auto freeze - proxy > will freeze sets 2`] = `[Error: [Immer] This object has been frozen and should not be mutated]`; exports[`auto freeze - proxy > will freeze sets 3`] = `[Error: [Immer] This object has been frozen and should not be mutated]`; ================================================ FILE: __tests__/__snapshots__/manual.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`manual - proxy > cannot finishDraft twice 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`manual - proxy > cannot modify after finish 1`] = `[TypeError: Cannot perform 'set' on a proxy that has been revoked]`; exports[`manual - proxy > should check arguments 1`] = `[Error: [Immer] First argument to \`createDraft\` must be a plain object, an array, or an immerable object]`; exports[`manual - proxy > should check arguments 2`] = `[Error: [Immer] First argument to \`createDraft\` must be a plain object, an array, or an immerable object]`; exports[`manual - proxy > should check arguments 3`] = `[Error: [Immer] First argument to \`finishDraft\` must be a draft returned by \`createDraft\`]`; exports[`manual - proxy > should not finish drafts from produce 1`] = `[Error: [Immer] First argument to \`finishDraft\` must be a draft returned by \`createDraft\`]`; exports[`manual - proxy > should not finish twice 1`] = `[TypeError: Cannot perform 'get' on a proxy that has been revoked]`; exports[`manual - proxy > should support patches drafts 1`] = ` [ [ [ { "op": "replace", "path": [ "a", ], "value": 2, }, { "op": "add", "path": [ "b", ], "value": 3, }, ], [ { "op": "replace", "path": [ "a", ], "value": 1, }, { "op": "remove", "path": [ "b", ], }, ], ], ] `; ================================================ FILE: __tests__/__snapshots__/patch.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`applyPatches > throws when \`op\` is not "add", "replace", nor "remove" 1`] = `[Error: [Immer] Unsupported patch operation: copy]`; exports[`applyPatches > throws when \`path\` cannot be resolved 1`] = `[Error: [Immer] Cannot apply patch, path doesn't resolve: a/b]`; exports[`applyPatches > throws when \`path\` cannot be resolved 2`] = `[Error: [Immer] Cannot apply patch, path doesn't resolve: a/b/c]`; ================================================ FILE: __tests__/__snapshots__/plugins.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`error when using Maps 1`] = `[Error: [Immer] The plugin for 'MapSet' has not been loaded into Immer. To enable the plugin, import and call \`enableMapSet()\` when initializing your application.]`; exports[`error when using patches - 1 1`] = `[Error: [Immer] The plugin for 'Patches' has not been loaded into Immer. To enable the plugin, import and call \`enablePatches()\` when initializing your application.]`; exports[`error when using patches - 2 1`] = `[Error: [Immer] The plugin for 'Patches' has not been loaded into Immer. To enable the plugin, import and call \`enablePatches()\` when initializing your application.]`; exports[`error when using patches - 3 1`] = `[Error: [Immer] The plugin for 'Patches' has not been loaded into Immer. To enable the plugin, import and call \`enablePatches()\` when initializing your application.]`; ================================================ FILE: __tests__/__snapshots__/readme.js.snap ================================================ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`Producers can update Maps 4`] = `[Error: [Immer] This object has been frozen and should not be mutated]`; ================================================ FILE: __tests__/base.js ================================================ "use strict" import {vi} from "vitest" import { Immer, nothing, original, isDraft, immerable, enablePatches, enableMapSet, enableArrayMethods } from "../src/immer" import { each, shallowCopy, DRAFT_STATE, clearPlugin, PluginArrayMethods } from "../src/internal" import deepFreeze from "deep-freeze" import * as lodash from "lodash" enablePatches() enableMapSet() vi.setConfig({ testTimeout: 2000 }) const isProd = process.env.NODE_ENV === "production" test("immer should have no dependencies", () => { expect(require("../package.json").dependencies).toBeUndefined() }) for (const autoFreeze of [true, false]) { for (const useStrictShallowCopy of [true, false]) { for (const useListener of [true, false]) { const name = `${autoFreeze ? "auto-freeze=true" : "auto-freeze=false"}:${ useStrictShallowCopy ? "shallow-copy=true" : "shallow-copy=false" }:${useListener ? "use-listener=true" : "use-listener=false"}` runBaseTest(name, autoFreeze, useStrictShallowCopy, useListener) } } } // Run one additional test suite with the array methods plugin enabled, // as that should be a separate concern from the other settings const testArrayMethodsName = `array-plugin=true:auto-freeze=true:shallow-copy=false:use-listener=false` runBaseTest(testArrayMethodsName, true, false, false, true) class Foo {} function runBaseTest( name, autoFreeze, useStrictShallowCopy, useListener, useArrayMethods = false ) { const listener = useListener ? function() {} : undefined const {produce, produceWithPatches} = createPatchedImmer({ autoFreeze, useStrictShallowCopy }) // When `useListener` is true, append a function to the arguments of every // uncurried `produce` call in every test. This makes tests easier to read. function createPatchedImmer(options) { const immer = new Immer(options) const {produce} = immer immer.produce = function(...args) { return typeof args[1] === "function" && args.length < 3 ? produce(...args, listener) : produce(...args) } return immer } describe(`base functionality - ${name}`, () => { let baseState let origBaseState beforeEach(() => { origBaseState = baseState = createBaseState() // Allow running our tests with and without the array method plugin if (useArrayMethods) { enableArrayMethods() } else { clearPlugin(PluginArrayMethods) } }) it("returns the original state when no changes are made", () => { const nextState = produce(baseState, s => { expect(s.aProp).toBe("hi") expect(s.anObject.nested).toMatchObject({yummie: true}) }) expect(nextState).toBe(baseState) }) it("does structural sharing", () => { const random = Math.random() const nextState = produce(baseState, s => { s.aProp = random }) expect(nextState).not.toBe(baseState) expect(nextState.aProp).toBe(random) expect(nextState.nested).toBe(baseState.nested) }) it("deep change bubbles up", () => { const nextState = produce(baseState, s => { s.anObject.nested.yummie = false }) expect(nextState).not.toBe(baseState) expect(nextState.anObject).not.toBe(baseState.anObject) expect(baseState.anObject.nested.yummie).toBe(true) expect(nextState.anObject.nested.yummie).toBe(false) expect(nextState.anArray).toBe(baseState.anArray) }) it("can add props", () => { const nextState = produce(baseState, s => { s.anObject.cookie = {tasty: true} }) expect(nextState).not.toBe(baseState) expect(nextState.anObject).not.toBe(baseState.anObject) expect(nextState.anObject.nested).toBe(baseState.anObject.nested) expect(nextState.anObject.cookie).toEqual({tasty: true}) }) it("can delete props", () => { const nextState = produce(baseState, s => { delete s.anObject.nested delete s.nonexisting }) expect(nextState).not.toBe(baseState) expect(nextState.anObject).not.toBe(baseState.anObject) expect(nextState.anObject.nested).toBe(undefined) }) it("can delete props - 2", () => { const nextState = produce(baseState, s => { delete s.nonexisting }) expect(nextState).toBe(baseState) }) // Found by: https://github.com/mweststrate/immer/pull/267 it("can delete props added in the producer", () => { const nextState = produce(baseState, s => { s.anObject.test = true delete s.anObject.test }) expect(nextState).not.toBe(baseState) expect(nextState).toEqual(baseState) }) // Found by: https://github.com/mweststrate/immer/issues/328 it("can set a property that was just deleted", () => { const baseState = {a: 1} const nextState = produce(baseState, s => { delete s.a s.a = 2 }) expect(nextState.a).toBe(2) }) it("can set a property to its original value after deleting it", () => { const baseState = {a: {b: 1}} const nextState = produce(baseState, s => { const a = s.a delete s.a s.a = a }) expect(nextState).not.toBe(baseState) expect(nextState).toEqual(baseState) }) it("can get property descriptors", () => { const getDescriptor = Object.getOwnPropertyDescriptor const baseState = deepFreeze([{a: 1}]) produce(baseState, arr => { const obj = arr[0] const desc = { configurable: true, enumerable: true, writable: true } // Known property expect(getDescriptor(obj, "a")).toMatchObject(desc) expect(getDescriptor(arr, 0)).toMatchObject(desc) // Deleted property delete obj.a arr.pop() expect(getDescriptor(obj, "a")).toBeUndefined() expect(getDescriptor(arr, 0)).toBeUndefined() // Unknown property expect(getDescriptor(obj, "b")).toBeUndefined() expect(getDescriptor(arr, 100)).toBeUndefined() // Added property obj.b = 2 arr[100] = 1 expect(getDescriptor(obj, "b")).toBeDefined() expect(getDescriptor(arr, 100)).toBeDefined() }) }) describe("array drafts", () => { it("supports Array.isArray()", () => { const nextState = produce(baseState, s => { expect(Array.isArray(s.anArray)).toBeTruthy() s.anArray.push(1) }) expect(Array.isArray(nextState.anArray)).toBeTruthy() }) it("supports index access", () => { const value = baseState.anArray[0] const nextState = produce(baseState, s => { expect(s.anArray[0]).toBe(value) }) expect(nextState).toBe(baseState) }) it("supports iteration", () => { const base = [ {id: 1, a: 1}, {id: 2, a: 1} ] const findById = (collection, id) => { for (const item of collection) { if (item.id === id) return item } return null } const result = produce(base, draft => { const obj1 = findById(draft, 1) const obj2 = findById(draft, 2) obj1.a = 2 obj2.a = 2 }) expect(result[0].a).toEqual(2) expect(result[1].a).toEqual(2) }) it("can assign an index via bracket notation", () => { const nextState = produce(baseState, s => { s.anArray[3] = true }) expect(nextState).not.toBe(baseState) expect(nextState.anArray).not.toBe(baseState.anArray) expect(nextState.anArray[3]).toEqual(true) }) it("can use splice() to both add and remove items", () => { const nextState = produce(baseState, s => { s.anArray.splice(1, 1, "a", "b") }) expect(nextState.anArray).not.toBe(baseState.anArray) expect(nextState.anArray[1]).toBe("a") expect(nextState.anArray[2]).toBe("b") }) it("can truncate via the length property", () => { const baseLength = baseState.anArray.length const nextState = produce(baseState, s => { s.anArray.length = baseLength - 1 }) expect(nextState.anArray).not.toBe(baseState.anArray) expect(nextState.anArray.length).toBe(baseLength - 1) }) it("can extend via the length property", () => { const baseLength = baseState.anArray.length const nextState = produce(baseState, s => { s.anArray.length = baseLength + 1 }) expect(nextState.anArray).not.toBe(baseState.anArray) expect(nextState.anArray.length).toBe(baseLength + 1) }) describe("mutating array methods", () => { // Reported here: https://github.com/mweststrate/immer/issues/116 it("can pop then push", () => { const nextState = produce([1, 2, 3], s => { s.pop() s.push(100) }) expect(nextState).toEqual([1, 2, 100]) }) it("can be sorted", () => { const baseState = [{value: 3}, {value: 1}, {value: 2}] const nextState = produce(baseState, s => { s.sort((a, b) => a.value - b.value) }) expect(nextState).not.toBe(baseState) expect(nextState).toEqual([{value: 1}, {value: 2}, {value: 3}]) }) it("can be reversed", () => { const baseState = [{value: 1}, {value: 2}, {value: 3}] const nextState = produce(baseState, s => { s.reverse() }) expect(nextState).not.toBe(baseState) expect(nextState).toEqual([{value: 3}, {value: 2}, {value: 1}]) }) it("can be sorted with existing proxies", () => { const baseState = [{value: 3}, {value: 1}, {value: 2}] const nextState = produce(baseState, s => { // First mutate a nested object to create a proxy s[0].value = 4 // Then sort the array s.sort((a, b) => a.value - b.value) }) expect(nextState).not.toBe(baseState) expect(nextState).toEqual([{value: 1}, {value: 2}, {value: 4}]) }) it("can be reversed with existing proxies", () => { const baseState = [{value: 1}, {value: 2}, {value: 3}] const nextState = produce(baseState, s => { // First mutate a nested object to create a proxy s[1].value = 5 // Then reverse the array s.reverse() }) expect(nextState).not.toBe(baseState) expect(nextState).toEqual([{value: 3}, {value: 5}, {value: 1}]) }) it("can be sorted with unmodified existing proxies", () => { const baseState = [{value: 3}, {value: 1}, {value: 2}] const nextState = produce(baseState, s => { // Access a nested object to create a proxy, but don't modify it const firstValue = s[0].value // This creates a proxy for s[0] expect(firstValue).toBe(3) // But we don't modify it // Then sort the array s.sort((a, b) => a.value - b.value) }) expect(nextState).not.toBe(baseState) expect(nextState).toEqual([{value: 1}, {value: 2}, {value: 3}]) }) describe("push()", () => { test("push single item", () => { const base = {items: [{id: 1}, {id: 2}]} const result = produce(base, draft => { draft.items.push({id: 3}) }) expect(result.items).toHaveLength(3) expect(result.items[2].id).toBe(3) }) test("push multiple items", () => { const base = {items: [{id: 1}]} const result = produce(base, draft => { draft.items.push({id: 2}, {id: 3}, {id: 4}) }) expect(result.items).toHaveLength(4) expect(result.items[3].id).toBe(4) }) test("push then mutate pushed item", () => { const base = {items: [{id: 1}]} const result = produce(base, draft => { draft.items.push({id: 2, value: 10}) draft.items[1].value = 20 }) expect(result.items[1].value).toBe(20) }) test("push returns new length", () => { const base = {items: [1, 2]} produce(base, draft => { const newLength = draft.items.push(3, 4) expect(newLength).toBe(4) }) }) }) describe("unshift()", () => { test("unshift single item", () => { const base = {items: [{id: 2}, {id: 3}]} const result = produce(base, draft => { draft.items.unshift({id: 1}) }) expect(result.items).toHaveLength(3) expect(result.items[0].id).toBe(1) expect(result.items[1].id).toBe(2) }) test("unshift multiple items", () => { const base = {items: [{id: 4}]} const result = produce(base, draft => { draft.items.unshift({id: 1}, {id: 2}, {id: 3}) }) expect(result.items).toHaveLength(4) expect(result.items[0].id).toBe(1) expect(result.items[3].id).toBe(4) }) test("unshift then mutate unshifted item", () => { const base = {items: [{id: 2}]} const result = produce(base, draft => { draft.items.unshift({id: 1, value: 10}) draft.items[0].value = 20 }) expect(result.items[0].value).toBe(20) }) test("unshift returns new length", () => { const base = {items: [3, 4]} produce(base, draft => { const newLength = draft.items.unshift(1, 2) expect(newLength).toBe(4) }) }) }) describe("shift()", () => { test("shift removes first item", () => { const base = {items: [{id: 1}, {id: 2}, {id: 3}]} const result = produce(base, draft => { const removed = draft.items.shift() expect(removed.id).toBe(1) }) expect(result.items).toHaveLength(2) expect(result.items[0].id).toBe(2) }) test("shift on empty array returns undefined", () => { const base = {items: []} produce(base, draft => { const removed = draft.items.shift() expect(removed).toBeUndefined() }) }) test("shift then mutate remaining items", () => { const base = {items: [{id: 1}, {id: 2, value: 10}]} const result = produce(base, draft => { draft.items.shift() draft.items[0].value = 20 }) expect(result.items).toHaveLength(1) expect(result.items[0].value).toBe(20) }) test("multiple shifts", () => { const base = {items: [{id: 1}, {id: 2}, {id: 3}]} const result = produce(base, draft => { draft.items.shift() draft.items.shift() }) expect(result.items).toHaveLength(1) expect(result.items[0].id).toBe(3) }) }) describe("splice() edge cases", () => { test("splice with only deleteCount (no items to add)", () => { const base = {items: [{id: 1}, {id: 2}, {id: 3}, {id: 4}]} const result = produce(base, draft => { const removed = draft.items.splice(1, 2) expect(removed).toHaveLength(2) expect(removed[0].id).toBe(2) }) expect(result.items).toHaveLength(2) expect(result.items[0].id).toBe(1) expect(result.items[1].id).toBe(4) }) test("splice with negative start index", () => { const base = {items: [{id: 1}, {id: 2}, {id: 3}]} const result = produce(base, draft => { draft.items.splice(-1, 1, {id: 99}) }) expect(result.items[2].id).toBe(99) }) test("splice at start (index 0)", () => { const base = {items: [{id: 1}, {id: 2}]} const result = produce(base, draft => { draft.items.splice(0, 0, {id: 0}) }) expect(result.items[0].id).toBe(0) expect(result.items).toHaveLength(3) }) test("splice at end", () => { const base = {items: [{id: 1}, {id: 2}]} const result = produce(base, draft => { draft.items.splice(2, 0, {id: 3}) }) expect(result.items[2].id).toBe(3) }) test("splice then mutate spliced-in items", () => { const base = {items: [{id: 1}, {id: 3}]} const result = produce(base, draft => { draft.items.splice(1, 0, {id: 2, value: 10}) draft.items[1].value = 20 }) expect(result.items[1].value).toBe(20) }) }) describe("combined operations", () => { test("sort then push", () => { const base = {items: [{value: 3}, {value: 1}]} const result = produce(base, draft => { draft.items.sort((a, b) => a.value - b.value) draft.items.push({value: 4}) }) expect(result.items.map(i => i.value)).toEqual([1, 3, 4]) }) test("reverse then unshift", () => { const base = {items: [{id: 1}, {id: 2}, {id: 3}]} const result = produce(base, draft => { draft.items.reverse() draft.items.unshift({id: 0}) }) expect(result.items.map(i => i.id)).toEqual([0, 3, 2, 1]) }) test("splice then sort", () => { const base = {items: [{value: 5}, {value: 2}, {value: 8}]} const result = produce(base, draft => { draft.items.splice(1, 1, {value: 1}) draft.items.sort((a, b) => a.value - b.value) }) expect(result.items.map(i => i.value)).toEqual([1, 5, 8]) }) test("push, pop, push sequence", () => { const base = {items: [{id: 1}]} const result = produce(base, draft => { draft.items.push({id: 2}) draft.items.pop() draft.items.push({id: 3}) }) expect(result.items.map(i => i.id)).toEqual([1, 3]) }) }) describe("bulk operations with pre-existing proxies", () => { test("access items before sort", () => { const base = {items: [{value: 3}, {value: 1}, {value: 2}]} const result = produce(base, draft => { // Access all items to create proxies draft.items.forEach(item => item.value) // Then sort draft.items.sort((a, b) => a.value - b.value) }) expect(result.items.map(i => i.value)).toEqual([1, 2, 3]) }) test("mutate items before reverse", () => { const base = { items: [ {id: 1, value: 10}, {id: 2, value: 20} ] } const result = produce(base, draft => { // Mutate to create modified proxies draft.items[0].value = 15 draft.items[1].value = 25 // Then reverse draft.items.reverse() }) expect(result.items[0].id).toBe(2) expect(result.items[0].value).toBe(25) expect(result.items[1].id).toBe(1) expect(result.items[1].value).toBe(15) }) }) describe("return values", () => { test("pop returns removed item", () => { const base = {items: [{id: 1}, {id: 2}]} produce(base, draft => { const removed = draft.items.pop() expect(removed.id).toBe(2) // Verify we can mutate the returned item removed.modified = true expect(draft.items[0].modified).toBeUndefined() }) }) test("shift returns removed item", () => { const base = {items: [{id: 1}, {id: 2}]} produce(base, draft => { const removed = draft.items.shift() expect(removed.id).toBe(1) }) }) test("splice returns array of removed items", () => { const base = {items: [{id: 1}, {id: 2}, {id: 3}]} produce(base, draft => { const removed = draft.items.splice(0, 2) expect(removed).toHaveLength(2) expect(removed[0].id).toBe(1) expect(removed[1].id).toBe(2) }) }) }) }) describe("non-mutating array methods", () => { // Test data factory const createTestData = () => ({ items: [ {id: 1, value: 10, nested: {count: 1}}, {id: 2, value: 20, nested: {count: 2}}, {id: 3, value: 30, nested: {count: 3}}, {id: 4, value: 40, nested: {count: 4}}, {id: 5, value: 50, nested: {count: 5}} ], other: {data: "test"} }) describe("filter()", () => { test("returns new array with filtered items", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(item => item.value > 25) expect(filtered).toHaveLength(3) expect(filtered[0].id).toBe(3) }) expect(result).toBe(base) // No modifications }) test("mutations to filtered items are reflected in result", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(item => item.value > 25) // Verify filtered items are drafts expect(isDraft(filtered[0])).toBe(true) filtered[0].value = 999 }) expect(result.items[2].value).toBe(999) // id: 3 is at index 2 expect(result.items[0].value).toBe(10) // Unchanged // Verify base state unchanged expect(base.items[2].value).toBe(30) // Verify result is a copy expect(result.items[2]).not.toBe(base.items[2]) }) test("mutations to nested properties work correctly", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(item => item.id > 2) // Verify filtered items are drafts expect(isDraft(filtered[0])).toBe(true) filtered[0].nested.count = 100 }) expect(result.items[2].nested.count).toBe(100) // Verify base state unchanged expect(base.items[2].nested.count).toBe(3) // Verify result is a copy expect(result.items[2].nested).not.toBe(base.items[2].nested) }) test("multiple mutations to different filtered items", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(item => item.value > 15) // Verify all filtered items are drafts filtered.forEach(item => expect(isDraft(item)).toBe(true)) filtered[0].value = 200 // id: 2 filtered[1].value = 300 // id: 3 filtered[2].value = 400 // id: 4 }) expect(result.items[1].value).toBe(200) expect(result.items[2].value).toBe(300) expect(result.items[3].value).toBe(400) // Verify base state unchanged expect(base.items[1].value).toBe(20) expect(base.items[2].value).toBe(30) expect(base.items[3].value).toBe(40) }) test("filtered array can be assigned to another property", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(item => item.value > 25) draft.other.filtered = filtered }) expect(result.other.filtered).toHaveLength(3) expect(result.other.filtered[0].id).toBe(3) }) test("cross-reference: mutating filtered item affects original location", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(item => item.id === 3) draft.other.ref = filtered[0] filtered[0].value = 999 }) expect(result.items[2].value).toBe(999) expect(result.other.ref.value).toBe(999) }) test("read-only access doesn't cause mutations", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(item => item.value > 25) const sum = filtered.reduce((acc, item) => acc + item.value, 0) expect(sum).toBe(120) // 30 + 40 + 50 }) expect(result).toBe(base) // No modifications }) test("mutating item in filter result updates original value", () => { const initialState = { largeArray: Array.from({length: 10}).map((_, i) => ({ id: i, value: i * 10 })) } const result = produce(initialState, draft => { const filtered = draft.largeArray.filter(item => item.id <= 5) filtered[0].value = 999 draft.filtered = filtered }) expect(result.largeArray[0].value).toBe(999) expect(result.filtered[0].value).toBe(999) expect(result.largeArray[0]).toBe(result.filtered[0]) }) }) describe("map()", () => { test("returns new array with mapped items", () => { const base = createTestData() const result = produce(base, draft => { const mapped = draft.items.map(item => item.nested) expect(mapped).toHaveLength(5) expect(mapped[0].count).toBe(1) }) expect(result).toBe(base) }) test("mutations to mapped nested objects work", () => { const base = createTestData() const result = produce(base, draft => { const nested = draft.items.map(item => item.nested) // Verify mapped items are drafts expect(isDraft(nested[0])).toBe(true) nested[0].count = 100 }) expect(result.items[0].nested.count).toBe(100) // Verify base state unchanged expect(base.items[0].nested.count).toBe(1) // Verify result is a copy expect(result.items[0].nested).not.toBe(base.items[0].nested) }) test("map with transformation then mutate", () => { const base = createTestData() const result = produce(base, draft => { const mapped = draft.items.map(item => ({ ...item, doubled: item.value * 2 })) // This creates new objects, so mutations won't affect original mapped[0].value = 999 }) expect(result.items[0].value).toBe(10) // Unchanged }) test("map returning original items allows mutation", () => { const base = createTestData() const result = produce(base, draft => { const mapped = draft.items.map(item => item) // Identity map // Verify mapped items are drafts expect(isDraft(mapped[0])).toBe(true) mapped[0].value = 999 }) expect(result.items[0].value).toBe(999) // Verify base state unchanged expect(base.items[0].value).toBe(10) // Verify result is a copy expect(result.items[0]).not.toBe(base.items[0]) }) }) describe("find()", () => { test("returns found item", () => { const base = createTestData() const result = produce(base, draft => { const found = draft.items.find(item => item.id === 3) expect(found?.value).toBe(30) }) expect(result).toBe(base) }) test("mutations to found item are reflected", () => { const base = createTestData() const result = produce(base, draft => { const found = draft.items.find(item => item.id === 3) // Verify found item is a draft expect(isDraft(found)).toBe(true) if (found) { found.value = 999 } }) expect(result.items[2].value).toBe(999) // Verify base state unchanged expect(base.items[2].value).toBe(30) // Verify result is a copy expect(result.items[2]).not.toBe(base.items[2]) }) test("nested mutations on found item", () => { const base = createTestData() const result = produce(base, draft => { const found = draft.items.find(item => item.id === 2) // Verify found item is a draft expect(isDraft(found)).toBe(true) if (found) { found.nested.count = 200 } }) expect(result.items[1].nested.count).toBe(200) // Verify base state unchanged expect(base.items[1].nested.count).toBe(2) // Verify result is a copy expect(result.items[1].nested).not.toBe(base.items[1].nested) }) test("find returns undefined when not found", () => { const base = createTestData() const result = produce(base, draft => { const found = draft.items.find(item => item.id === 999) expect(found).toBeUndefined() }) expect(result).toBe(base) }) }) describe("findLast()", () => { test("returns last matching item", () => { const base = { items: [ {id: 1, type: "A"}, {id: 2, type: "B"}, {id: 3, type: "A"} ] } const result = produce(base, draft => { const found = draft.items.findLast(item => item.type === "A") expect(found?.id).toBe(3) }) expect(result).toBe(base) }) test("mutations to findLast result work", () => { const base = { items: [ {id: 1, type: "A", value: 10}, {id: 2, type: "B", value: 20}, {id: 3, type: "A", value: 30} ] } const result = produce(base, draft => { const found = draft.items.findLast(item => item.type === "A") // Verify found item is a draft expect(isDraft(found)).toBe(true) if (found) { found.value = 999 } }) expect(result.items[2].value).toBe(999) // Verify base state unchanged expect(base.items[2].value).toBe(30) // Verify result is a copy expect(result.items[2]).not.toBe(base.items[2]) }) }) describe("slice()", () => { test("returns sliced array", () => { const base = createTestData() const result = produce(base, draft => { const sliced = draft.items.slice(1, 3) expect(sliced).toHaveLength(2) expect(sliced[0].id).toBe(2) }) expect(result).toBe(base) }) test("mutations to sliced items work", () => { const base = createTestData() const result = produce(base, draft => { const sliced = draft.items.slice(1, 3) // Verify sliced items are drafts expect(isDraft(sliced[0])).toBe(true) sliced[0].value = 999 }) expect(result.items[1].value).toBe(999) // Verify base state unchanged expect(base.items[1].value).toBe(20) // Verify result is a copy expect(result.items[1]).not.toBe(base.items[1]) }) test("slice with negative indices", () => { const base = createTestData() const result = produce(base, draft => { const sliced = draft.items.slice(-2) // Verify sliced items are drafts expect(isDraft(sliced[0])).toBe(true) sliced[0].value = 999 }) expect(result.items[3].value).toBe(999) // Verify base state unchanged expect(base.items[3].value).toBe(40) // Verify result is a copy expect(result.items[3]).not.toBe(base.items[3]) }) }) describe("flatMap()", () => { test("returns flattened array", () => { const base = { groups: [{items: [{id: 1}, {id: 2}]}, {items: [{id: 3}, {id: 4}]}] } const result = produce(base, draft => { const flat = draft.groups.flatMap(group => group.items) expect(flat).toHaveLength(4) expect(flat[0].id).toBe(1) }) expect(result).toBe(base) }) test("mutations to flatMapped items work", () => { const base = { groups: [ { items: [ {id: 1, value: 10}, {id: 2, value: 20} ] }, {items: [{id: 3, value: 30}]} ] } const result = produce(base, draft => { const flat = draft.groups.flatMap(group => group.items) // Verify flatMapped items are drafts expect(isDraft(flat[0])).toBe(true) flat[0].value = 999 }) expect(result.groups[0].items[0].value).toBe(999) // Verify base state unchanged expect(base.groups[0].items[0].value).toBe(10) // Verify result is a copy expect(result.groups[0].items[0]).not.toBe(base.groups[0].items[0]) }) }) describe("reduce()", () => { test("returns accumulated value", () => { const base = createTestData() const result = produce(base, draft => { const sum = draft.items.reduce((acc, item) => acc + item.value, 0) expect(sum).toBe(150) // 10 + 20 + 30 + 40 + 50 }) expect(result).toBe(base) }) test("mutations during reduce are reflected", () => { const base = createTestData() const result = produce(base, draft => { const sum = draft.items.reduce((acc, item, index) => { // Verify items in reduce are drafts expect(isDraft(item)).toBe(true) if (index === 2) { item.value = 999 } return acc + item.value }, 0) expect(sum).toBe(1119) // 10 + 20 + 999 + 40 + 50 }) expect(result.items[2].value).toBe(999) // Verify base state unchanged expect(base.items[2].value).toBe(30) // Verify result is a copy expect(result.items[2]).not.toBe(base.items[2]) }) test("reduce with object accumulator", () => { const base = createTestData() const result = produce(base, draft => { const grouped = draft.items.reduce((acc, item) => { const key = item.value > 25 ? "high" : "low" if (!acc[key]) acc[key] = [] acc[key].push(item) return acc }, {}) expect(grouped.low).toHaveLength(2) expect(grouped.high).toHaveLength(3) }) expect(result).toBe(base) }) test("reduce then mutate accumulated items", () => { const base = createTestData() const result = produce(base, draft => { const items = draft.items.reduce((acc, item) => { // Verify items in reduce are drafts expect(isDraft(item)).toBe(true) if (item.value > 25) acc.push(item) return acc }, []) // Verify accumulated items are drafts expect(isDraft(items[0])).toBe(true) items[0].value = 999 }) expect(result.items[2].value).toBe(999) // id: 3 is at index 2 // Verify base state unchanged expect(base.items[2].value).toBe(30) // Verify result is a copy expect(result.items[2]).not.toBe(base.items[2]) }) }) describe("forEach()", () => { test("iterates over all items", () => { const base = createTestData() const result = produce(base, draft => { let count = 0 draft.items.forEach(item => { count++ expect(item.id).toBeDefined() }) expect(count).toBe(5) }) expect(result).toBe(base) }) test("mutations during forEach are reflected", () => { const base = createTestData() const result = produce(base, draft => { draft.items.forEach((item, index) => { // Verify items in forEach are drafts expect(isDraft(item)).toBe(true) if (index === 1) { item.value = 999 } }) }) expect(result.items[1].value).toBe(999) // Verify base state unchanged expect(base.items[1].value).toBe(20) // Verify result is a copy expect(result.items[1]).not.toBe(base.items[1]) }) test("forEach with nested mutations", () => { const base = createTestData() const result = produce(base, draft => { draft.items.forEach(item => { // Verify items in forEach are drafts expect(isDraft(item)).toBe(true) item.nested.count *= 10 }) }) expect(result.items[0].nested.count).toBe(10) expect(result.items[4].nested.count).toBe(50) // Verify base state unchanged expect(base.items[0].nested.count).toBe(1) // Verify result is a copy expect(result.items[0].nested).not.toBe(base.items[0].nested) }) test("forEach returns undefined", () => { const base = createTestData() const result = produce(base, draft => { const returnValue = draft.items.forEach(item => item.value) expect(returnValue).toBeUndefined() }) expect(result).toBe(base) }) }) describe("indexOf()", () => { test("returns index of found item", () => { const base = {items: [1, 2, 3, 4, 5]} const result = produce(base, draft => { const index = draft.items.indexOf(3) expect(index).toBe(2) }) expect(result).toBe(base) }) test("returns -1 when item not found", () => { const base = {items: [1, 2, 3, 4, 5]} const result = produce(base, draft => { const index = draft.items.indexOf(99) expect(index).toBe(-1) }) expect(result).toBe(base) }) test("works with object references", () => { const base = createTestData() const result = produce(base, draft => { const item = draft.items[2] const index = draft.items.indexOf(item) expect(index).toBe(2) }) expect(result).toBe(base) }) test("indexOf with fromIndex parameter", () => { const base = {items: [1, 2, 3, 2, 5]} const result = produce(base, draft => { const firstIndex = draft.items.indexOf(2) const secondIndex = draft.items.indexOf(2, 2) expect(firstIndex).toBe(1) expect(secondIndex).toBe(3) }) expect(result).toBe(base) }) }) describe("join()", () => { test("returns joined string", () => { const base = {items: [1, 2, 3, 4, 5]} const result = produce(base, draft => { const joined = draft.items.join(",") expect(joined).toBe("1,2,3,4,5") }) expect(result).toBe(base) }) test("join with custom separator", () => { const base = {items: ["a", "b", "c"]} const result = produce(base, draft => { const joined = draft.items.join(" - ") expect(joined).toBe("a - b - c") }) expect(result).toBe(base) }) test("join with no separator uses comma", () => { const base = {items: [1, 2, 3]} const result = produce(base, draft => { const joined = draft.items.join() expect(joined).toBe("1,2,3") }) expect(result).toBe(base) }) test("join with objects calls toString", () => { const base = createTestData() const result = produce(base, draft => { const joined = draft.items.join(",") expect(joined).toContain("[object Object]") }) expect(result).toBe(base) }) }) describe("concat()", () => { test("returns new array with concatenated items", () => { const base = {items: [{id: 1}, {id: 2}]} const result = produce(base, draft => { const concatenated = draft.items.concat([{id: 3}]) expect(concatenated).toHaveLength(3) expect(concatenated[2].id).toBe(3) }) expect(result).toBe(base) }) test("concat with no arguments creates shallow copy", () => { const base = { items: [ {id: 1, value: 10}, {id: 2, value: 20} ] } const result = produce(base, draft => { const copy = draft.items.concat() expect(copy).toHaveLength(2) expect(copy[0].id).toBe(1) }) expect(result).toBe(base) }) // Behavior differs based on array methods plugin if (useArrayMethods) { test("concat returns base values, not drafts (with plugin)", () => { const base = {items: [{id: 1, value: 10}]} const result = produce(base, draft => { const concatenated = draft.items.concat() // With plugin: concat returns base values, not drafts expect(isDraft(concatenated[0])).toBe(false) }) expect(result).toBe(base) }) } else { test("concat returns draft proxies (default behavior)", () => { const base = {items: [{id: 1, value: 10}]} const result = produce(base, draft => { const concatenated = draft.items.concat() // Without plugin: concat returns draft proxies via get trap expect(isDraft(concatenated[0])).toBe(true) }) expect(result).toBe(base) }) } test("concat with multiple arrays", () => { const base = {items: [{id: 1}]} const result = produce(base, draft => { const concatenated = draft.items.concat([{id: 2}], [{id: 3}]) expect(concatenated).toHaveLength(3) expect(concatenated[1].id).toBe(2) expect(concatenated[2].id).toBe(3) }) expect(result).toBe(base) }) test("concat result assigned to draft works", () => { const base = {items: [{id: 1}], combined: []} const result = produce(base, draft => { draft.combined = draft.items.concat([{id: 2}]) }) expect(result.combined).toHaveLength(2) expect(result.combined[0].id).toBe(1) expect(result.combined[1].id).toBe(2) }) test("concat with primitives", () => { const base = {numbers: [1, 2, 3]} const result = produce(base, draft => { const concatenated = draft.numbers.concat([4, 5]) expect(concatenated).toEqual([1, 2, 3, 4, 5]) }) expect(result).toBe(base) }) }) describe("flat()", () => { test("returns flattened array", () => { const base = { nested: [ [1, 2], [3, 4] ] } const result = produce(base, draft => { const flattened = draft.nested.flat() expect(flattened).toEqual([1, 2, 3, 4]) }) expect(result).toBe(base) }) test("flat with depth parameter", () => { const base = {nested: [[[1, 2]], [[3, 4]]]} const result = produce(base, draft => { const shallow = draft.nested.flat(1) expect(shallow).toEqual([ [1, 2], [3, 4] ]) const deep = draft.nested.flat(2) expect(deep).toEqual([1, 2, 3, 4]) }) expect(result).toBe(base) }) // Behavior differs based on array methods plugin if (useArrayMethods) { test("flat returns base values, not drafts (with plugin)", () => { const base = {nested: [[{id: 1}], [{id: 2}]]} const result = produce(base, draft => { const flattened = draft.nested.flat() expect(flattened).toHaveLength(2) // With plugin: flat returns base values, not drafts expect(isDraft(flattened[0])).toBe(false) }) expect(result).toBe(base) }) } else { test("flat returns draft proxies (default behavior)", () => { const base = {nested: [[{id: 1}], [{id: 2}]]} const result = produce(base, draft => { const flattened = draft.nested.flat() expect(flattened).toHaveLength(2) // Without plugin: flat returns draft proxies via get trap expect(isDraft(flattened[0])).toBe(true) }) expect(result).toBe(base) }) } test("flat with empty nested arrays", () => { const base = {nested: [[], [1, 2], []]} const result = produce(base, draft => { const flattened = draft.nested.flat() expect(flattened).toEqual([1, 2]) }) expect(result).toBe(base) }) test("flat result assigned to draft works", () => { const base = {nested: [[1], [2]], result: []} const result = produce(base, draft => { draft.result = draft.nested.flat() }) expect(result.result).toEqual([1, 2]) }) }) describe("findIndex()", () => { test("returns index of found item", () => { const base = createTestData() const result = produce(base, draft => { const index = draft.items.findIndex(item => item.id === 3) expect(index).toBe(2) }) expect(result).toBe(base) }) test("returns -1 when not found", () => { const base = createTestData() const result = produce(base, draft => { const index = draft.items.findIndex(item => item.id === 999) expect(index).toBe(-1) }) expect(result).toBe(base) }) test("predicate receives correct arguments", () => { const base = createTestData() const result = produce(base, draft => { draft.items.findIndex((item, index, array) => { expect(typeof index).toBe("number") expect(Array.isArray(array)).toBe(true) return false }) }) expect(result).toBe(base) }) test("works with primitives", () => { const base = {numbers: [10, 20, 30, 40, 50]} const result = produce(base, draft => { const index = draft.numbers.findIndex(n => n > 25) expect(index).toBe(2) }) expect(result).toBe(base) }) }) describe("findLastIndex()", () => { test("returns last matching index", () => { const base = { items: [ {id: 1, type: "A"}, {id: 2, type: "B"}, {id: 3, type: "A"} ] } const result = produce(base, draft => { const index = draft.items.findLastIndex(item => item.type === "A") expect(index).toBe(2) }) expect(result).toBe(base) }) test("returns -1 when not found", () => { const base = {items: [{id: 1}, {id: 2}]} const result = produce(base, draft => { const index = draft.items.findLastIndex(item => item.id === 999) expect(index).toBe(-1) }) expect(result).toBe(base) }) test("predicate receives correct arguments", () => { const base = createTestData() const result = produce(base, draft => { draft.items.findLastIndex((item, index, array) => { expect(typeof index).toBe("number") expect(Array.isArray(array)).toBe(true) return false }) }) expect(result).toBe(base) }) }) describe("some()", () => { test("returns true when condition met", () => { const base = createTestData() const result = produce(base, draft => { const hasHighValue = draft.items.some(item => item.value > 40) expect(hasHighValue).toBe(true) }) expect(result).toBe(base) }) test("returns false when no items match", () => { const base = createTestData() const result = produce(base, draft => { const hasHugeValue = draft.items.some(item => item.value > 1000) expect(hasHugeValue).toBe(false) }) expect(result).toBe(base) }) test("short-circuits on first match", () => { const base = {items: [{id: 1}, {id: 2}, {id: 3}]} let callCount = 0 const result = produce(base, draft => { const found = draft.items.some(item => { callCount++ return item.id === 1 }) expect(found).toBe(true) }) expect(callCount).toBe(1) expect(result).toBe(base) }) test("predicate receives correct arguments", () => { const base = createTestData() const result = produce(base, draft => { draft.items.some((item, index, array) => { expect(typeof index).toBe("number") expect(Array.isArray(array)).toBe(true) return false }) }) expect(result).toBe(base) }) test("works with primitives", () => { const base = {numbers: [1, 2, 3, 4, 5]} const result = produce(base, draft => { expect(draft.numbers.some(n => n > 3)).toBe(true) expect(draft.numbers.some(n => n > 10)).toBe(false) }) expect(result).toBe(base) }) }) describe("every()", () => { test("returns true when all items match", () => { const base = createTestData() const result = produce(base, draft => { const allPositive = draft.items.every(item => item.value > 0) expect(allPositive).toBe(true) }) expect(result).toBe(base) }) test("returns false when any item fails", () => { const base = createTestData() const result = produce(base, draft => { const allHighValue = draft.items.every(item => item.value > 30) expect(allHighValue).toBe(false) }) expect(result).toBe(base) }) test("short-circuits on first failure", () => { const base = {items: [{id: 1}, {id: 2}, {id: 3}]} let callCount = 0 const result = produce(base, draft => { const allMatch = draft.items.every(item => { callCount++ return item.id === 999 }) expect(allMatch).toBe(false) }) expect(callCount).toBe(1) expect(result).toBe(base) }) test("predicate receives correct arguments", () => { const base = createTestData() const result = produce(base, draft => { draft.items.every((item, index, array) => { expect(typeof index).toBe("number") expect(Array.isArray(array)).toBe(true) return true }) }) expect(result).toBe(base) }) test("returns true for empty array", () => { const base = {items: []} const result = produce(base, draft => { const allMatch = draft.items.every(() => false) expect(allMatch).toBe(true) }) expect(result).toBe(base) }) }) describe("lastIndexOf()", () => { test("returns last index of item", () => { const base = {items: [1, 2, 3, 2, 1]} const result = produce(base, draft => { const index = draft.items.lastIndexOf(2) expect(index).toBe(3) }) expect(result).toBe(base) }) test("returns -1 when not found", () => { const base = {items: [1, 2, 3]} const result = produce(base, draft => { const index = draft.items.lastIndexOf(99) expect(index).toBe(-1) }) expect(result).toBe(base) }) test("works with fromIndex parameter", () => { const base = {items: [1, 2, 3, 2, 1]} const result = produce(base, draft => { const index = draft.items.lastIndexOf(2, 2) expect(index).toBe(1) }) expect(result).toBe(base) }) test("works with negative fromIndex", () => { const base = {items: [1, 2, 3, 2, 1]} const result = produce(base, draft => { const index = draft.items.lastIndexOf(2, -2) expect(index).toBe(3) }) expect(result).toBe(base) }) }) describe("includes()", () => { test("returns true when item exists", () => { const base = {items: [1, 2, 3, 4, 5]} const result = produce(base, draft => { expect(draft.items.includes(3)).toBe(true) }) expect(result).toBe(base) }) test("returns false when item doesn't exist", () => { const base = {items: [1, 2, 3, 4, 5]} const result = produce(base, draft => { expect(draft.items.includes(99)).toBe(false) }) expect(result).toBe(base) }) test("works with fromIndex parameter", () => { const base = {items: [1, 2, 3, 4, 5]} const result = produce(base, draft => { expect(draft.items.includes(2, 2)).toBe(false) expect(draft.items.includes(3, 2)).toBe(true) }) expect(result).toBe(base) }) test("works with NaN", () => { const base = {items: [1, NaN, 3]} const result = produce(base, draft => { expect(draft.items.includes(NaN)).toBe(true) }) expect(result).toBe(base) }) test("works with negative fromIndex", () => { const base = {items: [1, 2, 3, 4, 5]} const result = produce(base, draft => { expect(draft.items.includes(4, -2)).toBe(true) expect(draft.items.includes(2, -2)).toBe(false) }) expect(result).toBe(base) }) }) describe("toString()", () => { test("returns string representation", () => { const base = {items: [1, 2, 3]} const result = produce(base, draft => { const str = draft.items.toString() expect(str).toBe("1,2,3") }) expect(result).toBe(base) }) test("works with objects", () => { const base = {items: [{id: 1}, {id: 2}]} const result = produce(base, draft => { const str = draft.items.toString() expect(str).toContain("[object Object]") }) expect(result).toBe(base) }) test("works with empty array", () => { const base = {items: []} const result = produce(base, draft => { const str = draft.items.toString() expect(str).toBe("") }) expect(result).toBe(base) }) }) describe("toLocaleString()", () => { test("returns locale string representation", () => { const base = {items: [1, 2, 3]} const result = produce(base, draft => { const str = draft.items.toLocaleString() expect(typeof str).toBe("string") }) expect(result).toBe(base) }) test("works with numbers", () => { const base = {numbers: [1000, 2000]} const result = produce(base, draft => { const str = draft.numbers.toLocaleString() expect(typeof str).toBe("string") }) expect(result).toBe(base) }) }) describe("findLast() additional edge cases", () => { test("returns undefined when not found", () => { const base = {items: [{id: 1}, {id: 2}, {id: 3}]} const result = produce(base, draft => { const found = draft.items.findLast(item => item.id === 999) expect(found).toBeUndefined() }) expect(result).toBe(base) }) test("nested mutations on findLast result", () => { const base = { items: [ {id: 1, type: "A", nested: {value: 10}}, {id: 2, type: "B", nested: {value: 20}}, {id: 3, type: "A", nested: {value: 30}} ] } const result = produce(base, draft => { const found = draft.items.findLast(item => item.type === "A") expect(isDraft(found)).toBe(true) if (found) { found.nested.value = 999 } }) expect(result.items[2].nested.value).toBe(999) expect(base.items[2].nested.value).toBe(30) }) test("findLast on empty array", () => { const base = {items: []} const result = produce(base, draft => { const found = draft.items.findLast(() => true) expect(found).toBeUndefined() }) expect(result).toBe(base) }) }) describe("comparison: filter vs concat behavior", () => { test("filter returns drafts that can affect original", () => { const base = { items: [ {id: 1, value: 10}, {id: 2, value: 20} ] } const result = produce(base, draft => { const filtered = draft.items.filter(item => item.id === 1) expect(isDraft(filtered[0])).toBe(true) filtered[0].value = 999 }) expect(result.items[0].value).toBe(999) }) // Behavior differs based on array methods plugin if (useArrayMethods) { test("concat returns base values that cannot affect original (with plugin)", () => { const base = {items: [{id: 1, value: 10}]} const result = produce(base, draft => { const concatenated = draft.items.concat() // With plugin: concat returns base values, not drafts expect(isDraft(concatenated[0])).toBe(false) // Attempting to mutate won't affect the draft // (would throw if autoFreeze is on, or just not be tracked) }) expect(result).toBe(base) }) } else { test("concat returns drafts that can affect original (default behavior)", () => { const base = {items: [{id: 1, value: 10}]} const result = produce(base, draft => { const concatenated = draft.items.concat() // Without plugin: concat returns draft proxies via get trap expect(isDraft(concatenated[0])).toBe(true) // Mutations to concatenated items ARE tracked concatenated[0].value = 999 }) expect(result.items[0].value).toBe(999) }) } }) describe("combined operations", () => { test("chain filter then map then mutate", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(item => item.value > 20) // Verify filtered items are drafts filtered.forEach(item => expect(isDraft(item)).toBe(true)) const nested = filtered.map(item => item.nested) // Verify mapped items are drafts expect(isDraft(nested[0])).toBe(true) nested[0].count = 999 }) expect(result.items[2].nested.count).toBe(999) // Verify base state unchanged expect(base.items[2].nested.count).toBe(3) // Verify result is a copy expect(result.items[2].nested).not.toBe(base.items[2].nested) }) test("filter, find, then mutate", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(item => item.value > 20) // Verify filtered items are drafts filtered.forEach(item => expect(isDraft(item)).toBe(true)) const found = filtered.find(item => item.id === 4) // Verify found item is a draft expect(isDraft(found)).toBe(true) if (found) { found.value = 999 } }) expect(result.items[3].value).toBe(999) // Verify base state unchanged expect(base.items[3].value).toBe(40) // Verify result is a copy expect(result.items[3]).not.toBe(base.items[3]) }) test("multiple filters with mutations", () => { const base = createTestData() const result = produce(base, draft => { const filtered1 = draft.items.filter(item => item.value > 15) // Verify first filter items are drafts filtered1.forEach(item => expect(isDraft(item)).toBe(true)) const filtered2 = filtered1.filter(item => item.value < 45) // Verify second filter items are drafts filtered2.forEach(item => expect(isDraft(item)).toBe(true)) filtered2[0].value = 999 }) expect(result.items[1].value).toBe(999) // Verify base state unchanged expect(base.items[1].value).toBe(20) // Verify result is a copy expect(result.items[1]).not.toBe(base.items[1]) }) }) describe("edge cases", () => { test("empty filter result", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(item => item.value > 1000) expect(filtered).toHaveLength(0) }) expect(result).toBe(base) }) test("filter with all items", () => { const base = createTestData() const result = produce(base, draft => { const filtered = draft.items.filter(() => true) filtered[0].value = 999 }) expect(result.items[0].value).toBe(999) }) test("primitive array filter", () => { const base = {numbers: [1, 2, 3, 4, 5]} const result = produce(base, draft => { const filtered = draft.numbers.filter(n => n > 2) expect(filtered).toEqual([3, 4, 5]) }) expect(result).toBe(base) }) test("mixed draft and non-draft in filter result", () => { const base = createTestData() const result = produce(base, draft => { // Mutate some items before filtering draft.items[0].value = 15 draft.items[2].value = 35 const filtered = draft.items.filter(item => item.value > 14) filtered[0].value = 999 // Mutate already-mutated item }) expect(result.items[0].value).toBe(999) }) test("assigning filtered array back to draft", () => { const base = createTestData() const result = produce(base, draft => { draft.items = draft.items.filter(item => item.value > 25) draft.items[0].value = 999 }) expect(result.items).toHaveLength(3) expect(result.items[0].value).toBe(999) expect(result.items[0].id).toBe(3) }) }) describe("performance-critical patterns", () => { test("large array filter with read-only access", () => { const base = { items: Array.from({length: 1000}, (_, i) => ({ id: i, value: i * 10 })) } const result = produce(base, draft => { const filtered = draft.items.filter(item => item.value > 5000) const sum = filtered.reduce((acc, item) => acc + item.value, 0) expect(sum).toBeGreaterThan(0) }) expect(result).toBe(base) // No modifications }) test("multiple filters without mutations", () => { const base = createTestData() const result = produce(base, draft => { const f1 = draft.items.filter(item => item.value > 10) const f2 = draft.items.filter(item => item.value < 40) const f3 = draft.items.filter(item => item.id % 2 === 0) expect(f1.length + f2.length + f3.length).toBeGreaterThan(0) }) expect(result).toBe(base) }) }) }) it("supports the same child reference multiple times in the same array via index assignment", () => { const obj = {value: 1} const baseState = {items: [obj, {}, {}, {}, {}]} const nextState = produce(baseState, draft => { // Assign the same object to multiple indices draft.items[0] = obj // Original position draft.items[2] = obj // Same object at different index draft.items[4] = obj // Same object at yet another index // Modify the object through one of the references draft.items[0].value = 2 }) // Immer behavior: modified draft gets new object, unmodified drafts are optimized expect(nextState.items[0]).not.toBe(nextState.items[2]) // Modified vs unmodified expect(nextState.items[2]).toBe(nextState.items[4]) // Both unmodified, same reference expect(nextState.items[0].value).toBe(2) // Modified expect(nextState.items[2].value).toBe(1) // Unmodified (same as original) expect(nextState.items[4].value).toBe(1) // Unmodified (same as original) // The unmodified items should be the same as the original object expect(nextState.items[2]).toBe(obj) expect(nextState.items[4]).toBe(obj) // Original object should be unchanged expect(obj.value).toBe(1) // Verify array structure expect(nextState.items.length).toBe(5) }) it("supports modifying nested objects", () => { const baseState = [{a: 1}, {}] const nextState = produce(baseState, s => { s[0].a++ s[0].a++ s[1].a = 0 s[0].a-- }) expect(nextState).not.toBe(baseState) expect(nextState[0].a).toBe(2) expect(nextState[1].a).toBe(0) }) it("never preserves non-numeric properties", () => { const baseState = [] baseState.x = 7 const nextState = produce(baseState, s => { s.push(3) }) expect("x" in nextState).toBeFalsy() }) if (!global.USES_BUILD) { it("throws when a non-numeric property is added", () => { expect(() => { produce([], d => { d.x = 3 }) }).toThrowErrorMatchingSnapshot() }) it("throws when a non-numeric property is deleted", () => { expect(() => { const baseState = [] baseState.x = 7 produce(baseState, d => { delete d.x }) }).toThrowErrorMatchingSnapshot() }) } }) describe("map drafts", () => { it("supports key access", () => { const value = baseState.aMap.get("jedi") const nextState = produce(baseState, s => { expect(s.aMap.get("jedi")).toEqual(value) }) expect(nextState).toBe(baseState) }) it("supports key access for non-primitive keys", () => { const key = {prop: "val"} const base = new Map([[key, {id: 1, a: 1}]]) const value = base.get(key) const nextState = produce(base, s => { expect(s.get(key)).toEqual(value) }) expect(nextState).toBe(base) }) it("supports iteration", () => { const base = new Map([ ["first", {id: 1, a: 1}], ["second", {id: 2, a: 1}] ]) const findById = (map, id) => { for (const [, item] of map) { if (item.id === id) return item } return null } const result = produce(base, draft => { const obj1 = findById(draft, 1) const obj2 = findById(draft, 2) obj1.a = 2 obj2.a = 2 }) expect(result).not.toBe(base) expect(result.get("first").a).toEqual(2) expect(result.get("second").a).toEqual(2) }) it("supports 'entries'", () => { const base = new Map([ ["first", {id: 1, a: 1}], ["second", {id: 2, a: 1}] ]) const findById = (map, id) => { for (const [, item] of map.entries()) { if (item.id === id) return item } return null } const result = produce(base, draft => { const obj1 = findById(draft, 1) const obj2 = findById(draft, 2) obj1.a = 2 obj2.a = 2 }) expect(result).not.toBe(base) expect(result.get("first").a).toEqual(2) expect(result.get("second").a).toEqual(2) }) it("supports 'values'", () => { const base = new Map([ ["first", {id: 1, a: 1}], ["second", {id: 2, a: 1}] ]) const findById = (map, id) => { for (const item of map.values()) { if (item.id === id) return item } return null } const result = produce(base, draft => { const obj1 = findById(draft, 1) const obj2 = findById(draft, 2) obj1.a = 2 obj2.a = 2 }) expect(result).not.toBe(base) expect(result.get("first").a).toEqual(2) expect(result.get("second").a).toEqual(2) }) it("supports 'keys", () => { const base = new Map([ ["first", Symbol()], ["second", Symbol()] ]) const result = produce(base, draft => { expect([...draft.keys()]).toEqual(["first", "second"]) draft.set("third", Symbol()) expect([...draft.keys()]).toEqual(["first", "second", "third"]) }) }) it("supports forEach", () => { const key1 = {prop: "val1"} const key2 = {prop: "val2"} const base = new Map([ ["first", {id: 1, a: 1}], ["second", {id: 2, a: 1}], [key1, {id: 3, a: 1}], [key2, {id: 4, a: 1}] ]) const result = produce(base, draft => { let sum1 = 0 draft.forEach(({a}) => { sum1 += a }) expect(sum1).toBe(4) let sum2 = 0 draft.get("first").a = 10 draft.get("second").a = 20 draft.get(key1).a = 30 draft.get(key2).a = 40 draft.forEach(({a}) => { sum2 += a }) expect(sum2).toBe(100) }) expect(result).not.toBe(base) expect(base.get("first").a).toEqual(1) expect(base.get("second").a).toEqual(1) expect(base.get(key1).a).toEqual(1) expect(base.get(key2).a).toEqual(1) expect(result.get("first").a).toEqual(10) expect(result.get("second").a).toEqual(20) expect(result.get(key1).a).toEqual(30) expect(result.get(key2).a).toEqual(40) }) it("supports forEach mutation", () => { const base = new Map([ ["first", {id: 1, a: 1}], ["second", {id: 2, a: 1}] ]) const result = produce(base, draft => { draft.forEach(item => { item.a = 100 }) }) expect(result).not.toBe(base) expect(result.get("first").a).toEqual(100) expect(result.get("second").a).toEqual(100) }) it("can assign by key", () => { const nextState = produce(baseState, s => { // Map.prototype.set should return the Map itself const res = s.aMap.set("force", true) if (!global.USES_BUILD) expect(res).toBe(s.aMap[DRAFT_STATE].draft_) }) expect(nextState).not.toBe(baseState) expect(nextState.aMap).not.toBe(baseState.aMap) expect(nextState.aMap.get("force")).toEqual(true) }) it("can assign by a non-primitive key", () => { const key = {prop: "val"} const value = {id: 1, a: 1} const base = new Map([[key, value]]) const nextState = produce(base, s => { s.set(key, true) }) expect(nextState).not.toBe(base) expect(base.get(key)).toEqual(value) expect(nextState.get(key)).toEqual(true) }) it("state stays the same if the same item is assigned by key", () => { const nextState = produce(baseState, s => { s.aMap.set("jediTotal", 42) }) expect(nextState).toBe(baseState) expect(nextState.aMap).toBe(baseState.aMap) }) it("returns 'size'", () => { const nextState = produce(baseState, s => { s.aMap.set("newKey", true) expect(s.aMap.size).toBe(baseState.aMap.size + 1) }) expect(nextState).not.toBe(baseState) expect(nextState.aMap).not.toBe(baseState.aMap) expect(nextState.aMap.get("newKey")).toEqual(true) expect(nextState.aMap.size).toEqual(baseState.aMap.size + 1) }) it("can use 'delete' to remove items", () => { const nextState = produce(baseState, s => { expect(s.aMap.has("jedi")).toBe(true) expect(s.aMap.delete("jedi")).toBe(true) expect(s.aMap.has("jedi")).toBe(false) }) expect(nextState.aMap).not.toBe(baseState.aMap) expect(nextState.aMap.size).toBe(baseState.aMap.size - 1) expect(baseState.aMap.has("jedi")).toBe(true) expect(nextState.aMap.has("jedi")).toBe(false) }) it("can use 'clear' to remove items", () => { const nextState = produce(baseState, s => { expect(s.aMap.size).not.toBe(0) s.aMap.clear() expect(s.aMap.size).toBe(0) }) expect(nextState.aMap).not.toBe(baseState.aMap) expect(baseState.aMap.size).not.toBe(0) expect(nextState.aMap.size).toBe(0) }) it("support 'has'", () => { const nextState = produce(baseState, s => { expect(s.aMap.has("newKey")).toBe(false) s.aMap.set("newKey", true) expect(s.aMap.has("newKey")).toBe(true) }) expect(nextState).not.toBe(baseState) expect(nextState.aMap).not.toBe(baseState.aMap) expect(baseState.aMap.has("newKey")).toBe(false) expect(nextState.aMap.has("newKey")).toBe(true) }) it("supports nested maps", () => { const base = new Map([["first", new Map([["second", {prop: "test"}]])]]) const result = produce(base, draft => { draft.get("first").get("second").prop = "test1" }) expect(result).not.toBe(base) expect(result.get("first")).not.toBe(base.get("first")) expect(result.get("first").get("second")).not.toBe( base.get("first").get("second") ) expect(base.get("first").get("second").prop).toBe("test") expect(result.get("first").get("second").prop).toBe("test1") }) it("treats void deletes as no-op", () => { const base = new Map([["x", 1]]) const next = produce(base, d => { expect(d.delete("y")).toBe(false) }) expect(next).toBe(base) }) it("revokes map proxies", () => { let m produce(baseState, s => { m = s.aMap }) expect(() => m.get("x")).toThrowErrorMatchingSnapshot() expect(() => m.set("x", 3)).toThrowErrorMatchingSnapshot() }) it("does not draft map keys", () => { // anything else would be terribly confusing const key = {a: 1} const map = new Map([[key, 2]]) const next = produce(map, d => { const dKey = Array.from(d.keys())[0] expect(isDraft(dKey)).toBe(false) expect(dKey).toBe(key) dKey.a += 1 d.set(dKey, d.get(dKey) + 1) d.set(key, d.get(key) + 1) expect(d.get(key)).toBe(4) expect(key.a).toBe(2) }) const entries = Array.from(next.entries()) expect(entries).toEqual([[key, 4]]) expect(entries[0][0]).toBe(key) expect(entries[0][0].a).toBe(2) }) it("does support instanceof Map", () => { const map = new Map() produce(map, d => { expect(d instanceof Map).toBeTruthy() }) }) it("handles clear correctly", () => { const map = new Map([ ["a", 1], ["c", 3] ]) const next = produce(map, draft => { draft.delete("a") draft.set("b", 2) draft.set("c", 4) draft.clear() }) expect(next).toEqual(new Map()) }) }) describe("set drafts", () => { it("supports iteration", () => { const base = new Set([ {id: 1, a: 1}, {id: 2, a: 1} ]) const findById = (set, id) => { for (const item of set) { if (item.id === id) return item } return null } const result = produce(base, draft => { const obj1 = findById(draft, 1) const obj2 = findById(draft, 2) obj1.a = 2 obj2.a = 2 }) expect(result).not.toBe(base) expect(base).toEqual( new Set([ {id: 1, a: 1}, {id: 2, a: 1} ]) ) expect(result).toEqual( new Set([ {id: 1, a: 2}, {id: 2, a: 2} ]) ) }) it("supports 'entries'", () => { const base = new Set([ {id: 1, a: 1}, {id: 2, a: 1} ]) const findById = (set, id) => { for (const [item1, item2] of set.entries()) { expect(item1).toBe(item2) if (item1.id === id) return item1 } return null } const result = produce(base, draft => { const obj1 = findById(draft, 1) const obj2 = findById(draft, 2) obj1.a = 2 obj2.a = 2 }) expect(result).not.toBe(base) expect(base).toEqual( new Set([ {id: 1, a: 1}, {id: 2, a: 1} ]) ) expect(result).toEqual( new Set([ {id: 1, a: 2}, {id: 2, a: 2} ]) ) }) it("supports 'values'", () => { const base = new Set([ {id: 1, a: 1}, {id: 2, a: 1} ]) const findById = (set, id) => { for (const item of set.values()) { if (item.id === id) return item } return null } const result = produce(base, draft => { const obj1 = findById(draft, 1) const obj2 = findById(draft, 2) obj1.a = 2 obj2.a = 2 }) expect(result).not.toBe(base) expect(base).toEqual( new Set([ {id: 1, a: 1}, {id: 2, a: 1} ]) ) expect(result).toEqual( new Set([ {id: 1, a: 2}, {id: 2, a: 2} ]) ) }) it("supports 'keys'", () => { const base = new Set([ {id: 1, a: 1}, {id: 2, a: 1} ]) const findById = (set, id) => { for (const item of set.keys()) { if (item.id === id) return item } return null } const result = produce(base, draft => { const obj1 = findById(draft, 1) const obj2 = findById(draft, 2) obj1.a = 2 obj2.a = 2 }) expect(result).not.toBe(base) expect(base).toEqual( new Set([ {id: 1, a: 1}, {id: 2, a: 1} ]) ) expect(result).toEqual( new Set([ {id: 1, a: 2}, {id: 2, a: 2} ]) ) }) it("supports forEach with mutation after reads", () => { const base = new Set([ {id: 1, a: 1}, {id: 2, a: 2} ]) const result = produce(base, draft => { let sum1 = 0 draft.forEach(({a}) => { sum1 += a }) expect(sum1).toBe(3) let sum2 = 0 draft.forEach(item => { item.a += 10 sum2 += item.a }) expect(sum2).toBe(23) }) expect(result).not.toBe(base) expect(base).toEqual( new Set([ {id: 1, a: 1}, {id: 2, a: 2} ]) ) expect(result).toEqual( new Set([ {id: 1, a: 11}, {id: 2, a: 12} ]) ) }) it("state stays the same if the same item is added", () => { const nextState = produce(baseState, s => { s.aSet.add("Luke") }) expect(nextState).toBe(baseState) expect(nextState.aSet).toBe(baseState.aSet) }) it("can add new items", () => { const nextState = produce(baseState, s => { // Set.prototype.set should return the Set itself const res = s.aSet.add("force") if (!global.USES_BUILD) expect(res).toBe(s.aSet[DRAFT_STATE].draft_) }) expect(nextState).not.toBe(baseState) expect(nextState.aSet).not.toBe(baseState.aSet) expect(baseState.aSet.has("force")).toBe(false) expect(nextState.aSet.has("force")).toBe(true) }) it("returns 'size'", () => { const nextState = produce(baseState, s => { s.aSet.add("newKey") expect(s.aSet.size).toBe(baseState.aSet.size + 1) }) expect(nextState).not.toBe(baseState) expect(nextState.aSet).not.toBe(baseState.aSet) expect(nextState.aSet.has("newKey")).toBe(true) expect(nextState.aSet.size).toEqual(baseState.aSet.size + 1) }) it("can use 'delete' to remove items", () => { const nextState = produce(baseState, s => { expect(s.aSet.has("Luke")).toBe(true) expect(s.aSet.delete("Luke")).toBe(true) expect(s.aSet.delete("Luke")).toBe(false) expect(s.aSet.has("Luke")).toBe(false) }) expect(nextState.aSet).not.toBe(baseState.aSet) expect(baseState.aSet.has("Luke")).toBe(true) expect(nextState.aSet.has("Luke")).toBe(false) expect(nextState.aSet.size).toBe(baseState.aSet.size - 1) }) it("can use 'clear' to remove items", () => { const nextState = produce(baseState, s => { expect(s.aSet.size).not.toBe(0) s.aSet.clear() expect(s.aSet.size).toBe(0) }) expect(nextState.aSet).not.toBe(baseState.aSet) expect(baseState.aSet.size).not.toBe(0) expect(nextState.aSet.size).toBe(0) }) it("supports 'has'", () => { const nextState = produce(baseState, s => { expect(s.aSet.has("newKey")).toBe(false) s.aSet.add("newKey") expect(s.aSet.has("newKey")).toBe(true) }) expect(nextState).not.toBe(baseState) expect(nextState.aSet).not.toBe(baseState.aSet) expect(baseState.aSet.has("newKey")).toBe(false) expect(nextState.aSet.has("newKey")).toBe(true) }) it("supports nested sets", () => { const base = new Set([new Set(["Serenity"])]) const result = produce(base, draft => { draft.forEach(nestedItem => nestedItem.add("Firefly")) }) expect(result).not.toBe(base) expect(base).toEqual(new Set([new Set(["Serenity"])])) expect(result).toEqual(new Set([new Set(["Serenity", "Firefly"])])) }) it("supports has / delete on elements from the original", () => { const obj = {} const set = new Set([obj]) const next = produce(set, d => { expect(d.has(obj)).toBe(true) d.add(3) expect(d.has(obj)).toBe(true) d.delete(obj) expect(d.has(obj)).toBe(false) }) expect(next).toEqual(new Set([3])) }) it("revokes sets", () => { let m produce(baseState, s => { m = s.aSet }) expect(() => m.has("x")).toThrowErrorMatchingSnapshot() expect(() => m.add("x")).toThrowErrorMatchingSnapshot() }) it("does support instanceof Set", () => { const set = new Set() produce(set, d => { expect(d instanceof Set).toBeTruthy() }) }) }) it("supports `immerable` symbol on constructor", () => { class One {} One[immerable] = true const baseState = new One() const nextState = produce(baseState, draft => { expect(draft).not.toBe(baseState) draft.foo = true }) expect(nextState).not.toBe(baseState) expect(nextState.foo).toBeTruthy() }) it("preserves symbol properties", () => { const test = Symbol("test") const baseState = {[test]: true} const nextState = produce(baseState, s => { expect(s[test]).toBeTruthy() s.foo = true }) expect(nextState).toEqual({ [test]: true, foo: true }) }) if (!global.USES_BUILD) it("preserves non-enumerable properties", () => { const baseState = {} // Non-enumerable object property Object.defineProperty(baseState, "foo", { value: {a: 1}, enumerable: false }) // Non-enumerable primitive property Object.defineProperty(baseState, "bar", { value: 1, enumerable: false }) // Non-enumerable primitive property that won't modified. Object.defineProperty(baseState, "baz", { value: 1, enumerable: false }) // When using Proxy, even non-enumerable keys will be copied if it's changed. const canReferNonEnumerableProperty = useStrictShallowCopy const nextState = produce(baseState, s => { if (canReferNonEnumerableProperty) expect(s.foo).toBeTruthy() if (useStrictShallowCopy) expect(isEnumerable(s, "foo")).toBeFalsy() if (canReferNonEnumerableProperty) s.bar++ if (useStrictShallowCopy) expect(isEnumerable(s, "foo")).toBeFalsy() if (canReferNonEnumerableProperty) s.foo.a++ if (useStrictShallowCopy) expect(isEnumerable(s, "foo")).toBeFalsy() }) if (canReferNonEnumerableProperty) { expect(nextState.foo).toEqual({a: 2}) } if (useStrictShallowCopy) expect(isEnumerable(nextState, "foo")).toBeFalsy() if (useStrictShallowCopy) expect(nextState.baz).toBeTruthy() }) it("can work with own computed props", () => { const baseState = { x: 1, get y() { return this.x }, set y(v) { this.x = v } } const nextState = produce(baseState, d => { expect(d.y).toBe(1) d.x = 2 expect(d.x).toBe(2) expect(d.y).toBe(1) // this has been copied! d.y = 3 expect(d.x).toBe(2) }) expect(baseState.x).toBe(1) expect(baseState.y).toBe(1) expect(nextState.x).toBe(2) expect(nextState.y).toBe(3) if (!autoFreeze) { nextState.y = 4 // decoupled now! expect(nextState.y).toBe(4) expect(nextState.x).toBe(2) expect(Object.getOwnPropertyDescriptor(nextState, "y").value).toBe(4) } }) it("can work with class with computed props", () => { class State { [immerable] = true x = 1 set y(v) { this.x = v } get y() { return this.x } } const baseState = new State() const nextState = produce(baseState, d => { expect(d.y).toBe(1) d.y = 2 expect(d.x).toBe(2) expect(d.y).toBe(2) expect(Object.getOwnPropertyDescriptor(d, "y")).toBeUndefined() }) expect(baseState.x).toBe(1) expect(baseState.y).toBe(1) expect(nextState.x).toBe(2) expect(nextState.y).toBe(2) expect(Object.getOwnPropertyDescriptor(nextState, "y")).toBeUndefined() }) it("allows inherited computed properties", () => { const proto = {} Object.defineProperty(proto, "foo", { get() { return this.bar }, set(val) { this.bar = val } }) proto[immerable] = true const baseState = Object.create(proto) produce(baseState, s => { expect(s.bar).toBeUndefined() s.foo = {} expect(s.bar).toBeDefined() expect(s.foo).toBe(s.bar) }) }) it("optimization: does not visit properties of new data structures if autofreeze is disabled and no drafts are unfinalized", () => { const newData = {} Object.defineProperty(newData, "x", { enumerable: true, get() { throw new Error("visited!") } }) const run = () => produce({}, d => { d.data = newData }) if (autoFreeze) { expect(run).toThrow("visited!") } else { expect(run).not.toThrow("visited!") } }) it("same optimization doesn't cause draft from nested producers to be unfinished", () => { const base = { y: 1, child: { x: 1 } } const wrap = produce(draft => { return { wrapped: draft } }) const res = produce(base, draft => { draft.y++ draft.child = wrap(draft.child) draft.child.wrapped.x++ }) expect(res).toEqual({ y: 2, child: {wrapped: {x: 2}} }) }) it("supports a base state with multiple references to an object", () => { const obj = {notEmpty: true} const res = produce({a: obj, b: obj}, d => { // Two drafts are created for each occurrence of an object in the base state. expect(d.a).not.toBe(d.b) d.a.z = true expect(d.b.z).toBeUndefined() }) expect(res.b).toBe(obj) expect(res.a).not.toBe(res.b) expect(res.a.z).toBeTruthy() }) // NOTE: Except the root draft. it("supports multiple references to any modified draft", () => { const next = produce({a: {b: 1}}, d => { d.a.b++ d.b = d.a }) expect(next.a).toBe(next.b) }) it("can rename nested objects (no changes)", () => { const nextState = produce({obj: {}}, s => { s.foo = s.obj delete s.obj }) expect(nextState).toEqual({foo: {}}) }) // Very similar to the test before, but the reused object has one // property changed, one added, and one removed. it("can rename nested objects (with changes)", () => { const nextState = produce({obj: {a: 1, b: 1}}, s => { s.obj.a = true // change delete s.obj.b // delete s.obj.c = true // add s.foo = s.obj delete s.obj }) expect(nextState).toEqual({foo: {a: true, c: true}}) }) it("can nest a draft in a new object (no changes)", () => { const baseState = {obj: {}} const nextState = produce(baseState, s => { s.foo = {bar: s.obj} delete s.obj }) expect(nextState.foo.bar).toBe(baseState.obj) }) it("can nest a modified draft in a new object", () => { const nextState = produce({obj: {a: 1, b: 1}}, s => { s.obj.a = true // change delete s.obj.b // delete s.obj.c = true // add s.foo = {bar: s.obj} delete s.obj }) expect(nextState).toEqual({foo: {bar: {a: true, c: true}}}) }) // #1209 - spread draft object and push back via array methods it("can spread a draft and push it back into the array", () => { const base = [{nestedArray: []}] const next = produce(base, s => { s.push({...s[0]}) }) expect(next[0].nestedArray).toEqual([]) expect(next[1].nestedArray).toEqual([]) expect(next[1].nestedArray.length).toBe(0) }) it("can spread a draft with nested objects and push it back", () => { const base = [{nested: {value: 42}}] const next = produce(base, s => { s.push({...s[0]}) }) expect(next[0].nested.value).toBe(42) expect(next[1].nested.value).toBe(42) }) it("can push a draft value directly into its parent array", () => { const base = [{nestedArray: []}] const next = produce(base, s => { s.push(s[0]) }) expect(next[0].nestedArray).toEqual([]) expect(next[1].nestedArray).toEqual([]) }) it("can unshift a spread draft back into the array", () => { const base = [{nestedArray: [1]}] const next = produce(base, s => { s.unshift({...s[0]}) }) expect(next[0].nestedArray).toEqual([1]) expect(next[1].nestedArray).toEqual([1]) }) it("can splice a spread draft into the array", () => { const base = [{nestedArray: ["a", "b"]}] const next = produce(base, s => { s.splice(0, 0, {...s[0]}) }) expect(next[0].nestedArray).toEqual(["a", "b"]) expect(next[1].nestedArray).toEqual(["a", "b"]) }) it("supports assigning undefined to an existing property", () => { const nextState = produce(baseState, s => { s.aProp = undefined }) expect(nextState).not.toBe(baseState) expect(nextState.aProp).toBe(undefined) }) it("supports assigning undefined to a new property", () => { const baseState = {} const nextState = produce(baseState, s => { s.aProp = undefined }) expect(nextState).not.toBe(baseState) expect(nextState.aProp).toBe(undefined) }) // NOTE: ES5 drafts only protect existing properties when revoked. if (!isProd) it("revokes the draft once produce returns", () => { const expectRevoked = fn => { expect(fn).toThrowErrorMatchingSnapshot() } // Test object drafts: let draft produce({a: 1, b: 1}, s => { draft = s delete s.b }) // Access known property on object draft. expectRevoked(() => { draft.a }) // Assign known property on object draft. expectRevoked(() => { draft.a = true }) // Access unknown property on object draft. expectRevoked(() => { draft.z }) // Assign unknown property on object draft. expectRevoked(() => { draft.z = true }) // Test array drafts: produce([1, 2], s => { draft = s s.pop() }) // Access known index of an array draft. expectRevoked(() => { draft[0] }) // Assign known index of an array draft. expectRevoked(() => { draft[0] = true }) // Access unknown index of an array draft. expectRevoked(() => { draft[1] }) // Assign unknown index of an array draft. expectRevoked(() => { draft[1] = true }) }) it("can access a child draft that was created before the draft was modified", () => { produce({a: {}}, s => { const before = s.a s.b = 1 expect(s.a).toBe(before) }) }) it("should reflect all changes made in the draft immediately", () => { produce(baseState, draft => { draft.anArray[0] = 5 draft.anArray.unshift("test") if (!global.USES_BUILD) expect(enumerableOnly(draft.anArray)).toEqual([ "test", 5, 2, {c: 3}, 1 ]) draft.stuffz = "coffee" expect(draft.stuffz).toBe("coffee") }) }) it("throws when Object.defineProperty() is used on drafts", () => { expect(() => { produce({}, draft => { Object.defineProperty(draft, "xx", { enumerable: true, writeable: true, value: 2 }) }) }).toThrowErrorMatchingSnapshot() }) it("should handle constructor correctly", () => { const baseState = { arr: new Array(), obj: new Object() } const result = produce(baseState, draft => { draft.arrConstructed = draft.arr.constructor(1) draft.objConstructed = draft.obj.constructor(1) }) expect(result.arrConstructed).toEqual(new Array().constructor(1)) expect(result.objConstructed).toEqual(new Object().constructor(1)) }) it("should handle equality correctly - 1", () => { const baseState = { y: 3 / 0, z: NaN } const nextState = produce(baseState, draft => { draft.y = 4 / 0 draft.z = NaN }) expect(nextState).toBe(baseState) }) it("should handle equality correctly - 2", () => { const baseState = { x: -0 } const nextState = produce(baseState, draft => { draft.x = +0 }) // 0 === -0 // true // Object.is(0, -0) // false // // MWE: // Immer preserves the difference between -0 and +0, // so a new state is created. // This isn't defined anywhere explicitly, so could be changed // in the future to follow === behavior, rather than Object.is. // But I think this is fine as is. expect(nextState).not.toBe(baseState) expect(nextState.x).toBe(-0) expect(nextState.x).not.toBe(+0) // however, toEqual treats -0 === +0 (which is true!) expect(nextState).toEqual(baseState) }) it("should handle equality correctly - 3", () => { const baseState = { x: "s1", y: 1, z: NaN } const nextState = produce(baseState, draft => { draft.x = "s2" draft.y = 1 draft.z = NaN if (!isProd) { expect(draft[DRAFT_STATE].assigned_.get("x")).toBe(true) expect(draft[DRAFT_STATE].assigned_.get("y")).toBe(undefined) expect(draft[DRAFT_STATE].assigned_.get("z")).toBe(undefined) } }) expect(nextState.x).toBe("s2") }) // AKA: recursive produce calls describe("nested producers", () => { describe("when base state is not a draft", () => { // This test ensures the global state used to manage proxies is // never left in a corrupted state by a nested `produce` call. it("never affects its parent producer implicitly", () => { const base = {obj: {a: 1}} const next = produce(base, draft => { // Notice how `base.obj` is passed, not `draft.obj` const obj2 = produce(base.obj, draft2 => { draft2.a = 0 }) expect(obj2.a).toBe(0) expect(draft.obj.a).toBe(1) // effects should not be visible outside }) expect(next).toBe(base) }) }) describe("when base state is a draft", () => { it("always wraps the draft in a new draft", () => { produce({}, parent => { produce(parent, child => { expect(child).not.toBe(parent) expect(isDraft(child)).toBeTruthy() expect(original(child)).toBe(parent) }) }) }) // Reported by: https://github.com/mweststrate/immer/issues/343 it("ensures each property is drafted", () => { produce({a: {}, b: {}}, parent => { parent.a // Access "a" but not "b" produce(parent, child => { child.c = 1 expect(isDraft(child.a)).toBeTruthy() expect(isDraft(child.b)).toBeTruthy() }) }) }) it("preserves any pending changes", () => { produce({a: 1, b: 1, d: 1}, parent => { parent.b = 2 parent.c = 2 delete parent.d produce(parent, child => { expect(child.a).toBe(1) // unchanged expect(child.b).toBe(2) // changed expect(child.c).toBe(2) // added expect(child.d).toBeUndefined() // deleted }) }) }) }) describe("when base state contains a draft", () => { it("wraps unowned draft with its own draft", () => { produce({a: {}}, parent => { produce({a: parent.a}, child => { expect(child.a).not.toBe(parent.a) expect(isDraft(child.a)).toBeTruthy() expect(original(child.a)).toBe(parent.a) }) }) }) it("returns unowned draft if no changes were made", () => { produce({a: {}}, parent => { const result = produce({a: parent.a}, () => {}) expect(result.a).toBe(parent.a) }) }) it("clones the unowned draft when changes are made", () => { produce({a: {}}, parent => { const result = produce({a: parent.a}, child => { child.a.b = 1 }) expect(result.a).not.toBe(parent.a) expect(result.a.b).toBe(1) expect("b" in parent.a).toBeFalsy() }) }) // We cannot auto-freeze the result of a nested producer, // because it may contain a draft from a parent producer. it("never auto-freezes the result", () => { produce({a: {}}, parent => { const r = produce({a: parent.a}, child => { child.b = 1 // Ensure a copy is returned. }) expect(Object.isFrozen(r)).toBeFalsy() }) }) }) // "Upvalues" are variables from a parent scope. it("does not finalize upvalue drafts", () => { produce({a: {}, b: {}}, parent => { expect(produce({}, () => parent)).toBe(parent) parent.x // Ensure proxy not revoked. expect(produce({}, () => [parent])[0]).toBe(parent) parent.x // Ensure proxy not revoked. expect(produce({}, () => parent.a)).toBe(parent.a) parent.a.x // Ensure proxy not revoked. // Modified parent test parent.c = 1 expect(produce({}, () => [parent.b])[0]).toBe(parent.b) parent.b.x // Ensure proxy not revoked. }) }) it("works with interweaved Immer instances", () => { const options = {autoFreeze} const one = createPatchedImmer(options) const two = createPatchedImmer(options) const base = {} const result = one.produce(base, s1 => two.produce({s1}, s2 => { expect(original(s2.s1)).toBe(s1) s2.n = 1 s2.s1 = one.produce({s2}, s3 => { expect(original(s3.s2)).toBe(s2) expect(original(s3.s2.s1)).toBe(s2.s1) return s3.s2.s1 }) }) ) expect(result.n).toBe(1) expect(result.s1).toBe(base) }) }) it("throws when Object.setPrototypeOf() is used on a draft", () => { produce({}, draft => { expect(() => Object.setPrototypeOf(draft, Array) ).toThrowErrorMatchingSnapshot() }) }) it("supports the 'in' operator", () => { produce(baseState, draft => { // Known property expect("anArray" in draft).toBe(true) expect(Reflect.has(draft, "anArray")).toBe(true) // Unknown property expect("bla" in draft).toBe(false) expect(Reflect.has(draft, "bla")).toBe(false) // Known index expect(0 in draft.anArray).toBe(true) expect("0" in draft.anArray).toBe(true) expect(Reflect.has(draft.anArray, 0)).toBe(true) expect(Reflect.has(draft.anArray, "0")).toBe(true) // Unknown index expect(17 in draft.anArray).toBe(false) expect("17" in draft.anArray).toBe(false) expect(Reflect.has(draft.anArray, 17)).toBe(false) expect(Reflect.has(draft.anArray, "17")).toBe(false) }) }) it("'this' should not be bound anymore - 1", () => { const base = {x: 3} const next1 = produce(base, function() { expect(this).toBe(undefined) }) }) it("'this' should not be bound anymore - 2", () => { const incrementor = produce(function() { expect(this).toBe(undefined) }) incrementor() }) it("should be possible to use dynamic bound this", () => { const world = { counter: {count: 1}, inc: produce(function(draft) { expect(this).toBe(world) draft.counter.count = this.counter.count + 1 }) } expect(world.inc(world).counter.count).toBe(2) }) it("doesnt recurse into frozen structures if external data is frozen", () => { const frozen = {} Object.defineProperty(frozen, "x", { get() { throw "oops" }, enumerable: true, configurable: true }) Object.freeze(frozen) expect(() => { produce({}, d => { d.x = frozen }) }).not.toThrow() }) // See here: https://github.com/mweststrate/immer/issues/89 it("supports the spread operator", () => { const base = {foo: {x: 0, y: 0}, bar: [0, 0]} const result = produce(base, draft => { draft.foo = {x: 1, ...draft.foo, y: 1} draft.bar = [1, ...draft.bar, 1] }) expect(result).toEqual({ foo: {x: 0, y: 1}, bar: [1, 0, 0, 1] }) }) it("processes with lodash.set", () => { const base = [{id: 1, a: 1}] const result = produce(base, draft => { lodash.set(draft, "[0].a", 2) }) expect(base[0].a).toEqual(1) expect(result[0].a).toEqual(2) }) it("processes with lodash.find", () => { const base = [{id: 1, a: 1}] const result = produce(base, draft => { const obj1 = lodash.find(draft, {id: 1}) lodash.set(obj1, "a", 2) }) expect(base[0].a).toEqual(1) expect(result[0].a).toEqual(2) }) it("does not draft external data", () => { const externalData = {x: 3} const base = {} const next = produce(base, draft => { // potentially, we *could* draft external data automatically, but only if those statements are not switched... draft.y = externalData draft.y.x += 1 externalData.x += 1 }) expect(next).toEqual({y: {x: 5}}) expect(externalData.x).toBe(5) expect(next.y).toBe(externalData) }) it("does not create new state unnecessary, #491", () => { const a = {highlight: true} const next1 = produce(a, draft => { draft.highlight = false draft.highlight = true }) // See explanation in issue expect(next1).not.toBe(a) const next2 = produce(a, draft => { draft.highlight = true }) expect(next2).toBe(a) }) autoFreeze && test("issue #462 - frozen", () => { var origin = { a: { value: "no" }, b: { value: "no" } } const next = produce(origin, draft => { draft.a.value = "im" }) expect(() => { origin.b.value = "yes" }).toThrowError( "Cannot assign to read only property 'value' of object '#'" ) expect(() => { next.b.value = "yes" }).toThrowError( "Cannot assign to read only property 'value' of object '#'" ) // should throw! }) autoFreeze && test("issue #1190 / #1192 - should not freeze non-draftable objects (class instances and typed arrays)", () => { class MutableClass { value = 5 } const state = { someValue: 5, mutableClass: new MutableClass(), typedArray: new Uint8Array(10) } expect(() => { // Should not throw when producing with autoFreeze enabled const result = produce(state, draft => { draft.someValue = 6 }) // Verify the non-draftable class instance is not frozen state.mutableClass.value = 6 }).not.toThrow() }) autoFreeze && test("issue #469, state not frozen", () => { const project = produce( { id: 1, tracks: [{id: 1}] }, () => {} ) expect(() => { project.id = 2 // Does not throw error }).toThrowError("Cannot assign to read only property 'id'") expect(() => { Object.assign(project, {id: 2}) // Uncaught TypeError: Cannot assign to read only property 'id' of object '#' }).toThrowError("Cannot assign to read only property 'id'") }) describe("recipe functions", () => { it("can return a new object", () => { const base = {x: 3} const res = produce(base, d => { return {x: d.x + 1} }) expect(res).not.toBe(base) expect(res).toEqual({x: 4}) }) it("can return the draft", () => { const base = {x: 3} const res = produce(base, d => { d.x = 4 return d }) expect(res).not.toBe(base) expect(res).toEqual({x: 4}) }) it("can return an unmodified child draft", () => { const base = {a: {}} const res = produce(base, d => { return d.a }) expect(res).toBe(base.a) }) // TODO: Avoid throwing if only the child draft was modified. it("cannot return a modified child draft", () => { const base = {a: {}} expect(() => { produce(base, d => { d.a.b = 1 return d.a }) }).toThrowErrorMatchingSnapshot() }) it("can return a frozen object", () => { const res = deepFreeze([{x: 3}]) expect(produce({}, () => res)).toBe(res) }) it("can return an object with two references to another object", () => { const next = produce({}, d => { const obj = {} return {obj, arr: [obj]} }) expect(next.obj).toBe(next.arr[0]) }) it("can return an object with two references to an unmodified draft", () => { const base = {a: {}} const next = produce(base, d => { return [d.a, d.a] }) expect(next[0]).toBe(base.a) expect(next[0]).toBe(next[1]) }) // As of the finalization callback rewrite, the // the original `() => res.self` check passes without throwing, // but we still will not have self-references // when returning updated values it("can return self-references, but not for modified values", () => { const res = {} res.self = res // the call will pass const next = produce(res, draft => { draft.a = 42 draft.self.b = 99 }) // Root object and first child were both copied expect(next).not.toBe(next.self) // Second child is the first circular reference expect(next.self.self).not.toBe(next.self) // And it's turtles all the way down expect(next.self.self.self).toBe(next.self.self.self.self) expect(next.a).toBe(42) expect(next.self.b).toBe(99) // The child copy did not receive the update // to the root object expect(next.self.a).toBe(undefined) }) }) it("throws when the draft is modified and another object is returned", () => { const base = {x: 3} expect(() => { produce(base, draft => { draft.x = 4 return {x: 5} }) }).toThrowErrorMatchingSnapshot() }) it("should fix #117 - 1", () => { const reducer = (state, action) => produce(state, draft => { switch (action.type) { case "SET_STARTING_DOTS": return draft.availableStartingDots.map(a => a) default: break } }) const base = { availableStartingDots: [ {dots: 4, count: 1}, {dots: 3, count: 2}, {dots: 2, count: 3}, {dots: 1, count: 4} ] } const next = reducer(base, {type: "SET_STARTING_DOTS"}) expect(next).toEqual(base.availableStartingDots) expect(next).not.toBe(base.availableStartingDots) }) it("should fix #117 - 2", () => { const reducer = (state, action) => produce(state, draft => { switch (action.type) { case "SET_STARTING_DOTS": return { dots: draft.availableStartingDots.map(a => a) } default: break } }) const base = { availableStartingDots: [ {dots: 4, count: 1}, {dots: 3, count: 2}, {dots: 2, count: 3}, {dots: 1, count: 4} ] } const next = reducer(base, {type: "SET_STARTING_DOTS"}) expect(next).toEqual({dots: base.availableStartingDots}) }) it("cannot always detect noop assignments - 0", () => { const baseState = {x: {y: 3}} const nextState = produce(baseState, d => { const a = d.x d.x = a }) expect(nextState).toBe(baseState) }) it("cannot always detect noop assignments - 1", () => { const baseState = {x: {y: 3}} const nextState = produce(baseState, d => { const a = d.x d.x = 4 d.x = a }) // Ideally, this should actually be the same instances // but this would be pretty expensive to detect, // so we don't atm expect(nextState).not.toBe(baseState) }) it("cannot always detect noop assignments - 2", () => { const baseState = {x: {y: 3}} const nextState = produce(baseState, d => { const a = d.x const stuff = a.y + 3 d.x = 4 d.x = a }) // Ideally, this should actually be the same instances // but this would be pretty expensive to detect, // so we don't atm expect(nextState).not.toBe(baseState) }) it("cannot always detect noop assignments - 3", () => { const baseState = {x: 3} const nextState = produce(baseState, d => { d.x = 3 }) expect(nextState).toBe(baseState) }) it("cannot always detect noop assignments - 4", () => { const baseState = {x: 3} const nextState = produce(baseState, d => { d.x = 4 d.x = 3 }) // Ideally, this should actually be the same instances // but this would be pretty expensive to detect, // so we don't atm expect(nextState).not.toBe(baseState) }) it("cannot always detect noop assignments - 4", () => { const baseState = {} const [nextState, patches] = produceWithPatches(baseState, d => { d.x = 4 delete d.x }) expect(nextState).toEqual({}) expect(patches).toEqual([]) // This differs between ES5 and proxy, and ES5 does it better :( expect(nextState).not.toBe(baseState) }) it("cannot produce undefined by returning undefined", () => { const base = 3 expect(produce(base, () => 4)).toBe(4) expect(produce(base, () => null)).toBe(null) expect(produce(base, () => undefined)).toBe(3) expect(produce(base, () => {})).toBe(3) expect(produce(base, () => nothing)).toBe(undefined) expect(produce({}, () => undefined)).toEqual({}) expect(produce({}, () => nothing)).toBe(undefined) expect(produce(3, () => nothing)).toBe(undefined) expect(produce(() => undefined)({})).toEqual({}) expect(produce(() => nothing)({})).toBe(undefined) expect(produce(() => nothing)(3)).toBe(undefined) }) describe("base state type", () => { if (!global.USES_BUILD) testObjectTypes(produce) testLiteralTypes(produce) }) afterEach(() => { expect(baseState).toBe(origBaseState) expect(baseState).toEqual(createBaseState()) }) function createBaseState() { const data = { anInstance: new Foo(), anArray: [3, 2, {c: 3}, 1], aMap: new Map([ ["jedi", {name: "Luke", skill: 10}], ["jediTotal", 42], ["force", "these aren't the droids you're looking for"] ]), aSet: new Set([ "Luke", 42, { jedi: "Yoda" } ]), aProp: "hi", anObject: { nested: { yummie: true }, coffee: false } } return autoFreeze ? deepFreeze(data) : data } }) it(`works with spread #524 - ${name}`, () => { const state = { level1: { level2: { level3: "data" } } } const nextState = produce(state, draft => { return {...draft} }) const nextState1 = produce(state, draft => { const newLevel1 = produce(draft.level1, level1Draft => { return {...level1Draft} }) draft.level1 = newLevel1 }) const nextState2 = produce(state, draft => { const newLevel1 = produce(draft.level1, level1Draft => { return {...level1Draft} }) return { level1: newLevel1 } }) const nextState3 = produce(state, draft => { const newLevel1 = produce(draft.level1, level1Draft => { return Object.assign({}, level1Draft) }) return Object.assign(draft, { level1: newLevel1 }) }) const expected = {level1: {level2: {level3: "data"}}} expect(nextState1).toEqual(expected) expect(nextState2).toEqual(expected) expect(nextState3).toEqual(expected) }) it(`Something with nested producers #522 ${name}`, () => { function initialStateFactory() { return { substate: { array: [ {id: "id1", value: 0}, {id: "id2", value: 0} ] }, array: [ {id: "id1", value: 0}, {id: "id2", value: 0} ] } } const globalProducer = produce(draft => { draft.substate = subProducer(draft.substate) draft.array = arrayProducer(draft.array) }, initialStateFactory()) const subProducer = produce(draftSubState => { draftSubState.array = arrayProducer(draftSubState.array) }) const arrayProducer = produce(draftArray => { draftArray[0].value += 5 }) { const state = globalProducer(undefined) expect(state.array[0].value).toBe(5) expect(state.array.length).toBe(2) expect(state.array[1]).toMatchObject({ id: "id2", value: 0 }) } { const state = globalProducer(undefined) expect(state.substate.array[0].value).toBe(5) expect(state.substate.array.length).toBe(2) expect(state.substate.array[1]).toMatchObject({ id: "id2", value: 0 }) expect(state.substate.array).toMatchObject(state.array) } }) describe(`isDraft - ${name}`, () => { it("returns true for object drafts", () => { produce({}, state => { expect(isDraft(state)).toBeTruthy() }) }) it("returns true for array drafts", () => { produce([], state => { expect(isDraft(state)).toBeTruthy() }) }) it("returns true for objects nested in object drafts", () => { produce({a: {b: {}}}, state => { expect(isDraft(state.a)).toBeTruthy() expect(isDraft(state.a.b)).toBeTruthy() }) }) it("returns false for new objects added to a draft", () => { produce({}, state => { state.a = {} expect(isDraft(state.a)).toBeFalsy() }) }) it("returns false for objects returned by the producer", () => { const object = produce([], () => Object.create(null)) expect(isDraft(object)).toBeFalsy() }) it("returns false for arrays returned by the producer", () => { const array = produce({}, _ => []) expect(isDraft(array)).toBeFalsy() }) it("returns false for object drafts returned by the producer", () => { const object = produce({}, state => state) expect(isDraft(object)).toBeFalsy() }) it("returns false for array drafts returned by the producer", () => { const array = produce([], state => state) expect(isDraft(array)).toBeFalsy() }) }) describe(`complex nesting map / set / object`, () => { const a = {a: 1} const b = {b: 2} const c = {c: 3} const set1 = new Set([a, b]) const set2 = new Set([c]) const map = new Map([ ["set1", set1], ["set2", set2] ]) const base = {map} function first(set) { return Array.from(set.values())[0] } function second(set) { return Array.from(set.values())[1] } test(`modify deep object`, () => { const [res, patches] = produceWithPatches(base, draft => { const v = first(draft.map.get("set1")) expect(original(v)).toBe(a) expect(v).toEqual(a) expect(v).not.toBe(a) v.a++ }) expect(res).toMatchSnapshot() expect(patches).toMatchSnapshot() expect(a.a).toBe(1) expect(base.map.get("set1")).toBe(set1) expect(first(base.map.get("set1"))).toBe(a) expect(res).not.toBe(base) expect(res.map).not.toBe(base.map) expect(res.map.get("set1")).not.toBe(base.map.get("set1")) expect(second(base.map.get("set1"))).toBe(b) expect(base.map.get("set2")).toBe(set2) expect(first(res.map.get("set1"))).toEqual({a: 2}) }) test(`modify deep object - keep value`, () => { const [res, patches] = produceWithPatches(base, draft => { const v = first(draft.map.get("set1")) expect(original(v)).toBe(a) expect(v).toEqual(a) expect(v).not.toBe(a) v.a = 1 // same value }) expect(a.a).toBe(1) expect(base.map.get("set1")).toBe(set1) expect(first(base.map.get("set1"))).toBe(a) expect(res).toBe(base) expect(res.map).toBe(base.map) expect(res.map.get("set1")).toBe(base.map.get("set1")) expect(first(res.map.get("set1"))).toBe(a) expect(second(base.map.get("set1"))).toBe(b) expect(base.map.get("set2")).toBe(set2) expect(patches.length).toBe(0) }) }) if (!autoFreeze) { test("#613", () => { const x1 = {} const y1 = produce(x1, draft => { draft.foo = produce({bar: "baz"}, draft1 => { draft1.bar = "baa" }) draft.foo.bar = "a" }) expect(y1.foo.bar).toBe("a") }) } } function testObjectTypes(produce) { class Foo { constructor(foo) { this.foo = foo this[immerable] = true } } const values = { "empty object": {}, "plain object": {a: 1, b: 2}, "object (no prototype)": Object.create(null), "empty array": [], "plain array": [1, 2], "class instance (draftable)": new Foo(1) } for (const name in values) { const value = values[name] const copy = shallowCopy(value) testObjectType(name, value) testObjectType(name + " (frozen)", Object.freeze(copy)) } function testObjectType(name, base) { describe(name, () => { it("creates a draft", () => { produce(base, draft => { expect(draft).not.toBe(base) expect(shallowCopy(draft, true)).toEqual(base) }) }) it("preserves the prototype", () => { const proto = Object.getPrototypeOf(base) produce(base, draft => { expect(Object.getPrototypeOf(draft)).toBe(proto) }) }) it("returns the base state when no changes are made", () => { expect(produce(base, () => {})).toBe(base) }) it("returns a copy when changes are made", () => { const random = Math.random() const result = produce(base, draft => { draft[0] = random }) expect(result).not.toBe(base) expect(result.constructor).toBe(base.constructor) expect(result[0]).toBe(random) }) }) } describe("class with getters", () => { class State { [immerable] = true _bar = {baz: 1} foo get bar() { return this._bar } syncFoo() { const value = this.bar.baz this.foo = value this.bar.baz++ } } const state = new State() it("should use a method to assing a field using a getter that return a non primitive object", () => { const newState = produce(state, draft => { draft.syncFoo() }) expect(newState.foo).toEqual(1) expect(newState.bar).toEqual({baz: 2}) expect(state.bar).toEqual({baz: 1}) }) }) describe("super class with getters", () => { class BaseState { [immerable] = true _bar = {baz: 1} foo get bar() { return this._bar } syncFoo() { const value = this.bar.baz this.foo = value this.bar.baz++ } } class State extends BaseState {} const state = new State() it("should use a method to assing a field using a getter that return a non primitive object", () => { const newState = produce(state, draft => { draft.syncFoo() }) expect(newState.foo).toEqual(1) expect(newState.bar).toEqual({baz: 2}) expect(state.bar).toEqual({baz: 1}) }) }) describe("class with setters", () => { class State { [immerable] = true _bar = 0 get bar() { return this._bar } set bar(x) { this._bar = x } } const state = new State() it("should define a field with a setter", () => { const newState3 = produce(state, d => { d.bar = 1 expect(d._bar).toEqual(1) }) expect(newState3._bar).toEqual(1) expect(newState3.bar).toEqual(1) expect(state._bar).toEqual(0) expect(state.bar).toEqual(0) }) }) test("setter only", () => { let setterCalled = 0 class State { [immerable] = true x = 0 set y(value) { setterCalled++ this.x = value } } const state = new State() const next = produce(state, draft => { expect(draft.y).toBeUndefined() draft.y = 2 // setter is inherited, so works expect(draft.x).toBe(2) }) expect(setterCalled).toBe(1) expect(next.x).toBe(2) expect(state.x).toBe(0) }) test("getter only", () => { let getterCalled = 0 class State { [immerable] = true x = 0 get y() { getterCalled++ return this.x } } const state = new State() const next = produce(state, draft => { expect(draft.y).toBe(0) expect(() => { draft.y = 2 }).toThrow("Cannot set property y") draft.x = 2 expect(draft.y).toBe(2) }) expect(next.x).toBe(2) expect(next.y).toBe(2) expect(state.x).toBe(0) }) test("own setter only", () => { let setterCalled = 0 const state = { x: 0, set y(value) { setterCalled++ this.x = value } } const next = produce(state, draft => { expect(draft.y).toBeUndefined() // setter is not preserved, so we can write draft.y = 2 expect(draft.x).toBe(0) expect(draft.y).toBe(2) }) expect(setterCalled).toBe(0) expect(next.x).toBe(0) expect(next.y).toBe(2) expect(state.x).toBe(0) }) test("own getter only", () => { let getterCalled = 0 const state = { x: 0, get y() { getterCalled++ return this.x } } const next = produce(state, draft => { expect(draft.y).toBe(0) // de-referenced, so stores it locally draft.y = 2 expect(draft.y).toBe(2) expect(draft.x).toBe(0) }) expect(getterCalled).not.toBe(1) expect(next.x).toBe(0) expect(next.y).toBe(2) expect(state.x).toBe(0) }) test("#620", () => { const customSymbol = Symbol("customSymbol") class TestClass { [immerable] = true; [customSymbol] = 1 } /* Create class instance */ let test0 = new TestClass() /* First produce. This works */ let test1 = produce(test0, draft => { expect(draft[customSymbol]).toBe(1) draft[customSymbol] = 2 }) expect(test1).toEqual({ [immerable]: true, [customSymbol]: 2 }) /* Second produce. This does NOT work. See console error */ /* With version 6.0.9, this works though */ let test2 = produce(test1, draft => { expect(draft[customSymbol]).toBe(2) draft[customSymbol] = 3 }) expect(test2).toEqual({ [immerable]: true, [customSymbol]: 3 }) }) test("#1096 / #1087 / proxies", () => { const sym = Symbol() let state = { id: 1, [sym]: {x: 2} } state = produce(state, draft => { draft.id = 2 draft[sym] }) expect(state[sym].x).toBe(2) }) } function testLiteralTypes(produce) { class Foo {} const values = { "falsy number": 0, "truthy number": 1, "negative number": -1, NaN: NaN, infinity: 1 / 0, true: true, false: false, "empty string": "", "truthy string": "1", null: null, undefined: undefined, /** * These objects are treated as literals because Immer * does not know how to draft them. */ function: () => {}, "regexp object": /.+/g, "boxed number": new Number(0), "boxed string": new String(""), "boxed boolean": new Boolean(), "date object": new Date(), "class instance (not draftable)": new Foo() } for (const name in values) { describe(name, () => { const value = values[name] if (value && typeof value == "object") { it("does not return a copy when changes are made", () => { expect(() => produce(value, draft => { draft.foo = true }) ).toThrowError( isProd ? "[Immer] minified error nr: 1" : "produce can only be called on things that are draftable" ) }) } else { it("does not create a draft", () => { produce(value, draft => { expect(draft).toBe(value) }) }) it("returns the base state when no changes are made", () => { expect(produce(value, () => {})).toBe(value) }) } }) } } function enumerableOnly(x) { const copy = Array.isArray(x) ? x.slice() : Object.assign({}, x) each(copy, (prop, value) => { if (value && typeof value === "object") { copy[prop] = enumerableOnly(value) } }) return copy } function isEnumerable(base, prop) { const desc = Object.getOwnPropertyDescriptor(base, prop) return desc && desc.enumerable ? true : false } ================================================ FILE: __tests__/current.js ================================================ import { setAutoFreeze, current, immerable, isDraft, produce, original, freeze, enableMapSet } from "../src/immer" enableMapSet() runTests("proxy", true) const isProd = process.env.NODE_ENV === "production" function runTests(name) { describe("current - " + name, () => { beforeAll(() => { setAutoFreeze(true) }) it("must be called on draft", () => { expect(() => { current({}) }).toThrowError( isProd ? "[Immer] minified error nr: 10. Full error at: https://bit.ly/3cXEKWf" : "[Immer] 'current' expects a draft, got: [object Object]" ) }) it("can handle simple arrays", () => { const base = [{x: 1}] let c const next = produce(base, draft => { expect(current(draft)).toEqual(base) draft[0].x++ c = current(draft) expect(c).toEqual([{x: 2}]) expect(Array.isArray(c)) draft[0].x++ }) expect(next).toEqual([{x: 3}]) expect(c).toEqual([{x: 2}]) expect(isDraft(c)).toBe(false) }) it("won't freeze", () => { const base = {x: 1} const next = produce(base, draft => { draft.x++ expect(Object.isFrozen(current(draft))).toBe(false) }) }) it("returns original without changes", () => { const base = {} produce(base, draft => { expect(original(draft)).toBe(base) expect(current(draft)).toBe(base) }) }) it("can handle property additions", () => { const base = {} produce(base, draft => { draft.x = true const c = current(draft) expect(c).not.toBe(base) expect(c).not.toBe(draft) expect(c).toEqual({ x: true }) }) }) it("can handle property deletions", () => { const base = { x: 1 } produce(base, draft => { delete draft.x const c = current(draft) expect(c).not.toBe(base) expect(c).not.toBe(draft) expect(c).toEqual({}) }) }) it("won't reflect changes over time", () => { const base = { x: 1 } produce(base, draft => { draft.x++ const c = current(draft) expect(c).toEqual({ x: 2 }) draft.x++ expect(c).toEqual({ x: 2 }) }) }) it("will find drafts inside objects", () => { const base = { x: 1, y: { z: 2 }, z: {}, w: {}, ww: freeze({}) } produce(base, draft => { draft.y.z++ draft.z = { nested: { z: 3 } } const c = current(draft) expect(c).toEqual({ x: 1, y: { z: 3 }, z: {nested: {z: 3}}, w: {}, ww: {} }) expect(isDraft(c)).toBe(false) expect(isDraft(c.y)).toBe(false) expect(isDraft(c.z)).toBe(false) expect(isDraft(c.z.nested)).toBe(false) expect(isDraft(c.z.nested.z)).toBe(false) // this works only with frozen objects, otherwise no way to tell if this was // a new object that was added during the recipe, that might contain drafts. // the recipe or not expect(c.w).not.toBe(base.w) // was frozen, so recyclable expect(c.ww).toBe(base.ww) }) }) it("will find drafts inside objects - 2", () => { const base = { ar: [ { x: 1 }, {x: 2} ] } produce(base, draft => { draft.ar[1].x++ draft.ar = [draft.ar[1], draft.ar[0]] // swap const c = current(draft) expect(c).toEqual({ ar: [{x: 3}, {x: 1}] }) expect(isDraft(c)).toBe(false) expect(isDraft(c.ar)).toBe(false) expect(isDraft(c.ar[0])).toBe(false) expect(isDraft(c.ar[1])).toBe(false) expect(c.ar[1]).toBe(base.ar[0]) }) }) it("handles map - 1", () => { const base = new Map([["a", {x: 1}]]) produce(base, draft => { expect(current(draft)).toBe(base) draft.delete("a") let c = current(draft) expect(current(draft)).not.toBe(base) expect(current(draft)).not.toBe(draft) expect(c).toEqual(new Map()) const obj = {} draft.set("b", obj) expect(c).toEqual(new Map()) expect(current(draft)).toEqual(new Map([["b", obj]])) expect(c).toBeInstanceOf(Map) }) }) it("handles map - 2", () => { const base = new Map([["a", {x: 1}]]) produce(base, draft => { draft.get("a").x++ const c = current(draft) expect(c).not.toBe(base) expect(c).toEqual(new Map([["a", {x: 2}]])) draft.get("a").x++ expect(c).toEqual(new Map([["a", {x: 2}]])) }) }) it("handles set", () => { const base = new Set([1]) produce(base, draft => { expect(current(draft)).toBe(base) draft.add(2) const c = current(draft) expect(c).toEqual(new Set([1, 2])) expect(c).not.toBe(draft) expect(c).not.toBe(base) draft.add(3) expect(c).toEqual(new Set([1, 2])) expect(c).toBeInstanceOf(Set) }) }) it("handles simple class", () => { class Counter { [immerable] = true current = 0 inc() { this.current++ } } const counter1 = new Counter() produce(counter1, draft => { expect(current(draft)).toBe(counter1) draft.inc() const c = current(draft) expect(c).not.toBe(draft) expect(c.current).toBe(1) c.inc() expect(c.current).toBe(2) expect(draft.current).toBe(1) draft.inc() draft.inc() expect(c.current).toBe(2) expect(draft.current).toBe(3) expect(c).toBeInstanceOf(Counter) }) }) }) } ================================================ FILE: __tests__/curry.js ================================================ "use strict" import { produce, setUseProxies, produceWithPatches, enablePatches } from "../src/immer" enablePatches() runTests("proxy", true) function runTests(name) { describe("curry - " + name, () => { it("should check arguments", () => { expect(() => produce()).toThrowErrorMatchingSnapshot() expect(() => produce({})).toThrowErrorMatchingSnapshot() expect(() => produce({}, {})).toThrowErrorMatchingSnapshot() expect(() => produce({}, () => {}, [])).toThrowErrorMatchingSnapshot() }) it("should support currying", () => { const state = [{}, {}, {}] const mapper = produce((item, index) => { item.index = index }) expect(state.map(mapper)).not.toBe(state) expect(state.map(mapper)).toEqual([{index: 0}, {index: 1}, {index: 2}]) expect(state).toEqual([{}, {}, {}]) }) it("should support returning new states from curring", () => { const reducer = produce((item, index) => { if (!item) { return {hello: "world"} } item.index = index }) expect(reducer(undefined, 3)).toEqual({hello: "world"}) expect(reducer({}, 3)).toEqual({index: 3}) }) it("should support passing an initial state as second argument", () => { const reducer = produce( (item, index) => { item.index = index }, {hello: "world"} ) expect(reducer(undefined, 3)).toEqual({hello: "world", index: 3}) expect(reducer({}, 3)).toEqual({index: 3}) expect(reducer()).toEqual({hello: "world", index: undefined}) }) it("can has fun with change detection", () => { const spread = produce(Object.assign) const base = { x: 1, y: 1 } expect({...base}).not.toBe(base) expect(spread(base, {})).toBe(base) expect(spread(base, {y: 1})).toBe(base) expect(spread(base, {...base})).toBe(base) expect(spread(base, {...base, y: 2})).not.toBe(base) expect(spread(base, {...base, y: 2})).toEqual({x: 1, y: 2}) expect(spread(base, {z: 3})).toEqual({x: 1, y: 1, z: 3}) expect(spread(base, {y: 1})).toBe(base) }) }) it("support currying for produceWithPatches", () => { const increment = produceWithPatches((draft, delta) => { draft.x += delta }) expect(increment({x: 5}, 2)).toEqual([ {x: 7}, [ { op: "replace", path: ["x"], value: 7 } ], [ { op: "replace", path: ["x"], value: 5 } ] ]) }) } ================================================ FILE: __tests__/draft.ts ================================================ import {assert, _} from "./spec_ts" import {produce, Draft, castDraft, original} from "../src/immer" // For checking if a type is assignable to its draft type (and vice versa) const toDraft: (value: T) => Draft = x => x as any const fromDraft: (draft: Draft) => T = x => x as any test("draft.ts", () => { // Tuple { let val: [1, 2] = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Tuple (nested in a tuple) { let val: [[1, 2]] = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Tuple (nested in two mutable arrays) { let val: [1, 2][][] = _ let draft: typeof val = _ val = assert(toDraft(val), draft) assert(fromDraft(draft), val) } // Tuple (nested in two readonly arrays) { let val: ReadonlyArray> = _ let draft: [1, 2][][] = _ val = assert(toDraft(val), draft) } // Readonly tuple { // TODO: Uncomment this when readonly tuples are supported. // More info: https://stackoverflow.com/a/53822074/2228559 // let val: Readonly<[1, 2]> = _ // let draft: [1, 2] = _ // draft = assert(toDraft(val), draft) // val = fromDraft(draft) } // Mutable array { let val: string[] = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Mutable array (nested in tuple) { let val: [string[]] = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Readonly array { let val: ReadonlyArray = _ let draft: string[] = _ val = assert(toDraft(val), draft) fromDraft(draft) } // Readonly array (nested in readonly object) { let val: {readonly a: ReadonlyArray} = _ let draft: {a: string[]} = _ val = assert(toDraft(val), draft) fromDraft(draft) } // Mutable object { let val: {a: 1} = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Mutable object (nested in mutable object) { let val: {a: {b: 1}} = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Interface { interface Foo { a: {b: number} } let val: Foo = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Interface (nested in interface) { interface Foo { a: {b: number} } interface Bar { foo: Foo } let val: Bar = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Readonly object { let val: {readonly a: 1} = _ let draft: {a: 1} = _ val = assert(toDraft(val), draft) } // Readonly object (nested in tuple) { let val: [{readonly a: 1}] = _ let draft: [{a: 1}] = _ val = assert(toDraft(val), draft) } // Loose function { let val: Function = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Strict function { let val: () => void = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Class type (mutable) { class Foo { private test: any constructor(public bar: string) {} } let val: Foo = _ // TODO: Uncomment this when plain object types can be distinguished from class types. // More info here: https://github.com/Microsoft/TypeScript/issues/29063 // assert(toDraft(val), val) // assert(fromDraft(toDraft(val)), val) } // Class type (readonly) { class Foo { private test: any constructor(readonly bar: string) {} } let val: Foo = _ // TODO: Uncomment this when plain object types can be distinguished from class types. // More info here: https://github.com/Microsoft/TypeScript/issues/29063 // assert(toDraft(val), val) // assert(fromDraft(toDraft(val)), val) } // Map instance { let val: Map = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) // Weak maps let weak: WeakMap = _ assert(toDraft(weak), weak) assert(fromDraft(toDraft(weak)), weak) } // ReadonlyMap instance { let val: ReadonlyMap = _ let draft: Map = _ assert(toDraft(val), draft) } // Set instance { let val: Set = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) // Weak sets let weak: WeakSet = _ assert(toDraft(weak), weak) assert(fromDraft(toDraft(weak)), weak) } // ReadonlySet instance { let val: ReadonlySet = _ let draft: Set = _ assert(toDraft(val), draft) } // Promise object { let val: Promise = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Date instance { let val: Date = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // RegExp instance { let val: RegExp = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Boxed primitive { let val: Boolean = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // String literal { let val: string = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Any { let val: any = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Never { let val: never = _ as never assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Unknown { let val: unknown = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Numeral { let val: 1 = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Union of numerals { let val: 1 | 2 | 3 = _ assert(toDraft(val), val) assert(fromDraft(toDraft(val)), val) } // Union of tuple, array, object { let val: [0] | ReadonlyArray | Readonly<{a: 1}> = _ let draft: [0] | string[] | {a: 1} = _ val = assert(toDraft(val), draft) } // Generic type { // NOTE: "extends any" only helps a little. const $ = (val: ReadonlyArray) => { let draft: Draft = _ assert(toDraft(val), draft) // $ExpectError: [ts] Argument of type 'DraftArray' is not assignable to parameter of type 'Draft'. [2345] // assert(fromDraft(draft), draft) } } expect(true).toBe(true) }) test("castDraft", () => { type Todo = {readonly done: boolean} type State = { readonly finishedTodos: ReadonlyArray readonly unfinishedTodos: ReadonlyArray } function markAllFinished(state: State) { produce(state, draft => { draft.finishedTodos = castDraft(state.unfinishedTodos) }) } }) test("#505 original", () => { const baseState = {users: [{name: "Richie"}] as const} const nextState = produce(baseState, draftState => { original(draftState.users) === baseState.users }) }) test("castDraft preserves a value", () => { const x = {} expect(castDraft(x)).toBe(x) }) test("#512 createDraft creates a draft", () => { const x = {y: 1} assert(x, _ as Draft<{y: number}>) }) ================================================ FILE: __tests__/empty.ts ================================================ import { produce, produceWithPatches, immerable, enableMapSet, enablePatches, applyPatches } from "../src/immer" import {DRAFT_STATE, Patch} from "../src/internal" enableMapSet() enablePatches() test("empty stub test", () => { expect(true).toBe(true) }) describe("map set - proxy", () => { test("can assign set value", () => { const baseState = new Map([["x", 1]]) const nextState = produce(baseState, s => { s.set("x", 2) }) expect(baseState.get("x")).toEqual(1) expect(nextState).not.toBe(baseState) expect(nextState.get("x")).toEqual(2) }) test("can assign by key", () => { const baseState = new Map([["x", {a: 1}]]) const nextState = produce(baseState, s => { s.get("x")!.a++ }) expect(nextState.get("x")!.a).toEqual(2) expect(baseState.get("x")!.a).toEqual(1) expect(nextState).not.toBe(baseState) }) test("deep change bubbles up", () => { const baseState = createBaseState() const nextState = produce(baseState, s => { s.anObject.nested.yummie = false }) expect(nextState).not.toBe(baseState) expect(nextState.anObject).not.toBe(baseState.anObject) expect(baseState.anObject.nested.yummie).toBe(true) expect(nextState.anObject.nested.yummie).toBe(false) expect(nextState.anArray).toBe(baseState.anArray) }) it("can assign by key", () => { const baseState = createBaseState() const nextState = produce(baseState, s => { // Map.prototype.set should return the Map itself const res = s.aMap.set("force", true) // @ts-ignore if (!global.USES_BUILD) expect(res).toBe((s.aMap as any)[DRAFT_STATE].draft_) }) expect(nextState).not.toBe(baseState) expect(nextState.aMap).not.toBe(baseState.aMap) expect(nextState.aMap.get("force")).toEqual(true) }) it("can use 'delete' to remove items", () => { const baseState = createBaseState() const nextState = produce(baseState, s => { expect(s.aMap.has("jedi")).toBe(true) expect(s.aMap.delete("jedi")).toBe(true) expect(s.aMap.has("jedi")).toBe(false) }) expect(nextState.aMap).not.toBe(baseState.aMap) expect(nextState.aMap.size).toBe(baseState.aMap.size - 1) expect(baseState.aMap.has("jedi")).toBe(true) expect(nextState.aMap.has("jedi")).toBe(false) }) it("support 'has'", () => { const baseState = createBaseState() const nextState = produce(baseState, s => { expect(s.aMap.has("newKey")).toBe(false) s.aMap.set("newKey", true) expect(s.aMap.has("newKey")).toBe(true) }) expect(nextState).not.toBe(baseState) expect(nextState.aMap).not.toBe(baseState.aMap) expect(baseState.aMap.has("newKey")).toBe(false) expect(nextState.aMap.has("newKey")).toBe(true) }) }) function createBaseState() { const data = { anInstance: new (class {})(), anArray: [3, 2, {c: 3}, 1], aMap: new Map([ ["jedi", {name: "Luke", skill: 10}], ["jediTotal", 42], ["force", "these aren't the droids you're looking for"] ] as any), aSet: new Set([ "Luke", 42, { jedi: "Yoda" } ]), aProp: "hi", anObject: { nested: { yummie: true }, coffee: false } } return data } describe("#768", () => { class Stock { [immerable] = true constructor(public price: number) {} pushPrice(price: number) { this.price = price } } type State = { stock: Stock } test("bla", () => { // Set up conditions to produce the error const errorProducingPatch = [ { op: "replace", path: ["stock"], value: new Stock(200) } ] as Patch[] // Start with modified state const state = { stock: new Stock(100) } expect(state.stock.price).toEqual(100) expect(state.stock[immerable]).toBeTruthy() // Use patch to "replace" stocks const resetState: State = applyPatches(state, errorProducingPatch) expect(state.stock.price).toEqual(100) expect(resetState.stock.price).toEqual(200) expect(resetState.stock[immerable]).toBeTruthy() // Problems come in when resetState is modified const updatedState = produce(resetState, draft => { draft.stock.pushPrice(300) }) expect(state.stock.price).toEqual(100) expect(updatedState.stock.price).toEqual(300) expect(updatedState.stock[immerable]).toBeTruthy() expect(resetState.stock.price).toEqual(200) }) }) ================================================ FILE: __tests__/flow/.flowconfig ================================================ [include] ../../dist [lints] ambiguous-object-type=error deprecated-type=error untyped-import=error [options] suppress_comment= \\(.\\|\n\\)*\\$ExpectError include_warnings=true ================================================ FILE: __tests__/flow/flow.js.flow ================================================ // @flow import { produce, enableMapSet, setAutoFreeze, produce as produce2, applyPatches, Patch, original } from "../../dist/cjs/index.js.flow" enableMapSet() setAutoFreeze(true) // we really don't want this code to actually execute.. const result = produce({x: 3}, draft => { draft.x = 4 // $ExpectError console.log(draft.y) }) console.log(result.x) const result2 = produce({x: 3}, draft => { return {x: 4} }) console.log(result2.x) const f = produce( (draft): {| x: number |} => { return {x: 4} } ) f({x: 3}) const f2 = produce((draft): void => {}) f2({x: 3}) // $ExpectError setAutoFreeze(3) // $ExpectError console.log(result.y) // $ExpectError produce() // $ExpectError produce({x: 3}) // $ExpectError produce({x: 3}, []) { // curried & initial arg const f = produce( (state, increment: number): void => { state.x += increment }, {x: 3} ) // $ExpectError Too few arguments f({x: 5}) // $ExpectError f({x: 5}, "test") f({x: 5}, 3) f(undefined, 3) } { // curried f & no initial arg const f2 = produce( (state: {| x: number |}, increment: number): void => { state.x += increment } ) f2({x: 5}, 3) // $ExpectError f2(undefined, 3) } type State = {| user: {| age: number |} |} { declare function setState(updater: (State) => $Shape): void // curried use with setState, infer type of draft setState(produce(draft => { if (draft.user.age === 10) { return } draft.user.age += 1 // $ExpectError draft.user.name = "missing" })) } { // $ExpectError produce2({x: 3}) const result = produce2({x: 3}, draft => { draft.x = 4 // $ExpectError console.log(draft.y) }) } { let p: Patch[] = [] produce( {}, d => {}, (patches, inverse) => { p = patches } ) applyPatches({}, p) } { produce({x: 3}, draftState => { let a = original(draftState) if (a) { a.x // $ExpectError a.y } }) } { const arr: Array = [1] produce(arr, draftState => { const a = original(draftState) if (a) { const b: number = a[0] // $ExpectError const c: string = a[0] } }) } function testMap(state: Map) { // normal state = produce(state, draft => { if (draft.has(1)) { return } // $ExpectError draft.set(1, 2) draft.set(1, "tada") }) // curried, no initial state const f1 = produce(draft=> { draft.set(2, "ok") }) state = f1(state) // curried, with initial state const f2 = produce(draft=> { draft.set(2, "ok") }, state) state = f2(state) state = f2(undefined) } function testSet(state: Set) { // normal state = produce(state, draft => { if (draft.has(1)) { return } // $ExpectError draft.add("me") draft.add(100) }) // curried, no initial state const f1 = produce(draft => { draft.add(draft.size) }) state = f1(state) // curried, with initial state const f2 = produce(draft => { draft.add(draft.size) }, state) state = f2(state) state = f2(undefined) } ================================================ FILE: __tests__/frozen.js ================================================ "use strict" import { produce, setUseProxies, setAutoFreeze, freeze, enableMapSet } from "../src/immer" enableMapSet() const {isFrozen} = Object runTests("proxy", true) function runTests(name) { describe("auto freeze - " + name, () => { beforeAll(() => { setAutoFreeze(true) }) it("never freezes the base state", () => { const base = {arr: [1], obj: {a: 1}} const next = produce(base, draft => { draft.arr.push(1) }) expect(isFrozen(base)).toBeFalsy() expect(isFrozen(base.arr)).toBeFalsy() expect(isFrozen(next)).toBeTruthy() expect(isFrozen(next.arr)).toBeTruthy() }) it("freezes reused base state", () => { const base = {arr: [1], obj: {a: 1}} const next = produce(base, draft => { draft.arr.push(1) }) expect(next.obj).toBe(base.obj) expect(isFrozen(next.obj)).toBeTruthy() }) describe("the result is always auto-frozen when", () => { it("the root draft is mutated (and no error is thrown)", () => { const base = {} const next = produce(base, draft => { draft.a = 1 }) expect(next).not.toBe(base) expect(isFrozen(next)).toBeTruthy() }) it("a nested draft is mutated (and no error is thrown)", () => { const base = {a: {}} const next = produce(base, draft => { draft.a.b = 1 }) expect(next).not.toBe(base) expect(isFrozen(next)).toBeTruthy() expect(isFrozen(next.a)).toBeTruthy() }) it("a new object replaces the entire draft", () => { const obj = {a: {b: {}}} const next = produce({}, () => obj) expect(next).toBe(obj) expect(isFrozen(next)).toBeTruthy() expect(isFrozen(next.a)).toBeTruthy() expect(isFrozen(next.a.b)).toBeTruthy() }) it("a new object is added to the root draft", () => { const base = {} const next = produce(base, draft => { draft.a = {b: []} }) expect(next).not.toBe(base) expect(isFrozen(next)).toBeTruthy() expect(isFrozen(next.a)).toBeTruthy() expect(isFrozen(next.b)).toBeTruthy() }) it("a new object is added to a nested draft", () => { const base = {a: {}} const next = produce(base, draft => { draft.a.b = {c: {}} }) expect(next).not.toBe(base) expect(isFrozen(next)).toBeTruthy() expect(isFrozen(next.a)).toBeTruthy() expect(isFrozen(next.a.b)).toBeTruthy() expect(isFrozen(next.a.b.c)).toBeTruthy() }) it("a nested draft is returned", () => { const base = {a: {}} const next = produce(base, draft => draft.a) expect(next).toBe(base.a) expect(isFrozen(next)).toBeTruthy() }) it("the base state is returned", () => { const base = {} const next = produce(base, () => base) expect(next).toBe(base) expect(isFrozen(next)).toBeTruthy() }) it("the producer is a no-op", () => { const base = {a: {}} const next = produce(base, () => {}) expect(next).toBe(base) expect(isFrozen(next)).toBeTruthy() expect(isFrozen(next.a)).toBeTruthy() }) it("the root draft is returned", () => { const base = {a: {}} const next = produce(base, draft => draft) expect(next).toBe(base) expect(isFrozen(next)).toBeTruthy() expect(isFrozen(next.a)).toBeTruthy() }) it("a new object replaces a primitive base", () => { const obj = {a: {}} const next = produce(null, () => obj) expect(next).toBe(obj) expect(isFrozen(next)).toBeTruthy() expect(isFrozen(next.a)).toBeTruthy() }) }) it("can handle already frozen trees", () => { const a = [] const b = {a: a} Object.freeze(a) Object.freeze(b) const n = produce(b, draft => { draft.c = true draft.a.push(3) }) expect(n).toEqual({c: true, a: [3]}) }) it("will freeze maps", () => { const base = new Map() const res = produce(base, draft => { draft.set("a", 1) draft.set("o", {b: 1}) }) expect(() => res.set("b", 2)).toThrowErrorMatchingSnapshot() expect(() => res.clear()).toThrowErrorMatchingSnapshot() expect(() => res.delete("b")).toThrowErrorMatchingSnapshot() expect(Object.isFrozen(res.get("o"))).toBe(true) // In draft, still editable expect(produce(res, d => void d.set("a", 2))).not.toBe(res) }) it("will freeze sets", () => { const base = new Set() const res = produce(base, draft => { base.add(1) }) expect(() => base.add(2)).toThrowErrorMatchingSnapshot() expect(() => base.delete(1)).toThrowErrorMatchingSnapshot() expect(() => base.clear()).toThrowErrorMatchingSnapshot() // In draft, still editable expect(produce(res, d => void d.add(2))).not.toBe(res) }) it("Map#get() of frozen object will became draftable", () => { const base = { map: new Map([ [ "a", new Map([ ["a", true], ["b", true], ["c", true] ]) ], ["b", new Map([["a", true]])], ["c", new Map([["a", true]])] ]) } // This will freeze maps const frozen = produce(base, draft => {}) // https://github.com/immerjs/immer/issues/472 produce(frozen, draft => { ;["b", "c"].forEach(other => { const m = draft.map.get(other) m.delete("a") }) }) }) it("never freezes non-enumerable fields #590", () => { const component = {} Object.defineProperty(component, "state", { value: {x: 1}, enumerable: false, writable: true, configurable: true }) const state = { x: 1 } const state2 = produce(state, draft => { draft.ref = component }) expect(() => { state2.ref.state.x++ }).not.toThrow() expect(state2.ref.state.x).toBe(2) expect(component.state.x).toBe(2) }) it("never freezes symbolic fields #590", () => { const component = {} const symbol = Symbol("test") Object.defineProperty(component, symbol, { value: {x: 1}, enumerable: true, writable: true, configurable: true }) const state = { x: 1 } const state2 = produce(state, draft => { draft.ref = component }) expect(() => { state2.ref[symbol].x++ }).not.toThrow() expect(state2.ref[symbol].x).toBe(2) }) }) } test("freeze - shallow", () => { const obj1 = {hello: {world: true}} const res = freeze(obj1) expect(res).toBe(obj1) expect(Object.isFrozen(res)).toBe(true) expect(Object.isFrozen(res.hello)).toBe(false) }) test("freeze - deep", () => { const obj1 = {hello: {world: true}} const res = freeze(obj1, true) expect(res).toBe(obj1) expect(Object.isFrozen(res)).toBe(true) expect(Object.isFrozen(res.hello)).toBe(true) }) ================================================ FILE: __tests__/immutable.ts ================================================ import {assert, _} from "./spec_ts" import {produce, Immutable, castImmutable} from "../src/immer" test("types are ok", () => { // array in tuple { let val = _ as Immutable<[string[], 1]> assert(val, _ as readonly [ReadonlyArray, 1]) } // tuple in array { let val = _ as Immutable<[string, 1][]> assert(val, _ as ReadonlyArray) } // tuple in tuple { let val = _ as Immutable<[[string, 1], 1]> assert(val, _ as readonly [readonly [string, 1], 1]) } // array in array { let val = _ as Immutable assert(val, _ as ReadonlyArray>) } // tuple in object { let val = _ as Immutable<{a: [string, 1]}> assert(val, _ as {readonly a: readonly [string, 1]}) } // object in tuple { let val = _ as Immutable<[{a: string}, 1]> assert(val, _ as readonly [{readonly a: string}, 1]) } // array in object { let val = _ as Immutable<{a: string[]}> assert(val, _ as {readonly a: ReadonlyArray}) } // object in array { let val = _ as Immutable> assert(val, _ as ReadonlyArray<{readonly a: string}>) } // object in object { let val = _ as Immutable<{a: {b: string}}> assert(val, _ as {readonly a: {readonly b: string}}) } // Map { let val = _ as Immutable> assert(val, _ as ReadonlyMap) } // Already immutable Map { let val = _ as Immutable> assert(val, _ as ReadonlyMap) } // object in Map { let val = _ as Immutable> assert(val, _ as ReadonlyMap<{readonly a: string}, {readonly b: string}>) } // Set { let val = _ as Immutable> assert(val, _ as ReadonlySet) } // Already immutable Set { let val = _ as Immutable> assert(val, _ as ReadonlySet) } // object in Set { let val = _ as Immutable> assert(val, _ as ReadonlySet<{readonly a: string}>) } expect(true).toBe(true) }) test("#381 produce immutable state", () => { const someState = { todos: [ { done: false } ] } const immutable = castImmutable(produce(someState, _draft => {})) assert( immutable, _ as {readonly todos: ReadonlyArray<{readonly done: boolean}>} ) }) test("castImmutable preserves a value", () => { const x = {} expect(castImmutable(x)).toBe(x) }) ================================================ FILE: __tests__/isDraftable.js ================================================ "use strict" import {isDraftable} from "../src/immer" test("non-plain object with undefined constructor doesn't error", () => { const obj = Object.create(Object.create(null)) expect(isDraftable(obj)).toBe(false) }) ================================================ FILE: __tests__/manual.js ================================================ "use strict" import {vi} from "vitest" import { setUseProxies, createDraft, finishDraft, produce, isDraft, enablePatches } from "../src/immer" enablePatches() const isProd = process.env.NODE_ENV === "production" runTests("proxy", true) function runTests(name) { describe("manual - " + name, () => { it("should check arguments", () => { expect(() => createDraft(3)).toThrowErrorMatchingSnapshot() const buf = Buffer.from([]) expect(() => createDraft(buf)).toThrowErrorMatchingSnapshot() expect(() => finishDraft({})).toThrowErrorMatchingSnapshot() }) it("should support manual drafts", () => { const state = [{}, {}, {}] const draft = createDraft(state) draft.forEach((item, index) => { item.index = index }) const result = finishDraft(draft) expect(result).not.toBe(state) expect(result).toEqual([{index: 0}, {index: 1}, {index: 2}]) expect(state).toEqual([{}, {}, {}]) }) if (!isProd) it("cannot modify after finish", () => { const state = {a: 1} const draft = createDraft(state) draft.a = 2 expect(finishDraft(draft)).toEqual({a: 2}) expect(() => { draft.a = 3 }).toThrowErrorMatchingSnapshot() }) it("cannot finishDraft twice", () => { const state = {a: 1} const draft = createDraft(state) draft.a = 2 expect(finishDraft(draft)).toEqual({a: 2}) expect(() => { finishDraft(draft) }).toThrowErrorMatchingSnapshot() }) it("should support patches drafts", () => { const state = {a: 1} const draft = createDraft(state) draft.a = 2 draft.b = 3 const listener = vi.fn() const result = finishDraft(draft, listener) expect(result).not.toBe(state) expect(result).toEqual({a: 2, b: 3}) expect(listener.mock.calls).toMatchSnapshot() }) it("should handle multiple create draft calls", () => { const state = {a: 1} const draft = createDraft(state) draft.a = 2 const draft2 = createDraft(state) draft2.b = 3 const result = finishDraft(draft) expect(result).not.toBe(state) expect(result).toEqual({a: 2}) draft2.a = 4 const result2 = finishDraft(draft2) expect(result2).not.toBe(result) expect(result2).toEqual({a: 4, b: 3}) }) it("combines with produce - 1", () => { const state = {a: 1} const draft = createDraft(state) draft.a = 2 const res1 = produce(draft, d => { d.b = 3 }) draft.b = 4 const res2 = finishDraft(draft) expect(res1).toEqual({a: 2, b: 3}) expect(res2).toEqual({a: 2, b: 4}) }) it("combines with produce - 2", () => { const state = {a: 1} const res1 = produce(state, draft => { draft.b = 3 const draft2 = createDraft(draft) draft.c = 4 draft2.d = 5 const res2 = finishDraft(draft2) expect(res2).toEqual({ a: 1, b: 3, d: 5 }) draft.d = 2 }) expect(res1).toEqual({ a: 1, b: 3, c: 4, d: 2 }) }) !global.USES_BUILD && it("should not finish drafts from produce", () => { produce({x: 1}, draft => { expect(() => finishDraft(draft)).toThrowErrorMatchingSnapshot() }) }) it("should not finish twice", () => { const draft = createDraft({a: 1}) draft.a++ finishDraft(draft) expect(() => finishDraft(draft)).toThrowErrorMatchingSnapshot() }) }) } ================================================ FILE: __tests__/map-set.js ================================================ "use strict" import {vi} from "vitest" import { Immer, nothing, original, isDraft, immerable, enablePatches, enableMapSet } from "../src/immer" import {each, shallowCopy, isEnumerable, DRAFT_STATE} from "../src/utils/common" enableMapSet() enablePatches() vi.setConfig({ testTimeout: 1000 }) runBaseTest("proxy (no freeze)", true, false) runBaseTest("proxy (autofreeze)", true, true) runBaseTest("proxy (autofreeze)(patch listener)", true, true, true) function runBaseTest(name, autoFreeze, useListener) { const listener = useListener ? function() {} : undefined const {produce, produceWithPatches} = createPatchedImmer({ autoFreeze }) // When `useListener` is true, append a function to the arguments of every // uncurried `produce` call in every test. This makes tests easier to read. function createPatchedImmer(options) { const immer = new Immer(options) const {produce} = immer immer.produce = function(...args) { return typeof args[1] === "function" && args.length < 3 ? produce(...args, listener) : produce(...args) } return immer } describe("map issues " + name, () => { test("#472 ", () => { const project = produce(new Map(), draft => { draft.set("bar1", {blocked: false}) draft.set("bar2", {blocked: false}) }) // Read before write -- no error produce(project, draft => { const bar1 = draft.get("bar1") const bar2 = draft.get("bar2") bar1.blocked = true bar2.blocked = true }) // Read/write interleaved -- error produce(project, draft => { const bar1 = draft.get("bar1") bar1.blocked = true const bar2 = draft.get("bar2") bar2.blocked = true // TypeError: "blocked" is read-only }) }) test("#466 - setNoPatches", () => { const obj = { set: new Set() } const result = produceWithPatches(obj, draft => { draft.set.add("abc") }) expect(result).toEqual([ {set: new Set(["abc"])}, [{op: "add", path: ["set", 0], value: "abc"}], [{op: "remove", path: ["set", 0], value: "abc"}] ]) }) test("#466 - mapChangeBug ", () => { const obj = { map: new Map([ [ "a", new Map([ ["b", true], ["c", true], ["d", true] ]) ], ["b", new Map([["a", true]])], ["c", new Map([["a", true]])], ["d", new Map([["a", true]])] ]) } const result = produceWithPatches(obj, draft => { const aMap = draft.map.get("a") aMap.forEach((_, other) => { const otherMap = draft.map.get(other) otherMap.delete("a") }) }) expect(result).toEqual([ { map: new Map([ [ "a", new Map([ ["b", true], ["c", true], ["d", true] ]) ], ["b", new Map()], ["c", new Map()], ["d", new Map()] ]) }, [ { op: "remove", path: ["map", "d", "a"] }, { op: "remove", path: ["map", "c", "a"] }, { op: "remove", path: ["map", "b", "a"] } ], [ { op: "add", path: ["map", "d", "a"], value: true }, { op: "add", path: ["map", "c", "a"], value: true }, { op: "add", path: ["map", "b", "a"], value: true } ] ]) }) test("#466 - mapChangeBug2 ", () => { const obj = { map: new Map([ [ "a", new Map([ ["b", true], ["c", true], ["d", true] ]) ], ["b", new Map([["a", true]])], ["c", new Map([["a", true]])], ["d", new Map([["a", true]])] ]) } const obj1 = produce(obj, draft => {}) const [result, p, ip] = produceWithPatches(obj1, draft => { const aMap = draft.map.get("a") aMap.forEach((_, other) => { const otherMap = draft.map.get(other) otherMap.delete("a") }) }) expect(result).toEqual({ map: new Map([ [ "a", new Map([ ["b", true], ["c", true], ["d", true] ]) ], ["b", new Map([])], ["c", new Map([])], ["d", new Map([])] ]) }) expect(p).toEqual([ { op: "remove", path: ["map", "d", "a"] }, { op: "remove", path: ["map", "c", "a"] }, { op: "remove", path: ["map", "b", "a"] } ]) expect(ip).toEqual([ { op: "add", path: ["map", "d", "a"], value: true }, { op: "add", path: ["map", "c", "a"], value: true }, { op: "add", path: ["map", "b", "a"], value: true } ]) }) test("#586", () => { const base = new Set([1, 2]) const set = produce(base, draftSet => { debugger expect(Array.from(draftSet)).toEqual([1, 2]) draftSet.add(3) }) expect(Array.from(set).sort()).toEqual([1, 2, 3]) }) test("#627 - new map key with value=undefined", () => { const map = new Map() const map1 = produce(map, draft => { draft.set("key", undefined) }) expect(map1.has("key")).toBe(true) expect(map1.get("key")).toBe(undefined) }) test("#663 - clear map", () => { const map = new Map([ ["a", "b"], ["b", "c"] ]) const result = produceWithPatches(map, draft => { draft.clear() }) expect(result).toEqual([ new Map(), [ {op: "remove", path: ["a"]}, {op: "remove", path: ["b"]} ], [ {op: "add", path: ["a"], value: "b"}, {op: "add", path: ["b"], value: "c"} ] ]) }) test("#680 - Clearing empty Set&Map should be noop", () => { const map = new Map() let result = produce(map, draft => { draft.clear() }) expect(result).toBe(map) const set = new Set() result = produce(set, draft => { draft.clear() }) expect(result).toBe(set) }) test("#692 - idempotent plugin loading", () => { let mapType1 produce(new Map(), draft => { mapType1 = draft.constructor }) enableMapSet() let mapType2 produce(new Map(), draft => { mapType2 = draft.constructor }) expect(mapType1).toBe(mapType2) }) test("#819 - Set with object maintains order when adding object", () => { const items = [ { id: "a" }, { id: "b" } ] const set = new Set([items[0]]) const newSet = produce(set, draft => { draft.add(items[1]) }) expect(Array.from(newSet)).toEqual([items[0], items[1]]) }) // More specific varaint of above test covering case of adding non-object item test("#819 - Set with object maintains order when adding string", () => { const items = [ { id: "a" }, "b" ] const set = new Set([items[0]]) const newSet = produce(set, draft => { draft.add(items[1]) }) expect(Array.from(newSet)).toEqual([items[0], items[1]]) }) }) describe("set issues " + name, () => { test("#819.A - maintains order when adding", () => { const objs = [ "a", { id: "b" } ] const set = new Set([objs[0]]) const newSet = produce(set, draft => { draft.add(objs[1]) }) // passes expect(Array.from(newSet)).toEqual([objs[0], objs[1]]) }) test("#819.B - maintains order when adding", () => { const objs = [ { id: "a" }, "b" ] const set = new Set([objs[0]]) const newSet = produce(set, draft => { draft.add(objs[1]) }) expect(Array.from(newSet)).toEqual([objs[0], objs[1]]) }) }) } // Bug reproduction: DraftSet leakage when placed in new object and set into Map // This bug occurs when a plain object containing a draft Set is set into a DraftMap describe("RTK-5159: DraftSet leakage in Map", () => { const {produce} = new Immer({autoFreeze: true}) test("DraftSet should not leak when placed in new object and set into Map", () => { const baseState = { map: new Map([["key1", {users: new Set()}]]) } // First produce: add a user const state1 = produce(baseState, draft => { const entry = draft.map.get("key1") entry.users.add({name: "user1"}) }) // Second produce: create new object with existing Set and set into Map const state2 = produce(state1, draft => { const existingUsers = draft.map.get("key1")?.users ?? new Set() const newEntry = {users: existingUsers} // New plain object with existing draft Set draft.map.set("key1", newEntry) newEntry.users.add({name: "user2"}) }) // Should not throw "Cannot use a proxy that has been revoked" const users = state2.map.get("key1").users expect(users).toBeInstanceOf(Set) expect([...users].map(u => u.name)).toEqual(["user1", "user2"]) }) test("DraftSet in new object set into Map should finalize correctly", () => { const baseState = { map: new Map([["key1", {items: new Set([1, 2, 3])}]]) } const result = produce(baseState, draft => { const existingItems = draft.map.get("key1").items // Create a new plain object containing the draft Set const newEntry = {items: existingItems, extra: "data"} draft.map.set("key1", newEntry) newEntry.items.add(4) }) // Verify the result is properly finalized (not a draft/proxy) const items = result.map.get("key1").items expect(items).toBeInstanceOf(Set) expect([...items]).toEqual([1, 2, 3, 4]) expect(result.map.get("key1").extra).toBe("data") }) // Test for DraftSet.add() with non-draft object containing nested draft // This covers the handleCrossReference() call in DraftSet.add() test("DraftSet.add() should handle non-draft object containing nested draft", () => { const baseState = { items: [{id: 1, name: "item1"}], itemSet: new Set() } const result = produce(baseState, draft => { // Get a draft of an existing item const draftItem = draft.items[0] // Create a new plain object that contains the draft const wrapper = {item: draftItem, extra: "wrapper data"} // Add the non-draft wrapper (containing a draft) to the Set draft.itemSet.add(wrapper) // Modify the draft item after adding draftItem.name = "modified" }) // The wrapper should be finalized correctly const addedItems = [...result.itemSet] expect(addedItems).toHaveLength(1) expect(addedItems[0].item.id).toBe(1) expect(addedItems[0].item.name).toBe("modified") expect(addedItems[0].extra).toBe("wrapper data") // Verify it's not a proxy expect(() => JSON.stringify(result)).not.toThrow() }) test("DraftSet.add() should handle deeply nested drafts in plain objects", () => { const baseState = { nested: { deep: { value: "original" } }, mySet: new Set() } const result = produce(baseState, draft => { // Get a draft of a deeply nested object const deepDraft = draft.nested.deep // Create a plain object hierarchy containing the draft const wrapper = { level1: { level2: { draftRef: deepDraft } } } // Add to Set draft.mySet.add(wrapper) // Modify the draft deepDraft.value = "modified" }) const items = [...result.mySet] expect(items).toHaveLength(1) expect(items[0].level1.level2.draftRef.value).toBe("modified") // Should not throw when accessing expect(() => JSON.stringify(result)).not.toThrow() }) }) ================================================ FILE: __tests__/not-strict-copy.ts ================================================ import { immerable, produce, setUseStrictShallowCopy, setAutoFreeze, StrictMode } from "../src/immer" describe.each([true, false, "class_only" as const])( "setUseStrictShallowCopy(true)", (strictMode: StrictMode) => { test("keep descriptors, mode: " + strictMode, () => { setUseStrictShallowCopy(strictMode) const base: Record = {} Object.defineProperty(base, "foo", { value: "foo", writable: false, configurable: false }) const copy = produce(base, (draft: any) => { draft.bar = "bar" }) if (strictMode === true) { expect(Object.getOwnPropertyDescriptor(copy, "foo")).toStrictEqual( Object.getOwnPropertyDescriptor(base, "foo") ) } else { expect(Object.getOwnPropertyDescriptor(copy, "foo")).toBeUndefined() } }) test("keep non-enumerable class descriptors, mode: " + strictMode, () => { setUseStrictShallowCopy(strictMode) setAutoFreeze(false) class X { [immerable] = true foo = "foo" bar!: string constructor() { Object.defineProperty(this, "bar", { get() { return this.foo + "bar" }, configurable: false, enumerable: false }) } get baz() { return this.foo + "baz" } } const copy = produce(new X(), (draft: any) => { draft.foo = "FOO" }) const strict = strictMode === true || strictMode === "class_only" // descriptors on the prototype are unaffected, so this is still a getter expect(copy.baz).toBe("FOObaz") // descriptors on the instance are found, even when non-enumerable, and read during copy // so new values won't be reflected expect(copy.bar).toBe(strict ? "foobar" : undefined) copy.foo = "fluff" // not updated, the own prop became a value expect(copy.bar).toBe(strict ? "foobar" : undefined) // updated, it is still a getter expect(copy.baz).toBe("fluffbaz") }) } ) ================================================ FILE: __tests__/null.js ================================================ "use strict" import {produce} from "../src/immer" describe("null functionality", () => { const baseState = null it("should return the original without modifications", () => { const nextState = produce(baseState, () => {}) expect(nextState).toBe(baseState) }) }) ================================================ FILE: __tests__/original.js ================================================ "use strict" import {produce, original} from "../src/immer" const isProd = process.env.NODE_ENV === "production" describe("original", () => { const baseState = { a: [], b: {} } it("should return the original from the draft", () => { produce(baseState, draftState => { expect(original(draftState)).toBe(baseState) expect(original(draftState.a)).toBe(baseState.a) expect(original(draftState.b)).toBe(baseState.b) }) }) it("should return the original from the proxy", () => { produce(baseState, draftState => { expect(original(draftState)).toBe(baseState) expect(original(draftState.a)).toBe(baseState.a) expect(original(draftState.b)).toBe(baseState.b) }) }) it("should throw undefined for new values on the draft", () => { produce(baseState, draftState => { draftState.c = {} draftState.d = 3 expect(() => original(draftState.c)).toThrowError( isProd ? `[Immer] minified error nr: 15. Full error at: https://bit.ly/3cXEKWf` : `[Immer] 'original' expects a draft, got: [object Object]` ) expect(() => original(draftState.d)).toThrowError( isProd ? `[Immer] minified error nr: 15. Full error at: https://bit.ly/3cXEKWf` : `[Immer] 'original' expects a draft, got: 3` ) }) }) it("should return undefined for an object that is not proxied", () => { expect(() => original({})).toThrowError( isProd ? `[Immer] minified error nr: 15. Full error at: https://bit.ly/3cXEKWf` : `[Immer] 'original' expects a draft, got: [object Object]` ) expect(() => original(3)).toThrowError( isProd ? `[Immer] minified error nr: 15. Full error at: https://bit.ly/3cXEKWf` : `[Immer] 'original' expects a draft, got: 3` ) }) }) ================================================ FILE: __tests__/patch.js ================================================ "use strict" import {vi} from "vitest" import { produce, applyPatches, produceWithPatches, isDraft, immerable, nothing, enablePatches, enableMapSet } from "../src/immer" enablePatches() enableMapSet() vi.setConfig({ testTimeout: 1000 }) const isProd = process.env.NODE_ENV === "production" function createPatchTestData( base, producer, expectedPatches, expectedInversePatches, expectedResult ) { let recordedPatches, recordedInversePatches const res = produce(base, producer, (p, i) => { recordedPatches = p recordedInversePatches = i }) return { result: res, patches: recordedPatches, inversePatches: recordedInversePatches, expectedPatches, expectedInversePatches, expectedResult, base } } function runPatchTests( testName, base, producer, expectedPatches, expectedInversePatches, expectedResult, options = {} ) { const {only = false, skip = false} = options // Choose the appropriate describe function let describeFn = describe if (testName === "") describeFn = (name, fn) => fn() if (only) describeFn = describe.only if (skip) describeFn = describe.skip let testData = createPatchTestData( base, producer, expectedPatches, expectedInversePatches, expectedResult ) describeFn(testName, () => { if (expectedResult !== undefined) { test("produced the correct result", () => { expect(testData.result).toEqual(expectedResult) }) } test("produces the correct patches", () => { expect(testData.patches).toEqual(expectedPatches) if (expectedInversePatches) { expect(testData.inversePatches).toEqual(expectedInversePatches) } }) test("patches are replayable", () => { expect(applyPatches(base, testData.patches)).toEqual(testData.result) }) test("patches can be reversed", () => { if (expectedInversePatches) { expect(applyPatches(testData.result, testData.inversePatches)).toEqual( base ) } }) }) return testData } // Convenience functions for common use cases runPatchTests.only = function( testName, base, producer, expectedPatches, expectedInversePatches, expectedResult ) { return runPatchTests( testName, base, producer, expectedPatches, expectedInversePatches, expectedResult, {only: true} ) } runPatchTests.skip = function( testName, base, producer, expectedPatches, expectedInversePatches, expectedResult ) { return runPatchTests( testName, base, producer, expectedPatches, expectedInversePatches, expectedResult, {skip: true} ) } describe("applyPatches", () => { it("mutates the base state when it is a draft", () => { produce({a: 1}, draft => { const result = applyPatches(draft, [ {op: "replace", path: ["a"], value: 2} ]) expect(result).toBe(draft) expect(draft.a).toBe(2) }) }) it("produces a copy of the base state when not a draft", () => { const base = {a: 1} const result = applyPatches(base, [{op: "replace", path: ["a"], value: 2}]) expect(result).not.toBe(base) expect(result.a).toBe(2) expect(base.a).toBe(1) }) it('throws when `op` is not "add", "replace", nor "remove"', () => { expect(() => { const patch = {op: "copy", from: [0], path: [1]} applyPatches([2], [patch]) }).toThrowErrorMatchingSnapshot() }) it("throws when `path` cannot be resolved", () => { // missing parent expect(() => { const patch = {op: "add", path: ["a", "b"], value: 1} applyPatches({}, [patch]) }).toThrowErrorMatchingSnapshot() // missing grand-parent expect(() => { const patch = {op: "add", path: ["a", "b", "c"], value: 1} applyPatches({}, [patch]) }).toThrowErrorMatchingSnapshot() }) it("applied patches cannot be modified", () => { // see also: https://github.com/immerjs/immer/issues/411 const s0 = { items: [1] } const [s1, p1] = produceWithPatches(s0, draft => { draft.items = [] }) const replaceValueBefore = p1[0].value.slice() const [s2, p2] = produceWithPatches(s1, draft => { draft.items.push(2) }) applyPatches(s0, [...p1, ...p2]) const replaceValueAfter = p1[0].value.slice() expect(replaceValueAfter).toStrictEqual(replaceValueBefore) }) }) // New macro-style test runPatchTests( "simple assignment - 1", {x: 3}, d => { d.x++ }, [{op: "replace", path: ["x"], value: 4}] ) // Original test (commented out for comparison) // describe("simple assignment - 1", () => { // runPatchTest( // {x: 3}, // d => { // d.x++ // }, // [{op: "replace", path: ["x"], value: 4}] // ) // }) // New macro-style tests runPatchTests( "simple assignment - 2", {x: {y: 4}}, d => { d.x.y++ }, [{op: "replace", path: ["x", "y"], value: 5}] ) runPatchTests( "simple assignment - 3", {x: [{y: 4}]}, d => { d.x[0].y++ }, [{op: "replace", path: ["x", 0, "y"], value: 5}] ) runPatchTests( "simple assignment - 4", new Map([["x", {y: 4}]]), d => { d.get("x").y++ }, [{op: "replace", path: ["x", "y"], value: 5}], [{op: "replace", path: ["x", "y"], value: 4}] ) runPatchTests( "simple assignment - 5", {x: new Map([["y", 4]])}, d => { d.x.set("y", 5) }, [{op: "replace", path: ["x", "y"], value: 5}], [{op: "replace", path: ["x", "y"], value: 4}] ) runPatchTests( "simple assignment - 6", new Map([["x", 1]]), d => { // Map.prototype.set should return the Map itself const res = d.set("x", 2) res.set("y", 3) }, [ {op: "replace", path: ["x"], value: 2}, {op: "add", path: ["y"], value: 3} ], [ {op: "replace", path: ["x"], value: 1}, {op: "remove", path: ["y"]} ] ) // Complex test with external variables - keep as individual describe describe("simple assignment - 7", () => { const key1 = {prop: "val1"} const key2 = {prop: "val2"} runPatchTests( "", {x: new Map([[key1, 4]])}, d => { d.x.set(key1, 5) d.x.set(key2, 6) }, [ {op: "replace", path: ["x", key1], value: 5}, {op: "add", path: ["x", key2], value: 6} ], [ {op: "replace", path: ["x", key1], value: 4}, {op: "remove", path: ["x", key2]} ] ) }) runPatchTests( "simple assignment - 8", new Map([[0, new Map([[1, 4]])]]), d => { d.get(0).set(1, 5) d.get(0).set(2, 6) }, [ {op: "replace", path: [0, 1], value: 5}, {op: "add", path: [0, 2], value: 6} ], [ {op: "replace", path: [0, 1], value: 4}, {op: "remove", path: [0, 2]} ] ) runPatchTests( "delete 1", {x: {y: 4}}, d => { delete d.x }, [{op: "remove", path: ["x"]}] ) runPatchTests( "delete 2", new Map([["x", 1]]), d => { d.delete("x") }, [{op: "remove", path: ["x"]}], [{op: "add", path: ["x"], value: 1}] ) runPatchTests( "delete 3", {x: new Map([["y", 1]])}, d => { d.x.delete("y") }, [{op: "remove", path: ["x", "y"]}], [{op: "add", path: ["x", "y"], value: 1}] ) describe("delete 5", () => { const key1 = {prop: "val1"} const key2 = {prop: "val2"} runPatchTests( "", { x: new Map([ [key1, 1], [key2, 2] ]) }, d => { d.x.delete(key1) d.x.delete(key2) }, [ {op: "remove", path: ["x", key1]}, {op: "remove", path: ["x", key2]} ], [ {op: "add", path: ["x", key1], value: 1}, {op: "add", path: ["x", key2], value: 2} ] ) }) runPatchTests( "delete 6", new Set(["x", 1]), d => { d.delete("x") }, [{op: "remove", path: [0], value: "x"}], [{op: "add", path: [0], value: "x"}] ) runPatchTests( "delete 7", {x: new Set(["y", 1])}, d => { d.x.delete("y") }, [{op: "remove", path: ["x", 0], value: "y"}], [{op: "add", path: ["x", 0], value: "y"}] ) describe("renaming properties", () => { runPatchTests( "nested object (no changes)", {a: {b: 1}}, d => { d.x = d.a delete d.a }, [ {op: "add", path: ["x"], value: {b: 1}}, {op: "remove", path: ["a"]} ] ) runPatchTests( "nested change in object", { a: {b: 1} }, d => { d.a.b++ }, [{op: "replace", path: ["a", "b"], value: 2}], [{op: "replace", path: ["a", "b"], value: 1}] ) runPatchTests( "nested change in map", new Map([["a", new Map([["b", 1]])]]), d => { d.get("a").set("b", 2) }, [{op: "replace", path: ["a", "b"], value: 2}], [{op: "replace", path: ["a", "b"], value: 1}] ) runPatchTests( "nested change in array", [[{b: 1}]], d => { d[0][0].b++ }, [{op: "replace", path: [0, 0, "b"], value: 2}], [{op: "replace", path: [0, 0, "b"], value: 1}] ) runPatchTests( "nested map (no changes)", new Map([["a", new Map([["b", 1]])]]), d => { d.set("x", d.get("a")) d.delete("a") }, [ {op: "add", path: ["x"], value: new Map([["b", 1]])}, {op: "remove", path: ["a"]} ], [ {op: "remove", path: ["x"]}, {op: "add", path: ["a"], value: new Map([["b", 1]])} ] ) runPatchTests( "nested object (with changes)", {a: {b: 1, c: 1}}, d => { let a = d.a a.b = 2 // change delete a.c // delete a.y = 2 // add // rename d.x = a delete d.a }, [ {op: "add", path: ["x"], value: {b: 2, y: 2}}, {op: "remove", path: ["a"]} ] ) runPatchTests( "nested map (with changes)", new Map([ [ "a", new Map([ ["b", 1], ["c", 1] ]) ] ]), d => { let a = d.get("a") a.set("b", 2) // change a.delete("c") // delete a.set("y", 2) // add // rename d.set("x", a) d.delete("a") }, [ { op: "add", path: ["x"], value: new Map([ ["b", 2], ["y", 2] ]) }, {op: "remove", path: ["a"]} ], [ {op: "remove", path: ["x"]}, { op: "add", path: ["a"], value: new Map([ ["b", 1], ["c", 1] ]) } ] ) runPatchTests( "deeply nested object (with changes)", {a: {b: {c: 1, d: 1}}}, d => { let b = d.a.b b.c = 2 // change delete b.d // delete b.y = 2 // add // rename d.a.x = b delete d.a.b }, [ {op: "add", path: ["a", "x"], value: {c: 2, y: 2}}, {op: "remove", path: ["a", "b"]} ] ) runPatchTests( "deeply nested map (with changes)", new Map([ [ "a", new Map([ [ "b", new Map([ ["c", 1], ["d", 1] ]) ] ]) ] ]), d => { let b = d.get("a").get("b") b.set("c", 2) // change b.delete("d") // delete b.set("y", 2) // add // rename d.get("a").set("x", b) d.get("a").delete("b") }, [ { op: "add", path: ["a", "x"], value: new Map([ ["c", 2], ["y", 2] ]) }, {op: "remove", path: ["a", "b"]} ], [ {op: "remove", path: ["a", "x"]}, { op: "add", path: ["a", "b"], value: new Map([ ["c", 1], ["d", 1] ]) } ] ) }) runPatchTests( "minimum amount of changes", {x: 3, y: {a: 4}, z: 3}, d => { d.y.a = 4 d.y.b = 5 Object.assign(d, {x: 4, y: {a: 2}}) }, [ {op: "replace", path: ["x"], value: 4}, {op: "replace", path: ["y"], value: {a: 2}} ] ) runPatchTests( "arrays - prepend", {x: [1, 2, 3]}, d => { d.x.unshift(4) }, [ {op: "replace", path: ["x", 0], value: 4}, {op: "replace", path: ["x", 1], value: 1}, {op: "replace", path: ["x", 2], value: 2}, {op: "add", path: ["x", 3], value: 3} ] ) runPatchTests( "arrays - multiple prepend", {x: [1, 2, 3]}, d => { d.x.unshift(4) d.x.unshift(5) // 4,5,1,2,3 }, [ {op: "replace", path: ["x", 0], value: 5}, {op: "replace", path: ["x", 1], value: 4}, {op: "replace", path: ["x", 2], value: 1}, {op: "add", path: ["x", 3], value: 2}, {op: "add", path: ["x", 4], value: 3} ] ) runPatchTests( "arrays - splice middle", {x: [1, 2, 3]}, d => { d.x.splice(1, 1) }, [ {op: "replace", path: ["x", 1], value: 3}, {op: "remove", path: ["x", 2]} ] ) runPatchTests( "arrays - multiple splice", [0, 1, 2, 3, 4, 5, 0], d => { d.splice(4, 2, 3) // [0,1,2,3,3,0] d.splice(1, 2, 3) // [0,3,3,3,0] expect(d.slice()).toEqual([0, 3, 3, 3, 0]) }, [ {op: "replace", path: [1], value: 3}, {op: "replace", path: [2], value: 3}, {op: "replace", path: [4], value: 0}, {op: "remove", path: [6]}, {op: "remove", path: [5]} ] ) runPatchTests( "arrays - modify and shrink", {x: [1, 2, 3]}, d => { d.x[0] = 4 d.x.length = 2 // [0, 2] }, [ {op: "replace", path: ["x", 0], value: 4}, {op: "remove", path: ["x", 2]} ], [ {op: "replace", path: ["x", 0], value: 1}, {op: "add", path: ["x", 2], value: 3} ] ) runPatchTests( "arrays - prepend then splice middle", {x: [1, 2, 3]}, d => { d.x.unshift(4) d.x.splice(2, 1) // 4, 1, 3 }, [ {op: "replace", path: ["x", 0], value: 4}, {op: "replace", path: ["x", 1], value: 1} ] ) runPatchTests( "arrays - splice middle then prepend", {x: [1, 2, 3]}, d => { d.x.splice(1, 1) d.x.unshift(4) // [4, 1, 3] }, [ {op: "replace", path: ["x", 0], value: 4}, {op: "replace", path: ["x", 1], value: 1} ] ) runPatchTests( "arrays - truncate", {x: [1, 2, 3]}, d => { d.x.length -= 2 }, [ {op: "remove", path: ["x", 2]}, {op: "remove", path: ["x", 1]} ], [ {op: "add", path: ["x", 1], value: 2}, {op: "add", path: ["x", 2], value: 3} ] ) runPatchTests( "arrays - pop twice", {x: [1, 2, 3]}, d => { d.x.pop() d.x.pop() }, [ {op: "remove", path: ["x", 2]}, {op: "remove", path: ["x", 1]} ] ) runPatchTests( "arrays - push multiple", {x: [1, 2, 3]}, d => { d.x.push(4, 5) }, [ {op: "add", path: ["x", 3], value: 4}, {op: "add", path: ["x", 4], value: 5} ], [ {op: "remove", path: ["x", 4]}, {op: "remove", path: ["x", 3]} ] ) runPatchTests( "arrays - splice (expand)", {x: [1, 2, 3]}, d => { d.x.splice(1, 1, 4, 5, 6) // [1,4,5,6,3] }, [ {op: "replace", path: ["x", 1], value: 4}, {op: "replace", path: ["x", 2], value: 5}, {op: "add", path: ["x", 3], value: 6}, {op: "add", path: ["x", 4], value: 3} ], [ {op: "replace", path: ["x", 1], value: 2}, {op: "replace", path: ["x", 2], value: 3}, {op: "remove", path: ["x", 4]}, {op: "remove", path: ["x", 3]} ] ) runPatchTests( "arrays - splice (shrink)", {x: [1, 2, 3, 4, 5]}, d => { d.x.splice(1, 3, 6) // [1, 6, 5] }, [ {op: "replace", path: ["x", 1], value: 6}, {op: "replace", path: ["x", 2], value: 5}, {op: "remove", path: ["x", 4]}, {op: "remove", path: ["x", 3]} ], [ {op: "replace", path: ["x", 1], value: 2}, {op: "replace", path: ["x", 2], value: 3}, {op: "add", path: ["x", 3], value: 4}, {op: "add", path: ["x", 4], value: 5} ] ) runPatchTests( "arrays - delete", { x: [ {a: 1, b: 2}, {c: 3, d: 4} ] }, d => { delete d.x[1].c }, [{op: "remove", path: ["x", 1, "c"]}] ) describe("arrays - append", () => { test("appends to array when last part of path is '-'", () => { const state = { list: [1, 2, 3] } const patch = { op: "add", value: 4, path: ["list", "-"] } expect(applyPatches(state, [patch])).toEqual({ list: [1, 2, 3, 4] }) }) }) runPatchTests( "sets - add - 1", new Set([1]), d => { d.add(2) }, [{op: "add", path: [1], value: 2}], [{op: "remove", path: [1], value: 2}] ) runPatchTests( "sets - add, delete, add - 1", new Set([1]), d => { d.add(2) d.delete(2) d.add(2) }, [{op: "add", path: [1], value: 2}], [{op: "remove", path: [1], value: 2}] ) runPatchTests( "sets - add, delete, add - 2", new Set([2, 1]), d => { d.add(2) d.delete(2) d.add(2) }, [], [] ) describe("sets - mutate - 1", () => { const findById = (set, id) => { for (const item of set) { if (item.id === id) return item } } runPatchTests( "", new Set([ {id: 1, val: "We"}, {id: 2, val: "will"} ]), d => { const obj1 = findById(d, 1) const obj2 = findById(d, 2) obj1.val = "rock" obj2.val = "you" }, [ {op: "remove", path: [0], value: {id: 1, val: "We"}}, {op: "remove", path: [1], value: {id: 2, val: "will"}}, {op: "add", path: [0], value: {id: 1, val: "rock"}}, {op: "add", path: [1], value: {id: 2, val: "you"}} ], [ {op: "remove", path: [1], value: {id: 2, val: "you"}}, {op: "remove", path: [0], value: {id: 1, val: "rock"}}, {op: "add", path: [1], value: {id: 2, val: "will"}}, {op: "add", path: [0], value: {id: 1, val: "We"}} ] ) }) // These patches were more optimal pre immer 7, but not always correct runPatchTests( "arrays - splice should should result in remove op.", [1, 2], d => { d.splice(1, 1) }, [{op: "remove", path: [1]}], [{op: "add", path: [1], value: 2}] ) // These patches were more optimal pre immer 7, but not always correct runPatchTests( "arrays - NESTED splice should should result in remove op.", {a: {b: {c: [1, 2]}}}, d => { d.a.b.c.splice(1, 1) }, [{op: "remove", path: ["a", "b", "c", 1]}], [{op: "add", path: ["a", "b", "c", 1], value: 2}] ) runPatchTests("simple replacement", {x: 3}, _d => 4, [ {op: "replace", path: [], value: 4} ]) runPatchTests( "same value replacement - 1", {x: {y: 3}}, d => { const a = d.x d.x = a }, [] ) runPatchTests( "same value replacement - 2", {x: {y: 3}}, d => { const a = d.x d.x = 4 d.x = a }, [] ) runPatchTests( "same value replacement - 3", {x: 3}, d => { d.x = 3 }, [] ) runPatchTests( "same value replacement - 4", {x: 3}, d => { d.x = 4 d.x = 3 }, [] ) runPatchTests( "same value replacement - 5", new Map([["x", 3]]), d => { d.set("x", 4) d.set("x", 3) }, [], [] ) runPatchTests( "same value replacement - 6", new Set(["x", 3]), d => { d.delete("x") d.add("x") }, [], [] ) runPatchTests( "simple delete", {x: 2}, d => { delete d.x }, [ { op: "remove", path: ["x"] } ] ) describe("patch compressions yields correct results", () => { let p1 = [ { op: "add", path: ["x"], value: { test: true } } ] let p2 = [ { op: "remove", path: ["x"] } ] runPatchTests( "add only", {}, d => { d.x = {test: true} }, p1 ) runPatchTests( "delete only", {x: {test: true}}, d => { delete d.x }, p2 ) const testData = runPatchTests( "add and delete together cancel", {}, d => { applyPatches(d, [...p1, ...p2]) }, [] ) expect(testData.result).toEqual({}) }) runPatchTests( "change then delete property", { x: 1 }, d => { d.x = 2 delete d.x }, [ { op: "remove", path: ["x"] } ] ) test("replaying patches with interweaved replacements should work correctly", () => { const patches = [] const s0 = {x: 1} const s1 = produce( s0, draft => { draft.x = 2 }, p => { patches.push(...p) } ) const s2 = produce( s1, draft => { return {x: 0} }, p => { patches.push(...p) } ) const s3 = produce( s2, draft => { draft.x-- }, p => { patches.push(...p) } ) expect(s3).toEqual({x: -1}) // correct result expect(applyPatches(s0, patches)).toEqual({x: -1}) // correct replay // manual replay on a draft should also be correct expect( produce(s0, draft => { return applyPatches(draft, patches) }) ).toEqual({x: -1}) }) describe("#468", () => { function run() { const item = {id: 1} const state = [item] const [nextState, patches] = produceWithPatches(state, draft => { draft[0].id = 2 draft[1] = item }) expect(nextState).toEqual([{id: 2}, {id: 1}]) expect(patches).toEqual([ { op: "replace", path: [0, "id"], value: 2 }, { op: "add", path: [1], value: { id: 1 } } ]) const final = applyPatches(state, patches) expect(final).toEqual(nextState) } test("proxy", () => { run() }) }) test("#521", () => { const state = new Map() const [nextState, patches] = produceWithPatches(state, draft => { draft.set("hello", new Set(["world"])) }) let patchedState = applyPatches(state, patches) expect(patchedState).toEqual(nextState) const [nextStateV2, patchesV2] = produceWithPatches(nextState, draft => { draft.get("hello").add("immer") }) expect(applyPatches(nextState, patchesV2)).toEqual( new Map([["hello", new Set(["world", "immer"])]]) ) }) test("#559 patches works in a nested reducer with proxies", () => { const state = { x: 1, sub: { y: [{a: 0}, {a: 1}] } } const changes = [] const inverseChanges = [] const newState = produce(state, draft => { draft.sub = produce( draft.sub, draft => { draft.y.pop() }, (patches, inversePatches) => { expect(isDraft(inversePatches[0].value)).toBeFalsy() expect(inversePatches[0].value).toMatchObject({a: 1}) changes.push(...patches) inverseChanges.push(...inversePatches) } ) }) const reversedSubState = applyPatches(newState.sub, inverseChanges) expect(reversedSubState).toMatchObject(state.sub) }) describe("#588", () => { const reference = {value: {num: 53}} class Base { [immerable] = true get nested() { return reference.value } set nested(value) {} } let base = new Base() runPatchTests( "", base, vdraft => { reference.value = vdraft produce(base, bdraft => { bdraft.nested.num = 42 }) }, [{op: "add", path: ["num"], value: 42}] ) }) test("#676 patching Date objects", () => { class Test { constructor() { this.test = true } perform() { return "tested!" } } const [nextState, patches] = produceWithPatches({}, function(draft) { draft.date = new Date("2020-11-10T08:08:08.003Z") draft.test = new Test() }) expect(nextState.date.toJSON()).toMatchInlineSnapshot( `"2020-11-10T08:08:08.003Z"` ) expect(nextState.test.perform()).toBe("tested!") const rebuilt = applyPatches({}, patches) expect(rebuilt.date).toBeInstanceOf(Date) expect(rebuilt.date.toJSON()).toMatchInlineSnapshot( `"2020-11-10T08:08:08.003Z"` ) expect(rebuilt.date).toEqual(new Date("2020-11-10T08:08:08.003Z")) }) test("do not allow __proto__ polution - 738", () => { const obj = {} // @ts-ignore expect(obj.polluted).toBe(undefined) expect(() => { applyPatches({}, [ {op: "add", path: ["__proto__", "polluted"], value: "yes"} ]) }).toThrow( isProd ? "19" : "Patching reserved attributes like __proto__, prototype and constructor is not allowed" ) // @ts-ignore expect(obj.polluted).toBe(undefined) }) test("do not allow __proto__ polution using arrays - 738", () => { const obj = {} const ar = [] // @ts-ignore expect(obj.polluted).toBe(undefined) // @ts-ignore expect(ar.polluted).toBe(undefined) expect(() => { applyPatches( [], [{op: "add", path: ["__proto__", "polluted"], value: "yes"}] ) }).toThrow( isProd ? "19" : "Patching reserved attributes like __proto__, prototype and constructor is not allowed" ) // @ts-ignore expect(obj.polluted).toBe(undefined) // @ts-ignore expect(ar.polluted).toBe(undefined) }) test("do not allow prototype polution - 738", () => { const obj = {} // @ts-ignore expect(obj.polluted).toBe(undefined) expect(() => { applyPatches(Object, [ {op: "add", path: ["prototype", "polluted"], value: "yes"} ]) }).toThrow( isProd ? "19" : "Patching reserved attributes like __proto__, prototype and constructor is not allowed" ) // @ts-ignore expect(obj.polluted).toBe(undefined) }) test("do not allow constructor polution - 738", () => { const obj = {} // @ts-ignore expect(obj.polluted).toBe(undefined) const t = {} applyPatches(t, [{op: "replace", path: ["constructor"], value: "yes"}]) expect(typeof t.constructor).toBe("function") // @ts-ignore expect(Object.polluted).toBe(undefined) }) test("do not allow constructor.prototype polution - 738", () => { const obj = {} // @ts-ignore expect(obj.polluted).toBe(undefined) expect(() => { applyPatches({}, [ {op: "add", path: ["constructor", "prototype", "polluted"], value: "yes"} ]) }).toThrow( isProd ? "19" : "Patching reserved attributes like __proto__, prototype and constructor is not allowed" ) // @ts-ignore expect(Object.polluted).toBe(undefined) }) test("maps can store __proto__, prototype and constructor props", () => { const obj = {} const map = new Map() map.set("__proto__", {}) map.set("constructor", {}) map.set("prototype", {}) const newMap = applyPatches(map, [ {op: "add", path: ["__proto__", "polluted"], value: "yes"}, {op: "add", path: ["constructor", "polluted"], value: "yes"}, {op: "add", path: ["prototype", "polluted"], value: "yes"} ]) expect(newMap.get("__proto__").polluted).toBe("yes") expect(newMap.get("constructor").polluted).toBe("yes") expect(newMap.get("prototype").polluted).toBe("yes") expect(obj.polluted).toBe(undefined) }) test("CVE-2020-28477 (https://snyk.io/vuln/SNYK-JS-IMMER-1019369) follow up", () => { const obj = {} // @ts-ignore expect(obj.polluted).toBe(undefined) expect(() => { applyPatches({}, [ {op: "add", path: [["__proto__"], "polluted"], value: "yes"} ]) }).toThrow( isProd ? "19" : "Patching reserved attributes like __proto__, prototype and constructor is not allowed" ) // @ts-ignore expect(obj.polluted).toBe(undefined) }) test("#648 assigning object to itself should not change patches", () => { const input = { obj: { value: 200 } } const [nextState, patches] = produceWithPatches(input, draft => { draft.obj.value = 1 draft.obj = draft.obj }) expect(patches).toEqual([ { op: "replace", path: ["obj", "value"], value: 1 } ]) }) test("#791 patch for nothing is stored as undefined", () => { const [newState, patches] = produceWithPatches({abc: 123}, draft => nothing) expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) expect(applyPatches({}, patches)).toEqual(undefined) }) test("#876 Ensure empty patch set for atomic set+delete on Map", () => { { const [newState, patches] = produceWithPatches( new Map([["foo", "baz"]]), draft => { draft.set("foo", "bar") draft.delete("foo") } ) expect(patches).toEqual([{op: "remove", path: ["foo"]}]) } { const [newState, patches] = produceWithPatches(new Map(), draft => { draft.set("foo", "bar") draft.delete("foo") }) expect(patches).toEqual([]) } }) test("#888 patch to a primitive produces the primitive", () => { { const [res, patches] = produceWithPatches({abc: 123}, draft => nothing) expect(res).toEqual(undefined) expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) } { const [res, patches] = produceWithPatches(null, draft => nothing) expect(res).toEqual(undefined) expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) } { const [res, patches] = produceWithPatches(0, draft => nothing) expect(res).toEqual(undefined) expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) } { const [res, patches] = produceWithPatches("foobar", draft => nothing) expect(res).toEqual(undefined) expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) } { const [res, patches] = produceWithPatches([], draft => nothing) expect(res).toEqual(undefined) expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) } { const [res, patches] = produceWithPatches(false, draft => nothing) expect(res).toEqual(undefined) expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) } { const [res, patches] = produceWithPatches( "foobar", draft => "something else" ) expect(res).toEqual("something else") expect(patches).toEqual([ {op: "replace", path: [], value: "something else"} ]) } { const [res, patches] = produceWithPatches(false, draft => true) expect(res).toEqual(true) expect(patches).toEqual([{op: "replace", path: [], value: true}]) } }) runPatchTests( "#879 delete item from array", [1, 2, 3], draft => { delete draft[1] }, [{op: "replace", path: [1], value: undefined}], [{op: "replace", path: [1], value: 2}], [1, undefined, 3] ) runPatchTests( "#879 delete item from array - 2", [1, 2, 3], draft => { delete draft[2] }, [{op: "replace", path: [2], value: undefined}], [{op: "replace", path: [2], value: 3}], [1, 2, undefined] ) test("#897 appendPatch", () => { const state0 = {a: []} const state1 = applyPatches(state0, [{op: "add", path: ["a", "-"], value: 1}]) const state2 = applyPatches(state1, [{op: "add", path: ["a", "-"], value: 2}]) const state3 = applyPatches(state2, [{op: "add", path: ["a", "-"], value: 3}]) expect(state3).toEqual({ a: [1, 2, 3] }) }) // Bug reproduction: Patch path truncation in production build // This bug is caused by the "key_" in state check failing after minification // The patch path should include the full path for nested array modifications describe("RTK-5159: Patch path truncation bug", () => { test("patch paths should include full path for nested array modifications", () => { const baseState = { lists: [{items: [{id: 1}]}] } const [result, patches] = produceWithPatches(baseState, draft => { draft.lists[0].items.push({id: 2}) }) // The patch path should be ["lists", 0, "items", 1], not just [1] expect(patches[0].path).toEqual(["lists", 0, "items", 1]) expect(patches).toEqual([ {op: "add", path: ["lists", 0, "items", 1], value: {id: 2}} ]) }) test("patch paths correct for deeply nested object in array", () => { const baseState = { queries: { queryKey: { data: { items: [{name: "item1"}] } } } } const [result, patches] = produceWithPatches(baseState, draft => { draft.queries.queryKey.data.items.push({name: "item2"}) }) expect(patches[0].path).toEqual(["queries", "queryKey", "data", "items", 1]) }) }) ================================================ FILE: __tests__/plugins.js ================================================ import {produce, produceWithPatches, applyPatches} from "../src/immer" test("error when using Maps", () => { expect(() => { produce(new Map(), function() {}) }).toThrowErrorMatchingSnapshot() }) test("error when using patches - 1", () => { expect(() => { produce( {}, function() {}, function() {} ) }).toThrowErrorMatchingSnapshot() }) test("error when using patches - 2", () => { expect(() => { produceWithPatches({}, function() {}) }).toThrowErrorMatchingSnapshot() }) test("error when using patches - 3", () => { expect(() => { applyPatches({}, []) }).toThrowErrorMatchingSnapshot() }) ================================================ FILE: __tests__/produce.ts ================================================ import {assert, _} from "./spec_ts" import { produce, applyPatches, Patch, nothing, Draft, Immutable, Immer, enableMapSet, enablePatches, produceWithPatches } from "../src/immer" enableMapSet() enablePatches() interface State { readonly num: number readonly foo?: string bar: string readonly baz: { readonly x: number readonly y: number } readonly arr: ReadonlyArray<{readonly value: string}> readonly arr2: {readonly value: string}[] } const state: State = { num: 0, bar: "foo", baz: { x: 1, y: 2 }, arr: [{value: "asdf"}], arr2: [{value: "asdf"}] } const expectedState: State = { num: 1, foo: "bar", bar: "foo", baz: { x: 2, y: 3 }, arr: [{value: "foo"}, {value: "asf"}], arr2: [{value: "foo"}, {value: "asf"}] } it("can update readonly state via standard api", () => { const newState = produce(state, draft => { draft.num++ draft.foo = "bar" draft.bar = "foo" draft.baz.x++ draft.baz.y++ draft.arr[0].value = "foo" draft.arr.push({value: "asf"}) draft.arr2[0].value = "foo" draft.arr2.push({value: "asf"}) }) assert(newState, _ as State) }) // NOTE: only when the function type is inferred it("can infer state type from default state", () => { type State = {readonly a: number} type Recipe = (state?: State | undefined) => State let foo = produce((_: any) => {}, _ as State) assert(foo, _ as Recipe) }) it("can infer state type from recipe function", () => { type A = {readonly a: string} type B = {readonly b: string} type State = A | B type Recipe = (state: State) => State let foo = produce((draft: State) => { assert(draft, _ as State) if (Math.random() > 0.5) return {a: "test"} else return {b: "boe"} }) const x = foo({a: ""}) const y = foo({b: ""}) assert(foo, _ as Recipe) }) it("can infer state type from recipe function with arguments", () => { type State = {readonly a: string} | {readonly b: string} type Recipe = (state: State, x: number) => State let foo = produce((draft, x) => { assert(draft, _ as Draft) assert(x, _ as number) }) assert(foo, _ as Recipe) }) it("can infer state type from recipe function with arguments and initial state", () => { type State = {readonly a: string} | {readonly b: string} type Recipe = (state: State | undefined, x: number) => State let foo = produce((draft: Draft, x: number) => {}, _ as State) assert(foo, _ as Recipe) }) it("cannot infer state type when the function type and default state are missing", () => { type Recipe = (state: S) => S const foo = produce((_: any) => {}) // @ts-expect-error assert(foo, _ as Recipe) }) it("can update readonly state via curried api", () => { const newState = produce((draft: Draft) => { draft.num++ draft.foo = "bar" draft.bar = "foo" draft.baz.x++ draft.baz.y++ draft.arr[0].value = "foo" draft.arr.push({value: "asf"}) draft.arr2[0].value = "foo" draft.arr2.push({value: "asf"}) })(state) expect(newState).not.toBe(state) expect(newState).toEqual(expectedState) }) it("can update use the non-default export", () => { const newState = produce((draft: Draft) => { draft.num++ draft.foo = "bar" draft.bar = "foo" draft.baz.x++ draft.baz.y++ draft.arr[0].value = "foo" draft.arr.push({value: "asf"}) draft.arr2[0].value = "foo" draft.arr2.push({value: "asf"}) })(state) expect(newState).not.toBe(state) expect(newState).toEqual(expectedState) }) it("can apply patches", () => { let patches: Patch[] = [] produce( {x: 3}, d => { d.x++ }, p => { patches = p } ) expect(applyPatches({}, patches)).toEqual({x: 4}) }) it("can apply readonly patches", () => { const [, patches]: readonly [ { x: number }, readonly Patch[], readonly Patch[] ] = produceWithPatches({x: 3}, d => { d.x++ }) expect(applyPatches({}, patches)).toEqual({x: 4}) }) describe("curried producer", () => { it("supports rest parameters", () => { type State = {readonly a: 1} // No initial state: { type Recipe = (state: State, a: number, b: number) => State let foo = produce((s: State, a: number, b: number) => {}) assert(foo, _ as Recipe) foo(_ as State, 1, 2) } // Using argument parameters: { type Recipe = (state: Immutable, ...rest: number[]) => Draft let woo = produce((state: Draft, ...args: number[]) => {}) assert(woo, _ as Recipe) woo(_ as State, 1, 2) } // With initial state: { type Recipe = (state?: State | undefined, ...rest: number[]) => State let bar = produce((state: Draft, ...args: number[]) => {}, _ as State) assert(bar, _ as Recipe) bar(_ as State, 1, 2) bar(_ as State) bar() } // When args is a tuple: { type Recipe = ( state: State | undefined, first: string, ...rest: number[] ) => State let tup = produce( (state: Draft, ...args: [string, ...number[]]) => {}, _ as State ) assert(tup, _ as Recipe) tup({a: 1}, "", 2) tup(undefined, "", 2) } }) it("can be passed a readonly array", () => { // No initial state: { let foo = produce((state: string[]) => {}) assert(foo, _ as (state: readonly string[]) => string[]) foo([] as ReadonlyArray) } // With initial state: { let bar = produce(() => {}, [] as ReadonlyArray) assert( bar, _ as (state?: readonly string[] | undefined) => readonly string[] ) bar([] as ReadonlyArray) bar(undefined) bar() } }) }) it("works with return type of: number", () => { let base = {a: 0} as {a: number} { if (Math.random() === 100) { // @ts-expect-error, this return accidentally a number, this is probably a dev error! let result = produce(base, draft => draft.a++) } } { let result = produce(base, draft => void draft.a++) assert(result, _ as {a: number}) } }) it("can return an object type that is identical to the base type", () => { let base = {a: 0} as {a: number} let result = produce(base, draft => { return draft.a < 0 ? {a: 0} : undefined }) assert(result, _ as {a: number}) }) it("can NOT return an object type that is _not_ assignable to the base type", () => { let base = {a: 0} as {a: number} // @ts-expect-error let result = produce(base, draft => { return draft.a < 0 ? {a: true} : undefined }) }) it("does not enforce immutability at the type level", () => { let result = produce([] as any[], draft => { draft.push(1) }) assert(result, _ as any[]) }) it("can produce an undefined value", () => { type State = {readonly a: number} | undefined const base = {a: 0} as State // Return only nothing. let result = produce(base, _ => nothing) assert(result, _ as State) // Return maybe nothing. let result2 = produce(base, draft => { if (draft?.a ?? 0 > 0) return nothing }) assert(result2, _ as State) }) it("can return the draft itself", () => { let base = _ as {readonly a: number} let result = produce(base, draft => draft) assert(result, _ as {readonly a: number}) }) it("works with `void` hack", () => { let base = {a: 0} as {readonly a: number} let copy = produce(base, s => void s.a++) assert(copy, base) }) it("works with generic parameters", () => { let insert = (array: readonly T[], index: number, elem: T) => { // Need explicit cast on draft as T[] is wider than readonly T[] return produce(array, (draft: T[]) => { draft.push(elem) draft.splice(index, 0, elem) draft.concat([elem]) }) } let val: {readonly a: ReadonlyArray} = {a: []} as any let arr: ReadonlyArray = [] as any insert(arr, 0, val) }) it("can work with non-readonly base types", () => { const state = { price: 10, todos: [ { title: "test", done: false } ] } type State = typeof state const newState = produce(state, draft => { draft.price += 5 draft.todos.push({ title: "hi", done: true }) }) assert(newState, _ as State) const reducer = (draft: State) => { draft.price += 5 draft.todos.push({ title: "hi", done: true }) } // base case for with-initial-state const newState4 = produce(reducer, state)(state) assert(newState4, _ as State) // no argument case, in that case, immutable version recipe first arg will be inferred const newState5 = produce(reducer, state)() assert(newState5, _ as State) // we can force the return type of the reducer by casting the initial state const newState3 = produce(reducer, state as State)() assert(newState3, _ as State) }) it("can work with readonly base types", () => { type State = { readonly price: number readonly todos: readonly { readonly title: string readonly done: boolean }[] } const state: State = { price: 10, todos: [ { title: "test", done: false } ] } const newState = produce(state, draft => { draft.price + 5 draft.todos.push({ title: "hi", done: true }) }) assert(newState, _ as State) assert(newState, _ as Immutable) // cause that is the same! const reducer = (draft: Draft) => { draft.price += 5 draft.todos.push({ title: "hi", done: true }) } const newState2: State = produce(reducer)(state) assert(newState2, _ as State) // base case for with-initial-state const newState4 = produce(reducer, state)(state) assert(newState4, _ as State) // no argument case, in that case, immutable version recipe first arg will be inferred const newState5 = produce(reducer, state)() assert(newState5, _ as State) // we can force the return type of the reducer by casting initial argument const newState3 = produce(reducer, state as State)() assert(newState3, _ as State) }) it("works with generic array", () => { const append = (queue: T[], item: T) => // T[] is needed here v. Too bad. produce(queue, (queueDraft: T[]) => { queueDraft.push(item) }) const queueBefore = [1, 2, 3] const queueAfter = append(queueBefore, 4) expect(queueAfter).toEqual([1, 2, 3, 4]) expect(queueBefore).toEqual([1, 2, 3]) }) it("works with Map and Set", () => { const m = new Map([["a", {x: 1}]]) const s = new Set([{x: 2}]) const res1 = produce(m, draft => { assert(draft, _ as Map) }) assert(res1, _ as Map) const res2 = produce(s, draft => { assert(draft, _ as Set<{x: number}>) }) assert(res2, _ as Set<{x: number}>) }) it("works with readonly Map and Set", () => { type S = {readonly x: number} const m: ReadonlyMap = new Map([["a", {x: 1}]]) const s: ReadonlySet = new Set([{x: 2}]) const res1 = produce(m, (draft: Draft>) => { assert(draft, _ as Map) }) assert(res1, _ as ReadonlyMap) const res2 = produce(s, (draft: Draft>) => { assert(draft, _ as Set<{x: number}>) }) assert(res2, _ as ReadonlySet<{readonly x: number}>) }) it("works with ReadonlyMap and ReadonlySet", () => { type S = {readonly x: number} const m: ReadonlyMap = new Map([["a", {x: 1}]]) const s: ReadonlySet = new Set([{x: 2}]) const res1 = produce(m, (draft: Draft>) => { assert(draft, _ as Map) }) assert(res1, _ as ReadonlyMap) const res2 = produce(s, (draft: Draft>) => { assert(draft, _ as Set<{x: number}>) }) assert(res2, _ as ReadonlySet<{readonly x: number}>) }) it("shows error in production if called incorrectly", () => { expect(() => { debugger produce(null as any) }).toThrow( (global as any).USES_BUILD ? "[Immer] minified error nr: 6" : "[Immer] The first or second argument to `produce` must be a function" ) }) it("#749 types Immer", () => { const t = { x: 3 } const immer = new Immer() const z = immer.produce(t, d => { d.x++ // @ts-expect-error d.y = 0 }) expect(z.x).toBe(4) // @ts-expect-error expect(z.z).toBeUndefined() }) it("infers draft, #720", () => { function nextNumberCalculator(fn: (base: number) => number) { // noop } const res2 = nextNumberCalculator( produce(draft => { // @ts-expect-error let x: string = draft return draft + 1 }) ) const res = nextNumberCalculator( produce(draft => { // @ts-expect-error let x: string = draft // return draft + 1; return undefined }) ) }) it("infers draft, #720 - 2", () => { function useState( initialState: S | (() => S) ): [S, Dispatch>] { return [initialState, function() {}] as any } type Dispatch = (value: A) => void type SetStateAction = S | ((prevState: S) => S) const [n, setN] = useState({x: 3}) setN( produce(draft => { // @ts-expect-error draft.y = 4 draft.x = 5 return draft }) ) setN( produce(draft => { // @ts-expect-error draft.y = 4 draft.x = 5 // return draft + 1; return undefined }) ) setN( produce(draft => { return {y: 3} as const }) ) }) it("infers draft, #720 - 3", () => { function useState( initialState: S | (() => S) ): [S, Dispatch>] { return [initialState, function() {}] as any } type Dispatch = (value: A) => void type SetStateAction = S | ((prevState: S) => S) const [n, setN] = useState({x: 3} as {readonly x: number}) setN( produce(draft => { // @ts-expect-error draft.y = 4 draft.x = 5 return draft }) ) setN( produce(draft => { // @ts-expect-error draft.y = 4 draft.x = 5 // return draft + 1; return undefined }) ) setN( produce(draft => { return {y: 3} as const }) ) }) it("infers curried", () => { type Todo = {title: string} { const fn = produce((draft: Todo) => { let x: string = draft.title }) fn({title: "test"}) // @ts-expect-error fn(3) } { const fn = produce((draft: Todo) => { let x: string = draft.title return draft }) fn({title: "test"}) // @ts-expect-error fn(3) } }) { type State = {count: number} type ROState = Immutable const base: any = {count: 0} { // basic const res = produce(base as State, draft => { draft.count++ }) assert(res, _ as State) } { // basic const res = produce(base, draft => { draft.count++ }) assert(res, _ as State) } { // basic const res = produce(base as ROState, draft => { draft.count++ }) assert(res, _ as ROState) } { // curried const f = produce((state: State) => { state.count++ }) assert(f, _ as (state: Immutable) => State) } { // curried const f = produce((state: Draft) => { state.count++ }) assert(f, _ as (state: ROState) => State) } { // curried const f: (value: State) => State = produce(state => { state.count++ }) } { // curried const f: (value: ROState) => ROState = produce(state => { state.count++ }) } { // curried initial const f = produce(state => { state.count++ }, _ as State) assert(f, _ as (state?: State) => State) } { // curried initial const f = produce(state => { state.count++ }, _ as ROState) assert(f, _ as (state?: ROState) => ROState) } { // curried const f: (value: State) => State = produce(state => { state.count++ }, base as ROState) } { // curried const f: (value: ROState) => ROState = produce(state => { state.count++ }, base as ROState) } { // nothing allowed const res = produce(base as State | undefined, draft => { return nothing }) assert(res, _ as State | undefined) } { // as any const res = produce(base as State, draft => { return nothing as any }) assert(res, _ as State) } { // nothing not allowed // @ts-expect-error produce(base as State, draft => { return nothing }) } { const f = produce((draft: State) => {}) const n = f(base as State) assert(n, _ as State) } { const f = produce((draft: Draft) => { draft.count++ }) const n = f(base as ROState) assert(n, _ as State) } { // explicitly use generic const f = produce(draft => { draft.count++ }) const n = f(base as ROState) assert(n, _ as ROState) // yay! } } it("allows for mixed property value types", () => { type TestReadonlyObject = { readonly testObjectOrNull: {readonly testProperty: number} | null } const input: TestReadonlyObject = {testObjectOrNull: null} produce(input, draft => { if (draft.testObjectOrNull) { draft.testObjectOrNull.testProperty = 5 } }) }) ================================================ FILE: __tests__/readme.js ================================================ "use strict" import { produce, applyPatches, immerable, produceWithPatches, enableMapSet, enablePatches, setAutoFreeze } from "../src/immer" enableMapSet() enablePatches() describe("readme example", () => { it("works", () => { const baseState = [ { todo: "Learn typescript", done: true }, { todo: "Try immer", done: false } ] const nextState = produce(baseState, draft => { draft.push({todo: "Tweet about it"}) draft[1].done = true }) // the new item is only added to the next state, // base state is unmodified expect(baseState.length).toBe(2) expect(nextState.length).toBe(3) // same for the changed 'done' prop expect(baseState[1].done).toBe(false) expect(nextState[1].done).toBe(true) // unchanged data is structurally shared expect(nextState[0]).toBe(baseState[0]) // changed data not (dûh) expect(nextState[1]).not.toBe(baseState[1]) }) it("patches", () => { let state = { name: "Micheal", age: 32 } // Let's assume the user is in a wizard, and we don't know whether // his changes should be updated let fork = state // all the changes the user made in the wizard let changes = [] // all the inverse patches let inverseChanges = [] fork = produce( fork, draft => { draft.age = 33 }, // The third argument to produce is a callback to which the patches will be fed (patches, inversePatches) => { changes.push(...patches) inverseChanges.push(...inversePatches) } ) // In the mean time, our original state is updated as well, as changes come in from the server state = produce(state, draft => { draft.name = "Michel" }) // When the wizard finishes (successfully) we can replay the changes made in the fork onto the *new* state! state = applyPatches(state, changes) // state now contains the changes from both code paths! expect(state).toEqual({ name: "Michel", age: 33 }) // Even after finishing the wizard, the user might change his mind... state = applyPatches(state, inverseChanges) expect(state).toEqual({ name: "Michel", age: 32 }) }) it("can update set", () => { const state = { title: "hello", tokenSet: new Set() } const nextState = produce(state, draft => { draft.title = draft.title.toUpperCase() draft.tokenSet.add("c1342") }) expect(state).toEqual({title: "hello", tokenSet: new Set()}) expect(nextState).toEqual({ title: "HELLO", tokenSet: new Set(["c1342"]) }) }) it("can deep update map", () => { const state = { users: new Map([["michel", {name: "miche", age: 27}]]) } const nextState = produce(state, draft => { draft.users.get("michel").name = "michel" }) expect(state).toEqual({ users: new Map([["michel", {name: "miche", age: 27}]]) }) expect(nextState).toEqual({ users: new Map([["michel", {name: "michel", age: 27}]]) }) }) it("supports immerable", () => { class Clock { constructor(hours = 0, minutes = 0) { this.hours = hours this.minutes = minutes } increment(hours, minutes = 0) { return produce(this, d => { d.hours += hours d.minutes += minutes }) } toString() { return `${("" + this.hours).padStart(2, 0)}:${( "" + this.minutes ).padStart(2, 0)}` } } Clock[immerable] = true const midnight = new Clock() const lunch = midnight.increment(12, 30) expect(midnight).not.toBe(lunch) expect(lunch).toBeInstanceOf(Clock) expect(midnight.toString()).toBe("00:00") expect(lunch.toString()).toBe("12:30") const diner = lunch.increment(6) expect(diner).not.toBe(lunch) expect(lunch).toBeInstanceOf(Clock) expect(diner.toString()).toBe("18:30") }) test("produceWithPatches", () => { const result = produceWithPatches( { age: 33 }, draft => { draft.age++ } ) expect(result).toEqual([ { age: 34 }, [ { op: "replace", path: ["age"], value: 34 } ], [ { op: "replace", path: ["age"], value: 33 } ] ]) }) }) test("Producers can update Maps", () => { setAutoFreeze(true) const usersById_v1 = new Map() const usersById_v2 = produce(usersById_v1, draft => { // Modifying a map results in a new map draft.set("michel", {name: "Michel Weststrate", country: "NL"}) }) const usersById_v3 = produce(usersById_v2, draft => { // Making a change deep inside a map, results in a new map as well! draft.get("michel").country = "UK" debugger }) // We got a new map each time! expect(usersById_v2).not.toBe(usersById_v1) expect(usersById_v3).not.toBe(usersById_v2) // With different content obviously expect(usersById_v1).toMatchInlineSnapshot(`Map {}`) expect(usersById_v2).toMatchInlineSnapshot(` Map { "michel" => { "country": "NL", "name": "Michel Weststrate", }, } `) expect(usersById_v3).toMatchInlineSnapshot(` Map { "michel" => { "country": "UK", "name": "Michel Weststrate", }, } `) // The old one was never modified expect(usersById_v1.size).toBe(0) // And trying to change a Map outside a producers is going to: NO! expect(() => usersById_v3.clear()).toThrowErrorMatchingSnapshot() }) test("clock class", () => { class Clock { [immerable] = true constructor(hour, minute) { this.hour = hour this.minute = minute } get time() { return `${this.hour}:${this.minute}` } tick() { return produce(this, draft => { draft.minute++ }) } } const clock1 = new Clock(12, 10) const clock2 = clock1.tick() expect(clock1.time).toEqual("12:10") // 12:10 expect(clock2.time).toEqual("12:11") // 12:11 expect(clock2).toBeInstanceOf(Clock) }) ================================================ FILE: __tests__/redux.ts ================================================ import {assert, _} from "./spec_ts" import {produce, Draft} from "../src/immer" import * as redux from "redux" // Mutable Redux { interface State { counter: number } interface Action { type: string payload: number } const initialState: State = { counter: 0 } /// =============== Actions const reduceCounterProducer = (state: State = initialState, action: Action) => produce(state, draftState => { switch (action.type) { case "ADD_TO_COUNTER": draftState.counter += action.payload break case "SUB_FROM_COUNTER": draftState.counter -= action.payload break } }) const reduceCounterCurriedProducer = produce( (draftState: State, action: Action) => { switch (action.type) { case "ADD_TO_COUNTER": draftState.counter += action.payload break case "SUB_FROM_COUNTER": draftState.counter -= action.payload break } }, initialState ) /// =============== Reducers const reduce = redux.combineReducers({ counterReducer: reduceCounterProducer }) const curredReduce = redux.combineReducers({ counterReducer: reduceCounterCurriedProducer }) // reducing the current state to get the next state! // console.log(reduce(initialState, addToCounter(12)); // ================ store const store = redux.createStore(reduce) const curriedStore = redux.createStore(curredReduce) it("#470 works with Redux combine reducers", () => { assert( store.getState().counterReducer, _ as { counter: number } ) assert( curriedStore.getState().counterReducer, _ as { counter: number } ) }) } // Readonly Redux { { interface State { readonly counter: number } interface Action { readonly type: string readonly payload: number } const initialState: State = { counter: 0 } /// =============== Actions const reduceCounterProducer = ( state: State = initialState, action: Action ) => produce(state, draftState => { switch (action.type) { case "ADD_TO_COUNTER": draftState.counter += action.payload break case "SUB_FROM_COUNTER": draftState.counter -= action.payload break } }) const reduceCounterCurriedProducer = produce( (draftState: Draft, action: Action) => { switch (action.type) { case "ADD_TO_COUNTER": draftState.counter += action.payload break case "SUB_FROM_COUNTER": draftState.counter -= action.payload break } }, initialState ) /// =============== Reducers const reduce = redux.combineReducers({ counterReducer: reduceCounterProducer }) const curredReduce = redux.combineReducers({ counterReducer: reduceCounterCurriedProducer }) // reducing the current state to get the next state! // console.log(reduce(initialState, addToCounter(12)); // ================ store const store = redux.createStore(reduce) const curriedStore = redux.createStore(curredReduce) it("#470 works with Redux combine readonly reducers", () => { assert( store.getState().counterReducer, _ as { readonly counter: number } ) assert( curriedStore.getState().counterReducer, _ as { readonly counter: number } ) }) } } it("works with inferred curried reducer", () => { type State = { count: number } type Action = { type: "inc" count: number } const defaultState = { count: 3 } const store = redux.createStore( produce((state: State, action: Action) => { if (action.type === "inc") state.count += action.count // @ts-expect-error state.count2 }, defaultState) ) assert(store.getState(), _ as State) store.dispatch({ type: "inc", count: 2 }) store.dispatch({ // @ts-expect-error type: "inc2", count: 2 }) }) it("works with inferred curried reducer - readonly", () => { type State = { readonly count: number } type Action = { readonly type: "inc" readonly count: number } const defaultState: State = { count: 3 } const store = redux.createStore( produce((state: Draft, action: Action) => { if (action.type === "inc") state.count += action.count // @ts-expect-error state.count2 }, defaultState) ) assert(store.getState(), _ as State) store.dispatch({ type: "inc", count: 2 }) store.dispatch({ // @ts-expect-error type: "inc2", count: 2 }) }) ================================================ FILE: __tests__/regressions.js ================================================ "use strict" import { Immer, nothing, original, isDraft, immerable, enableMapSet } from "../src/immer" enableMapSet() runBaseTest("proxy (no freeze)", true, false) runBaseTest("proxy (autofreeze)", true, true) runBaseTest("es5 (no freeze)", false, false) runBaseTest("es5 (autofreeze)", false, true) function runBaseTest(name, useProxies, autoFreeze, useListener) { const listener = useListener ? function() {} : undefined const {produce, produceWithPatches} = createPatchedImmer({ useProxies, autoFreeze }) // When `useListener` is true, append a function to the arguments of every // uncurried `produce` call in every test. This makes tests easier to read. function createPatchedImmer(options) { const immer = new Immer(options) const {produce} = immer immer.produce = function(...args) { return typeof args[1] === "function" && args.length < 3 ? produce(...args, listener) : produce(...args) } return immer } describe(`regressions ${name}`, () => { test("#604 freeze inside class", () => { class Thing { [immerable] = true constructor({x}) { this._data = {x} } get x() { return this._data.x } set x(x) { this._data.x = x } } let i = 1 let item = new Thing({x: i}) let item0 = item const bump = () => { item = produce(item, draft => { // uncomment this to make things work //draft._data draft.x = ++i }) } bump() bump() expect(i).toBe(3) expect(item._data).toEqual({ x: 3 }) expect(item0._data).toEqual({ x: 1 }) }) test("#646 setting undefined field to undefined should not create new result", () => { const foo = { bar: undefined } const foo2 = produce(foo, draft => { draft.bar = undefined }) expect(foo2).toBe(foo) }) test("#646 - 2 setting undefined field to undefined should not create new result", () => { const foo = {} const foo2 = produce(foo, draft => { draft.bar = undefined }) expect(foo2).not.toBe(foo) expect(foo).toEqual({}) expect(foo2).toEqual({bar: undefined}) }) test("#638 - out of range assignments", () => { const state = [] const state1 = produce(state, draft => { draft[2] = "v2" }) expect(state1.length).toBe(3) expect(state1).toEqual([undefined, undefined, "v2"]) const state2 = produce(state1, draft => { draft[1] = "v1" }) expect(state2.length).toBe(3) expect(state2).toEqual([undefined, "v1", "v2"]) }) test("#628 set removal hangs", () => { let arr = [] let set = new Set([arr]) let result = produce(set, draft1 => { produce(draft1, draft2 => { draft2.delete(arr) }) }) expect(result).toEqual(new Set([[]])) // N.B. this outcome doesn't seem not correct, but then again, // double produce without return looks iffy as well, so not sure what the expected outcome in the // original report was }) test("#628 - 2 set removal hangs", () => { let arr = [] let set = new Set([arr]) let result = produce(set, draft2 => { draft2.delete(arr) }) expect(result).toEqual(new Set()) }) test("#650 - changes with overridden arr.slice() fail", () => { const data = { foo: [ { isActive: false } ] } // That's roughly what seamless-immutable does data.foo.slice = (...args) => Object.freeze(Array.prototype.slice.call(data.foo, ...args)) const newData = produce(data, draft => { draft.foo[0].isActive = true }) expect(newData.foo[0].isActive).toBe(true) }) test("#659 no reconciliation after read", () => { const bar = {} const foo = {bar} const next = produce(foo, draft => { draft.bar draft.bar = bar }) expect(next).toBe(foo) }) test("#659 no reconciliation after read - 2", () => { const bar = {} const foo = {bar} const next = produce(foo, draft => { const subDraft = draft.bar draft.bar = bar subDraft.x = 3 // this subDraft is not part of the end result, so ignore }) expect(next).toEqual(foo) }) test("#659 no reconciliation after read - 3", () => { const bar = {} const foo = {bar} const next = produce(foo, draft => { const subDraft = draft.bar subDraft.x = 3 // this subDraft is not part of the end result, so ignore draft.bar = bar }) expect(next).toEqual(foo) }) // Disabled: these are optimizations that would be nice if they // could be detected, but don't change the correctness of the result test.skip("#659 no reconciliation after read - 4", () => { const bar = {} const foo = {bar} const next = produce(foo, draft => { const subDraft = draft.bar draft.bar = bar subDraft.x = 3 // this subDraft is not part of the end result, so ignore }) expect(next).toBe(foo) }) // Disabled: these are optimizations that would be nice if they // could be detected, but don't change the correctness of the result test.skip("#659 no reconciliation after read - 5", () => { const bar = {} const foo = {bar} const next = produce(foo, draft => { const subDraft = draft.bar subDraft.x = 3 // this subDraft is not part of the end result, so ignore draft.bar = bar }) expect(next).toBe(foo) }) test("#659 no reconciliation after read - 6", () => { const bar = {} const foo = {bar} const next = produce(foo, draft => { const subDraft = draft.bar subDraft.x = 3 // this subDraft is not part of the end result, so ignore draft.bar = bar draft.bar = subDraft }) expect(next).not.toBe(foo) expect(next).toEqual({ bar: {x: 3} }) }) test("#807 new undefined member not stored", () => { const state = {} const newState = produce(state, draft => { draft.baz = undefined }) expect(state).not.toBe(newState) expect(Object.hasOwnProperty.call(newState, "baz")).toBe(true) expect(newState).toEqual({ baz: undefined }) }) test("Nested and chained produce calls throw 'Cannot perform 'get' on a proxy that has been revoked' error", () => { const state = { foo: { bar: { baz: "banana" } } } const newState = produce(state, draft => { draft.foo = produce(draft.foo, fooDraft => { fooDraft.baz = fooDraft.bar.baz.replace("banana", "apple") }) draft.foo = produce(draft.foo, fooDraft => { /* another produce call makes this fail */ /* no actual mutation necessary to make this happen */ // This happened before becouse the outer object is not modified, // so assumed to be safely freezable by Immer, while it actually still // contains a draft of bar, which wasn't retracted since we don't do that in nested // producers, as it can still be modified outside a produce }) }) expect(newState).toEqual({ foo: {baz: "apple", bar: {baz: "banana"}} }) }) }) } ================================================ FILE: __tests__/spec_ts.ts ================================================ /** * This file is literally copied from https://github.com/aleclarson/spec.ts/blob/master/index.d.ts. * For the sole reason, that the package somehow fails to install in our GitHub workflow. * It is unclear why, but all credits to @aleclarson! */ // Give "any" its own class export class Any { // @ts-ignore private _: true } // Conditional returns can enforce identical types. // See here: https://github.com/Microsoft/TypeScript/issues/27024#issuecomment-421529650 // prettier-ignore type TestExact = (() => U extends Left ? 1 : 0) extends (() => U extends Right ? 1 : 0) ? Any : never; type IsAny = Any extends T ? ([T] extends [Any] ? 1 : 0) : 0 export type Test = IsAny extends 1 ? IsAny extends 1 ? 1 : "❌ Left type is 'any' but right type is not" : IsAny extends 1 ? "❌ Right type is 'any' but left type is not" : [Left] extends [Right] ? [Right] extends [Left] ? Any extends TestExact ? 1 : "❌ Unexpected or missing 'readonly' property" : "❌ Right type is not assignable to left type" : "❌ Left type is not assignable to right type" type Assert = U extends 1 ? T // No error. : IsAny extends 1 ? never // Ensure "any" is refused. : U // Return the error message. /** * Raise a compiler error when both argument types are not identical. */ export const assert: ( left: Assert>, right: Assert> ) => Right = x => x as any /** * Placeholder value followed by "as T" */ export const _: any = Symbol("spec.ts placeholder") test("empty test to silence jest", () => { expect(true).toBeTruthy() }) ================================================ FILE: __tests__/test-data.json ================================================ { "_id": "5a5e59f1bc9132a90101f521", "index": 0, "guid": "8dc96fdb-0526-4bc4-a0ef-fb08e6c06e77", "isActive": true, "balance": "$3,359.66", "picture": "http://placehold.it/32x32", "age": 40, "eyeColor": "blue", "name": "Samantha Richardson", "gender": "female", "company": "COWTOWN", "email": "samantharichardson@cowtown.com", "phone": "+1 (847) 556-2336", "address": "419 Bergen Street, Emison, Nebraska, 554", "about": "Enim magna ut do esse voluptate et commodo anim laborum proident aute. Nulla non sit in incididunt minim velit. Laboris et tempor enim cillum ex adipisicing excepteur. Dolore consectetur eiusmod eu ad eu. Veniam qui sunt est reprehenderit et ut occaecat eiusmod pariatur aliquip officia ipsum.\r\n", "registered": "2017-07-09T02:30:48 -02:00", "latitude": -38.375287, "longitude": -27.090184, "tags": ["ex", "cillum", "cillum", "Lorem", "fugiat", "dolore", "nulla", "anim", "aliqua", "sint"], "friends": [ { "id": 0, "name": "Adrian Dunlap" }, { "id": 1, "name": "Salinas Copeland" }, { "id": 2, "name": "Doreen Emerson" }, { "id": 3, "name": "Willis Long" }, { "id": 4, "name": "Josefina Garza" } ], "greeting": "Hello, Samantha Richardson! You have 8 unread messages.", "favoriteFruit": "banana" } ================================================ FILE: __tests__/tsconfig.json ================================================ { "include": ["*", "../dist"], "compilerOptions": { "lib": ["es2015"], "strict": true, "noUnusedLocals": false, "target": "ES5", "types": ["vitest/globals"] } } ================================================ FILE: __tests__/type-external.ts ================================================ import {isType, JSONArray, JSONObject, JSONTypes} from "type-plus" import {Draft} from "../src/types/types-external" describe("Draft", () => { test("can use JSONTypes as T", () => { type A = Draft isType.equal() }) it("can use JSONArray as T", () => { type A = Draft isType.equal() }) it("can use Tuple as T", () => { type A = Draft<[string, number, JSONArray, JSONObject]> isType.equal() }) }) ================================================ FILE: __tests__/updateScenarios.js ================================================ import {describe, test, expect, beforeEach} from "vitest" import {produce} from "../src/immer" // Test configuration - smaller values for faster tests const TEST_CONFIG = { arraySize: 10, nestedArraySize: 2, multiUpdateCount: 5, reuseStateIterations: 5 } function createInitialState(arraySize = TEST_CONFIG.arraySize) { const initialState = { largeArray: Array.from({length: arraySize}, (_, i) => ({ id: i, value: Math.random(), nested: {key: `key-${i}`, data: Math.random()}, moreNested: { items: Array.from({length: TEST_CONFIG.nestedArraySize}, (_, i) => ({ id: i, name: String(i) })) } })), otherData: Array.from({length: arraySize}, (_, i) => ({ id: i, name: `name-${i}`, isActive: i % 2 === 0 })) } return initialState } // Utility functions for calculating array indices based on size const getValidIndex = (arraySize = TEST_CONFIG.arraySize) => { // Return a valid index (not the last one to avoid edge cases) return Math.min(arraySize - 2, Math.max(0, arraySize - 2)) } const getValidId = (arraySize = TEST_CONFIG.arraySize) => { // Return a valid ID that exists in the array return Math.min(arraySize - 2, Math.max(0, arraySize - 2)) } const getHighIndex = (offset = 0, arraySize = TEST_CONFIG.arraySize) => { // Calculate high index (80% through the array + offset) return Math.floor(arraySize * 0.8) + (offset % Math.floor(arraySize * 0.2)) } // Action creators const add = index => ({ type: "test/addItem", payload: {id: index, value: index, nested: {data: index}} }) const remove = index => ({type: "test/removeItem", payload: index}) const filter = percentToKeep => ({ type: "test/filterItem", payload: percentToKeep }) const update = index => ({ type: "test/updateItem", payload: {id: index, value: index, nestedData: index} }) const concat = index => ({ type: "test/concatArray", payload: Array.from({length: 50}, (_, i) => ({id: i, value: index})) }) const updateHigh = index => ({ type: "test/updateHighIndex", payload: { id: getHighIndex(index), value: index, nestedData: index } }) const updateMultiple = index => ({ type: "test/updateMultiple", payload: Array.from({length: TEST_CONFIG.multiUpdateCount}, (_, i) => ({ id: (index + i) % TEST_CONFIG.arraySize, value: index + i, nestedData: index + i })) }) const removeHigh = index => ({ type: "test/removeHighIndex", payload: getHighIndex(index) }) const sortByIdReverse = () => ({ type: "test/sortByIdReverse" }) const reverseArray = () => ({ type: "test/reverseArray" }) const actions = { add, remove, filter, update, concat, updateHigh, updateMultiple, removeHigh, sortByIdReverse, reverseArray } // Vanilla reducer for comparison const vanillaReducer = (state = createInitialState(), action) => { switch (action.type) { case "test/addItem": return { ...state, largeArray: [...state.largeArray, action.payload] } case "test/removeItem": { const newArray = state.largeArray.slice() newArray.splice(action.payload, 1) return { ...state, largeArray: newArray } } case "test/filterItem": { const length = state.largeArray.length const newArray = state.largeArray.filter( (item, i) => i / length < action.payload ) return { ...state, largeArray: newArray } } case "test/updateItem": { return { ...state, largeArray: state.largeArray.map(item => item.id === action.payload.id ? { ...item, value: action.payload.value, nested: {...item.nested, data: action.payload.nestedData} } : item ) } } case "test/concatArray": { const length = state.largeArray.length const newArray = action.payload.concat(state.largeArray) newArray.length = length return { ...state, largeArray: newArray } } case "test/updateHighIndex": { return { ...state, largeArray: state.largeArray.map(item => item.id === action.payload.id ? { ...item, value: action.payload.value, nested: {...item.nested, data: action.payload.nestedData} } : item ) } } case "test/updateMultiple": { const updates = new Map(action.payload.map(p => [p.id, p])) return { ...state, largeArray: state.largeArray.map(item => { const update = updates.get(item.id) return update ? { ...item, value: update.value, nested: {...item.nested, data: update.nestedData} } : item }) } } case "test/removeHighIndex": { const newArray = state.largeArray.slice() const indexToRemove = newArray.findIndex( item => item.id === action.payload ) if (indexToRemove !== -1) { newArray.splice(indexToRemove, 1) } return { ...state, largeArray: newArray } } case "test/sortByIdReverse": { const newArray = state.largeArray.slice() newArray.sort((a, b) => b.id - a.id) // Sort by ID in reverse order return { ...state, largeArray: newArray } } case "test/reverseArray": { const newArray = state.largeArray.slice() newArray.reverse() return { ...state, largeArray: newArray } } default: return state } } // Immer reducer const createImmerReducer = produce => { const immerReducer = (state = createInitialState(), action) => produce(state, draft => { switch (action.type) { case "test/addItem": draft.largeArray.push(action.payload) break case "test/removeItem": draft.largeArray.splice(action.payload, 1) break case "test/filterItem": { const keepPercentage = action.payload / 10 const length = state.largeArray.length draft.largeArray = draft.largeArray.filter( (item, i) => i / length < action.payload ) break } case "test/updateItem": { const item = draft.largeArray.find( item => item.id === action.payload.id ) if (item) { item.value = action.payload.value item.nested.data = action.payload.nestedData } break } case "test/concatArray": { const length = state.largeArray.length const newArray = action.payload.concat(state.largeArray) newArray.length = length draft.largeArray = newArray break } case "test/updateHighIndex": { const item = draft.largeArray.find( item => item.id === action.payload.id ) if (item) { item.value = action.payload.value item.nested.data = action.payload.nestedData } break } case "test/updateMultiple": { action.payload.forEach(update => { const item = draft.largeArray.find(item => item.id === update.id) if (item) { item.value = update.value item.nested.data = update.nestedData } }) break } case "test/removeHighIndex": { const indexToRemove = draft.largeArray.findIndex( item => item.id === action.payload ) if (indexToRemove !== -1) { draft.largeArray.splice(indexToRemove, 1) } break } case "test/sortByIdReverse": { draft.largeArray.sort((a, b) => b.id - a.id) break } case "test/reverseArray": { draft.largeArray.reverse() break } } }) return immerReducer } const immerReducer = createImmerReducer(produce) describe("Update Scenarios - Single Operations", () => { let initialState beforeEach(() => { initialState = createInitialState() }) test("add scenario", () => { const action = actions.add(0) const vanillaResult = vanillaReducer(initialState, action) const immerResult = immerReducer(initialState, action) expect(immerResult.largeArray.length).toBe(vanillaResult.largeArray.length) expect(immerResult.largeArray[immerResult.largeArray.length - 1]).toEqual( action.payload ) }) test("remove scenario", () => { const action = actions.remove(getValidIndex()) const vanillaResult = vanillaReducer(initialState, action) const immerResult = immerReducer(initialState, action) expect(immerResult.largeArray.length).toBe(vanillaResult.largeArray.length) expect(immerResult.largeArray.length).toBe( initialState.largeArray.length - 1 ) }) test("filter scenario", () => { // Keep 60% of the items const percentage = 0.6 const action = actions.filter(percentage) const vanillaResult = vanillaReducer(initialState, action) const immerResult = immerReducer(initialState, action) expect(immerResult.largeArray.length).toBe(vanillaResult.largeArray.length) expect(immerResult.largeArray.length).toBe( initialState.largeArray.length * percentage ) }) test("update scenario", () => { const targetId = getValidId() const action = actions.update(targetId) const vanillaResult = vanillaReducer(initialState, action) const immerResult = immerReducer(initialState, action) const updatedItem = immerResult.largeArray.find( item => item.id === targetId ) expect(updatedItem.value).toBe(targetId) expect(updatedItem.nested.data).toBe(targetId) }) test("concat scenario", () => { const action = actions.concat(1) const vanillaResult = vanillaReducer(initialState, action) const immerResult = immerReducer(initialState, action) expect(immerResult.largeArray.length).toBe(vanillaResult.largeArray.length) expect(immerResult.largeArray.length).toBe(initialState.largeArray.length) }) test("updateHigh scenario", () => { const action = actions.updateHigh(2) const vanillaResult = vanillaReducer(initialState, action) const immerResult = immerReducer(initialState, action) const targetId = action.payload.id const updatedItem = immerResult.largeArray.find( item => item.id === targetId ) expect(updatedItem.value).toBe(2) expect(updatedItem.nested.data).toBe(2) }) test("updateMultiple scenario", () => { const action = actions.updateMultiple(3) const vanillaResult = vanillaReducer(initialState, action) const immerResult = immerReducer(initialState, action) action.payload.forEach(update => { const updatedItem = immerResult.largeArray.find( item => item.id === update.id ) expect(updatedItem.value).toBe(update.value) expect(updatedItem.nested.data).toBe(update.nestedData) }) }) test("removeHigh scenario", () => { const action = actions.removeHigh(1) const vanillaResult = vanillaReducer(initialState, action) const immerResult = immerReducer(initialState, action) expect(immerResult.largeArray.length).toBe(vanillaResult.largeArray.length) const removedItem = immerResult.largeArray.find( item => item.id === action.payload ) expect(removedItem).toBeUndefined() }) test("sortByIdReverse scenario", () => { const action = actions.sortByIdReverse() const vanillaResult = vanillaReducer(initialState, action) const immerResult = immerReducer(initialState, action) expect(immerResult.largeArray.length).toBe(vanillaResult.largeArray.length) expect(immerResult.largeArray.length).toBe(initialState.largeArray.length) // Verify sorting - first element should have highest ID expect(immerResult.largeArray[0].id).toBe(TEST_CONFIG.arraySize - 1) expect(immerResult.largeArray[immerResult.largeArray.length - 1].id).toBe(0) // Verify arrays match expect(immerResult.largeArray.map(item => item.id)).toEqual( vanillaResult.largeArray.map(item => item.id) ) }) test("reverseArray scenario", () => { const action = actions.reverseArray() const vanillaResult = vanillaReducer(initialState, action) const immerResult = immerReducer(initialState, action) expect(immerResult.largeArray.length).toBe(vanillaResult.largeArray.length) expect(immerResult.largeArray.length).toBe(initialState.largeArray.length) // Verify reversal - first element should be what was last expect(immerResult.largeArray[0].id).toBe(TEST_CONFIG.arraySize - 1) expect(immerResult.largeArray[immerResult.largeArray.length - 1].id).toBe(0) // Verify arrays match expect(immerResult.largeArray.map(item => item.id)).toEqual( vanillaResult.largeArray.map(item => item.id) ) }) }) describe("Update Scenarios - State Reuse", () => { test("update-reuse scenario", () => { let currentState = createInitialState() for (let i = 0; i < TEST_CONFIG.reuseStateIterations; i++) { currentState = immerReducer(currentState, actions.update(i)) } // Verify the final state has all updates applied for (let i = 0; i < TEST_CONFIG.reuseStateIterations; i++) { const item = currentState.largeArray.find(item => item.id === i) expect(item.value).toBe(i) expect(item.nested.data).toBe(i) } }) test("updateHigh-reuse scenario", () => { let currentState = createInitialState() for (let i = 0; i < TEST_CONFIG.reuseStateIterations; i++) { currentState = immerReducer(currentState, actions.updateHigh(i)) } // Verify updates were applied to high indices expect(currentState.largeArray.length).toBe(TEST_CONFIG.arraySize) }) test("remove-reuse scenario", () => { let currentState = createInitialState() const originalLength = currentState.largeArray.length for (let i = 0; i < TEST_CONFIG.reuseStateIterations; i++) { currentState = immerReducer(currentState, actions.remove(0)) // Always remove first item } expect(currentState.largeArray.length).toBe( originalLength - TEST_CONFIG.reuseStateIterations ) }) test("removeHigh-reuse scenario", () => { let currentState = createInitialState() const originalLength = currentState.largeArray.length for (let i = 0; i < TEST_CONFIG.reuseStateIterations; i++) { currentState = immerReducer(currentState, actions.removeHigh(i)) } expect(currentState.largeArray.length).toBeLessThan(originalLength) }) }) describe("Update Scenarios - Mixed Sequence", () => { test("mixed-sequence scenario", () => { let state = createInitialState() const originalLength = state.largeArray.length // Perform a sequence of different operations (typical workflow) state = immerReducer(state, actions.add(1)) expect(state.largeArray.length).toBe(originalLength + 1) const targetId = getValidId() state = immerReducer(state, actions.update(targetId)) const updatedItem = state.largeArray.find(item => item.id === targetId) expect(updatedItem.value).toBe(targetId) state = immerReducer(state, actions.updateHigh(2)) state = immerReducer(state, actions.updateMultiple(3)) state = immerReducer(state, actions.remove(getValidIndex())) expect(state.largeArray.length).toBe(originalLength) // +1 from add, -1 from remove // Verify final state integrity expect(state.largeArray).toBeDefined() expect(state.otherData).toBeDefined() expect(state.largeArray.every(item => item.id !== undefined)).toBe(true) }) }) describe("Update Scenarios - Performance Focused", () => { test("large array operations", () => { const largeState = createInitialState(5000) // Test that operations complete without timeout const result1 = immerReducer(largeState, actions.update(1000)) expect(result1.largeArray.length).toBe(5000) const result2 = immerReducer(largeState, actions.updateHigh(10)) expect(result2.largeArray.length).toBe(5000) const result3 = immerReducer(largeState, actions.updateMultiple(20)) expect(result3.largeArray.length).toBe(5000) }) test("nested data modifications", () => { const state = createInitialState(100) const result = immerReducer(state, actions.update(50)) const updatedItem = result.largeArray.find(item => item.id === 50) expect(updatedItem.nested.data).toBe(50) expect(updatedItem.moreNested.items).toBeDefined() expect(updatedItem.moreNested.items.length).toBe( TEST_CONFIG.nestedArraySize ) }) }) ================================================ FILE: _site/.github/ISSUE_TEMPLATE/bug/index.html ================================================

🐛 Bug Report

A clear and concise description of what the bug is.

To Reproduce

Steps to reproduce the behavior:

Expected behavior

A clear and concise description of what you expected to happen.

Link to repro (highly encouraged)

Environment

  • Immer version:
  • [ ] Occurs with setUseProxies(true)
  • [ ] Occurs with setUseProxies(false) (ES5 only)
================================================ FILE: _site/.github/ISSUE_TEMPLATE/feature/index.html ================================================

🚀 Feature Proposal

A clear and concise description of what the feature is.

Motivation

Please outline the motivation for the proposal.

Example

Please provide an example for how this feature would be used.

================================================ FILE: _site/readme/index.html ================================================

Immer

npm Build Status Coverage Status Minzipped size code style: prettier Donate

Create the next immutable state tree by simply modifying the current tree

Winner of the "Breakthrough of the year" React open source award and "Most impactful contribution" JavaScript open source award in 2019

Release notes

Did Immer make a difference to your project? Consider buying me a coffee!
Buy Me A Coffee


  • NPM: npm install immer
  • Yarn: yarn add immer
  • CDN: Exposed global is immer
    • Unpkg: <script src="https://unpkg.com/immer/dist/immer.umd.js"></script>
    • JSDelivr: <script src="https://cdn.jsdelivr.net/npm/immer/dist/immer.umd.js"></script>

Immer (German for: always) is a tiny package that allows you to work with immutable state in a more convenient way. It is based on the copy-on-write mechanism.

The basic idea is that you will apply all your changes to a temporary draftState, which is a proxy of the currentState. Once all your mutations are completed, Immer will produce the nextState based on the mutations to the draft state. This means that you can interact with your data by simply modifying it while keeping all the benefits of immutable data.

immer-hd.png

Using Immer is like having a personal assistant; he takes a letter (the current state) and gives you a copy (draft) to jot changes onto. Once you are done, the assistant will take your draft and produce the real immutable, final letter for you (the next state).

A mindful reader might notice that this is quite similar to withMutations of ImmutableJS. It is indeed, but generalized and applied to plain, native JavaScript data structures (arrays and objects) without further needing any library.

External resources

API

The Immer package exposes a default function that does all the work.

produce(currentState, producer: (draftState) => void): nextState

There is also a curried overload that is explained below.

Example

import produce from "immer"

const baseState = [
	{
		todo: "Learn typescript",
		done: true
	},
	{
		todo: "Try immer",
		done: false
	}
]

const nextState = produce(baseState, draftState => {
	draftState.push({todo: "Tweet about it"})
	draftState[1].done = true
})

The interesting thing about Immer is that the baseState will be untouched, but the nextState will reflect all changes made to draftState.

// the new item is only added to the next state,
// base state is unmodified
expect(baseState.length).toBe(2)
expect(nextState.length).toBe(3)

// same for the changed 'done' prop
expect(baseState[1].done).toBe(false)
expect(nextState[1].done).toBe(true)

// unchanged data is structurally shared
expect(nextState[0]).toBe(baseState[0])
// changed data not (dûh)
expect(nextState[1]).not.toBe(baseState[1])

Benefits

  • Immutability with normal JavaScript objects and arrays. No new APIs to learn!
  • Strongly typed, no string based paths selectors etc.
  • Structural sharing out of the box
  • Object freezing out of the box
  • Deep updates are a breeze
  • Boilerplate reduction. Less noise, more concise code.
  • Small size

Read further to see all these benefits explained.

Reducer Example

Here is a simple example of the difference that Immer could make in practice.

// Redux reducer
// Shortened, based on: https://github.com/reactjs/redux/blob/master/examples/shopping-cart/src/reducers/products.js
const byId = (state, action) => {
	switch (action.type) {
		case RECEIVE_PRODUCTS:
			return {
				...state,
				...action.products.reduce((obj, product) => {
					obj[product.id] = product
					return obj
				}, {})
			}
		default:
			return state
	}
}

After using Immer, that simply becomes:

import produce from "immer"

const byId = (state, action) =>
	produce(state, draft => {
		switch (action.type) {
			case RECEIVE_PRODUCTS:
				action.products.forEach(product => {
					draft[product.id] = product
				})
		}
	})

Notice that it is not needed to handle the default case, a producer that doesn't do anything will simply return the original state.

Creating Redux reducer is just a sample application of the Immer package. Immer is not just designed to simplify Redux reducers. It can be used in any context where you have an immutable data tree that you want to clone and modify (with structural sharing).

Note: it might be tempting after using producers for a while, to just place produce in your root reducer and then pass the draft to each reducer and work directly over such draft. Don't do that. It kills the point of Redux where each reducer is testable as pure reducer. Immer is best used when applying it to small individual pieces of logic.

React.setState example

Deep updates in the state of React components can be greatly simplified as well by using immer. Take for example the following onClick handlers (Try in codesandbox):

/**
 * Classic React.setState with a deep merge
 */
onBirthDayClick1 = () => {
	this.setState(prevState => ({
		user: {
			...prevState.user,
			age: prevState.user.age + 1
		}
	}))
}

/**
 * ...But, since setState accepts functions,
 * we can just create a curried producer and further simplify!
 */
onBirthDayClick2 = () => {
	this.setState(
		produce(draft => {
			draft.user.age += 1
		})
	)
}

Currying

Passing a function as the first argument to produce is intended to be used for currying. This means that you get a pre-bound producer that only needs a state to produce the value from. The producer function gets passed in the draft and any further arguments that were passed to the curried function.

For example:

// mapper will be of signature (state, index) => state
const mapper = produce((draft, index) => {
	draft.index = index
})

// example usage
console.dir([{}, {}, {}].map(mapper))
//[{index: 0}, {index: 1}, {index: 2}])

This mechanism can also nicely be leveraged to further simplify our example reducer:

import produce from "immer"

const byId = produce((draft, action) => {
	switch (action.type) {
		case RECEIVE_PRODUCTS:
			action.products.forEach(product => {
				draft[product.id] = product
			})
			return
	}
})

Note that state is now factored out (the created reducer will accept a state, and invoke the bound producer with it).

If you want to initialize an uninitialized state using this construction, you can do so by passing the initial state as second argument to produce:

import produce from "immer"

const byId = produce(
	(draft, action) => {
		switch (action.type) {
			case RECEIVE_PRODUCTS:
				action.products.forEach(product => {
					draft[product.id] = product
				})
				return
		}
	},
	{
		1: {id: 1, name: "product-1"}
	}
)
Fun with currying

A random fun example just for inspiration: a neat trick is to turn Object.assign into a producer to create a "spread" function that is smarter than the normal spread operator, as it doesn't produce a new state if the result doesn't actually change (details & explanation). Quick example:

import produce from "immer"
const spread = produce(Object.assign)

const base = {x: 1, y: 1}

console.log({...base, y: 1} === base) // false
console.log(spread(base, {y: 1}) === base) // true! base is recycled as no actual new value was produced
console.log(spread(base, {y: 2}) === base) // false, produced a new object as it should

Patches

During the run of a producer, Immer can record all the patches that would replay the changes made by the reducer. This is a very powerful tool if you want to fork your state temporarily and replay the changes to the original.

Patches are useful in few scenarios:

  • To exchange incremental updates with other parties, for example over websockets
  • For debugging / traces, to see precisely how state is changed over time
  • As basis for undo/redo or as an approach to replay changes on a slightly different state tree

To help with replaying patches, applyPatches comes in handy. Here is an example how patches could be used to record the incremental updates and (inverse) apply them:

import produce, {applyPatches} from "immer"

let state = {
	name: "Micheal",
	age: 32
}

// Let's assume the user is in a wizard, and we don't know whether
// his changes should end up in the base state ultimately or not...
let fork = state
// all the changes the user made in the wizard
let changes = []
// the inverse of all the changes made in the wizard
let inverseChanges = []

fork = produce(
	fork,
	draft => {
		draft.age = 33
	},
	// The third argument to produce is a callback to which the patches will be fed
	(patches, inversePatches) => {
		changes.push(...patches)
		inverseChanges.push(...inversePatches)
	}
)

// In the meantime, our original state is replaced, as, for example,
// some changes were received from the server
state = produce(state, draft => {
	draft.name = "Michel"
})

// When the wizard finishes (successfully) we can replay the changes that were in the fork onto the *new* state!
state = applyPatches(state, changes)

// state now contains the changes from both code paths!
expect(state).toEqual({
	name: "Michel", // changed by the server
	age: 33 // changed by the wizard
})

// Finally, even after finishing the wizard, the user might change his mind and undo his changes...
state = applyPatches(state, inverseChanges)
expect(state).toEqual({
	name: "Michel", // Not reverted
	age: 32 // Reverted
})

The generated patches are similar (but not the same) to the RFC-6902 JSON patch standard, except that the path property is an array, rather than a string. This makes processing patches easier. If you want to normalize to the official specification, patch.path = patch.path.join("/") should do the trick. Anyway, this is what a bunch of patches and their inverse could look like:

[
	{
		"op": "replace",
		"path": ["profile"],
		"value": {"name": "Veria", "age": 5}
	},
	{"op": "remove", "path": ["tags", 3]}
]
[
	{"op": "replace", "path": ["profile"], "value": {"name": "Noa", "age": 6}},
	{"op": "add", "path": ["tags", 3], "value": "kiddo"}
]

produceWithPatches

Instead of setting up a patch listener, an easier way to obtain the patches is to use produceWithPatches, which has the same signature as produce, except that it doesn't return just the next state, but a tuple consisting of [nextState, patches, inversePatches]. Like produce, produceWithPatches supports currying as well.

import {produceWithPatches} from "immer"

const [nextState, patches, inversePatches] = produceWithPatches(
	{
		age: 33
	},
	draft => {
		draft.age++
	}
)

Which produces:

;[
	{
		age: 34
	},
	[
		{
			op: "replace",
			path: ["age"],
			value: 34
		}
	],
	[
		{
			op: "replace",
			path: ["age"],
			value: 33
		}
	]
]

For a more in-depth study, see Distributing patches and rebasing actions using Immer

Tip: Check this trick to compress patches produced over time.

Async producers

It is allowed to return Promise objects from recipes. Or, in other words, to use async / await. This can be pretty useful for long running processes, that only produce the new object once the promise chain resolves. Note that produce itself (even in the curried form) will return a promise if the producer is async. Example:

import produce from "immer"

const user = {
	name: "michel",
	todos: []
}

const loadedUser = await produce(user, async function(draft) {
	draft.todos = await (await window.fetch("http://host/" + draft.name)).json()
})

Warning: please note that the draft shouldn't be 'leaked' from the async process and stored else where. The draft will still be revoked as soon as the async process completes.

createDraft and finishDraft

createDraft and finishDraft are two low-level functions that are mostly useful for libraries that build abstractions on top of immer. It avoids the need to always create a function in order to work with drafts. Instead, one can create a draft, modify it, and at some time in the future finish the draft, in which case the next immutable state will be produced. We could for example rewrite our above example as:

import {createDraft, finishDraft} from "immer"

const user = {
	name: "michel",
	todos: []
}

const draft = createDraft(user)
draft.todos = await (await window.fetch("http://host/" + draft.name)).json()
const loadedUser = finishDraft(draft)

Note: finishDraft takes a patchListener as second argument, which can be used to record the patches, similarly to produce.

Warning: in general, we recommend to use produce instead of the createDraft / finishDraft combo, produce is less error prone in usage, and more clearly separates the concepts of mutability and immutability in your code base.

Returning data from producers

It is not needed to return anything from a producer, as Immer will return the (finalized) version of the draft anyway. However, it is allowed to just return draft.

It is also allowed to return arbitrarily other data from the producer function. But only if you didn't modify the draft. This can be useful to produce an entirely new state. Some examples:

const userReducer = produce((draft, action) => {
	switch (action.type) {
		case "renameUser":
			// OK: we modify the current state
			draft.users[action.payload.id].name = action.payload.name
			return draft // same as just 'return'
		case "loadUsers":
			// OK: we return an entirely new state
			return action.payload
		case "adduser-1":
			// NOT OK: This doesn't do change the draft nor return a new state!
			// It doesn't modify the draft (it just redeclares it)
			// In fact, this just doesn't do anything at all
			draft = {users: [...draft.users, action.payload]}
			return
		case "adduser-2":
			// NOT OK: modifying draft *and* returning a new state
			draft.userCount += 1
			return {users: [...draft.users, action.payload]}
		case "adduser-3":
			// OK: returning a new state. But, unnecessary complex and expensive
			return {
				userCount: draft.userCount + 1,
				users: [...draft.users, action.payload]
			}
		case "adduser-4":
			// OK: the immer way
			draft.userCount += 1
			draft.users.push(action.payload)
			return
	}
})

Note: It is not possible to return undefined this way, as it is indistinguishable from not updating the draft! Read on...

Producing undefined using nothing

So, in general, one can replace the current state by just returning a new value from the producer, rather than modifying the draft. There is a subtle edge case however: if you try to write a producer that wants to replace the current state with undefined:

produce({}, draft => {
	// don't do anything
})

Versus:

produce({}, draft => {
	// Try to return undefined from the producer
	return undefined
})

The problem is that in JavaScript a function that doesn't return anything also returns undefined! So immer cannot differentiate between those different cases. So, by default, Immer will assume that any producer that returns undefined just tried to modify the draft.

However, to make it clear to Immer that you intentionally want to produce the value undefined, you can return the built-in token nothing:

import produce, {nothing} from "immer"

const state = {
	hello: "world"
}

produce(state, draft => {})
produce(state, draft => undefined)
// Both return the original state: { hello: "world"}

produce(state, draft => nothing)
// Produces a new state, 'undefined'

N.B. Note that this problem is specific for the undefined value, any other value, including null, doesn't suffer from this issue.

Inline shortcuts using void

Draft mutations in Immer usually warrant a code block, since a return denotes an overwrite. Sometimes that can stretch code a little more than you might be comfortable with.

In such cases, you can use javascripts void operator, which evaluates expressions and returns undefined.

// Single mutation
produce(draft => void (draft.user.age += 1))

// Multiple mutations
produce(draft => void ((draft.user.age += 1), (draft.user.height = 186)))

Code style is highly personal, but for code bases that are to be understood by many, we recommend to stick to the classic draft => { draft.user.age += 1} to avoid cognitive overhead.

Extracting the original object from a proxied instance

Immer exposes a named export original that will get the original object from the proxied instance inside produce (or return undefined for unproxied values). A good example of when this can be useful is when searching for nodes in a tree-like state using strict equality.

import {original} from "immer"

const baseState = {users: [{name: "Richie"}]}
const nextState = produce(baseState, draftState => {
	original(draftState.users) // is === baseState.users
})

Just want to know if a value is a proxied instance? Use the isDraft function!

import {isDraft} from "immer"

const baseState = {users: [{name: "Bobby"}]}
const nextState = produce(baseState, draft => {
	isDraft(draft) // => true
	isDraft(draft.users) // => true
	isDraft(draft.users[0]) // => true
})
isDraft(nextState) // => false

Auto freezing

Immer automatically freezes any state trees that are modified using produce. This protects against accidental modifications of the state tree outside of a producer. This comes with a performance impact, so it is recommended to disable this option in production. It is by default enabled. By default, it is turned on during local development and turned off in production. Use setAutoFreeze(true / false) to explicitly turn this feature on or off.

⚠️ If auto freezing is enabled, recipes are not entirely side-effect free: Any plain object or array that ends up in the produced result, will be frozen, even when these objects were not frozen before the start of the producer! ⚠️

Immer on older JavaScript environments?

By default produce tries to use proxies for optimal performance. However, on older JavaScript engines Proxy is not available. For example, when running Microsoft Internet Explorer or React Native (< v0.59) on Android. In such cases, Immer will fallback to an ES5 compatible implementation which works identical, but is a bit slower.

Importing immer

produce is exposed as the default export, but optionally it can be used as name import as well, as this benefits some older project setups. So the following imports are all correct, where the first is recommended:

import produce from "immer"
import {produce} from "immer"

const {produce} = require("immer")
const produce = require("immer").produce
const produce = require("immer").default

import unleashTheMagic from "immer"
import {produce as unleashTheMagic} from "immer"

Supported object types

Plain objects and arrays are always drafted by Immer.

Every other object must use the immerable symbol to mark itself as compatible with Immer. When one of these objects is mutated within a producer, its prototype is preserved between copies.

import {immerable} from "immer"

class Foo {
	[immerable] = true // Option 1

	constructor() {
		this[immerable] = true // Option 2
	}
}

Foo[immerable] = true // Option 3

For arrays, only numeric properties and the length property can be mutated. Custom properties are not preserved on arrays.

When working with Date objects, you should always create a new Date instance instead of mutating an existing Date object.

Built-in classes like Map and Set are not supported. As a workaround, you should clone them before mutating them in a producer:

const state = {
	set: new Set(),
	map: new Map()
}
const nextState = produce(state, draft => {
	// Don't use any Set methods, as that mutates the instance!
	draft.set.add("foo") // ❌

	// 1. Instead, clone the set (just once)
	const newSet = new Set(draft.set) // ✅

	// 2. Mutate the clone (just in this producer)
	newSet.add("foo")

	// 3. Update the draft with the new set
	draft.set = newSet

	// Similarly, don't use any Map methods.
	draft.map.set("foo", "bar") // ❌

	// 1. Instead, clone the map (just once)
	const newMap = new Map(draft.map) // ✅

	// 2. Mutate it
	newMap.set("foo", "bar")

	// 3. Update the draft
	draft.map = newMap
})

TypeScript or Flow

The Immer package ships with type definitions inside the package, which should be picked up by TypeScript and Flow out of the box and without further configuration.

The TypeScript typings automatically remove readonly modifiers from your draft types and return a value that matches your original type. See this practical example:

import produce from "immer"

interface State {
	readonly x: number
}

// `x` cannot be modified here
const state: State = {
	x: 0
}

const newState = produce(state, draft => {
	// `x` can be modified here
	draft.x++
})

// `newState.x` cannot be modified here

This ensures that the only place you can modify your state is in your produce callbacks. It even works recursively and with ReadonlyArrays!

For curried reducers, the type is inferred from the first argument of recipe function, so make sure to type it. The Draft utility type can be used if the state argument type is immutable:

import produce, {Draft} from "immer"

interface State {
	readonly x: number
}

// `x` cannot be modified here
const state: State = {
	x: 0
}

const increment = produce((draft: Draft<State>, inc: number) => {
	// `x` can be modified here
	draft.x += inc
})

const newState = increment(state, 2)
// `newState.x` cannot be modified here

Note: Immer v1.9+ supports TypeScript v3.1+ only.

Note: Immer v3.0+ supports TypeScript v3.4+ only.

Pitfalls

  1. Don't redefine draft like, draft = myCoolNewState. Instead, either modify the draft or return a new state. See Returning data from producers.
  2. Immer assumes your state to be a unidirectional tree. That is, no object should appear twice in the tree, and there should be no circular references.
  3. Since Immer uses proxies, reading huge amounts of data from state comes with an overhead (especially in the ES5 implementation). If this ever becomes an issue (measure before you optimize!), do the current state analysis before entering the producer function or read from the currentState rather than the draftState. Also, realize that immer is opt-in everywhere, so it is perfectly fine to manually write super performance critical reducers, and use immer for all the normal ones. Also note that original can be used to get the original state of an object, which is cheaper to read.
  4. Always try to pull produce 'up', for example for (let x of y) produce(base, d => d.push(x)) is exponentially slower than produce(base, d => { for (let x of y) d.push(x)})
  5. It is possible to return values from producers, except, it is not possible to return undefined that way, as it is indistinguishable from not updating the draft at all! If you want to replace the draft with undefined, just return nothing from the producer.

Cool things built with immer

  • react-copy-write Immutable state with a mutable API
  • redux-starter-kit A simple set of tools to make using Redux easier
  • immer based handleActions Boilerplate free actions for Redux
  • redux-box Modular and easy-to-grasp redux based state management, with least boilerplate
  • quick-redux tools to make redux development quicker and easier
  • bey Simple immutable state for React using Immer
  • immer-wieder State management lib that combines React 16 Context and immer for Redux semantics
  • robodux flexible way to reduce redux boilerplate
  • immer-reducer Type-safe and terse React (useReducer()) and Redux reducers with Typescript
  • redux-ts-utils Everything you need to create type-safe applications with Redux with a strong emphasis on simplicity
  • react-state-tree Drop-in replacement for useState that persists your state into a redux-like state tree
  • redux-immer is used to create an equivalent function of Redux combineReducers that works with immer state. Like redux-immutable but for immer
  • ... and many more

How does Immer work?

Read the (second part of the) introduction blog.

Example patterns.

For those who have to go back to thinking in object updates :-)

import produce from "immer"

// object mutations
const todosObj = {
	id1: {done: false, body: "Take out the trash"},
	id2: {done: false, body: "Check Email"}
}

// add
const addedTodosObj = produce(todosObj, draft => {
	draft["id3"] = {done: false, body: "Buy bananas"}
})

// delete
const deletedTodosObj = produce(todosObj, draft => {
	delete draft["id1"]
})

// update
const updatedTodosObj = produce(todosObj, draft => {
	draft["id1"].done = true
})

// array mutations
const todosArray = [
	{id: "id1", done: false, body: "Take out the trash"},
	{id: "id2", done: false, body: "Check Email"}
]

// add
const addedTodosArray = produce(todosArray, draft => {
	draft.push({id: "id3", done: false, body: "Buy bananas"})
})

// delete
const deletedTodosArray = produce(todosArray, draft => {
	draft.splice(draft.findIndex(todo => todo.id === "id1"), 1)
	// or (slower):
	// return draft.filter(todo => todo.id !== "id1")
})

// update
const updatedTodosArray = produce(todosArray, draft => {
	draft[draft.findIndex(todo => todo.id === "id1")].done = true
})

Performance

Here is a simple benchmark on the performance of Immer. This test takes 50,000 todo items and updates 5,000 of them. Freeze indicates that the state tree has been frozen after producing it. This is a development best practice, as it prevents developers from accidentally modifying the state tree.

These tests were executed on Node 9.3.0. Use yarn test:perf to reproduce them locally.

performance.png

Most important observation:

  • Immer with proxies is roughly speaking twice to three times slower as a handwritten reducer (the above test case is worst case, see yarn test:perf for more tests). This is in practice negligible.
  • Immer is roughly as fast as ImmutableJS. However, the immutableJS + toJS makes clear the cost that often needs to be paid later; converting the immutableJS objects back to plain objects, to be able to pass them to components, over the network etc... (And there is also the upfront cost of converting data received from e.g. the server to immutable JS)
  • Generating patches doesn't significantly slow down immer
  • The ES5 fallback implementation is roughly twice as slow as the proxy implementation, in some cases worse.

Migration

Immer 2.* -> 3.0

In your producers, make sure you're not treating this as the draft. (see here: https://github.com/immerjs/immer/issues/308)

Upgrade to typescript@^3.4 if you're a TypeScript user.

Immer 1.* -> 2.0

Make sure you don't return any promises as state, because produce will actually invoke the promise and wait until it settles.

Immer 2.1 -> 2.2

When using TypeScript, for curried reducers that are typed in the form produce<Type>((arg) => { }), rewrite this to produce((arg: Type) => { }) or produce((arg: Draft<Type>) => { }) for correct inference.

FAQ

(for those who skimmed the above instead of actually reading)

Q: Does Immer use structural sharing? So that my selectors can be memoized and such?

A: Yes

Q: Does Immer support deep updates?

A: Yes

Q: I can't rely on Proxies being present on my target environments. Can I use Immer?

A: Yes

Q: Can I typecheck my data structures when using Immer?

A: Yes

Q: Can I store Date objects, functions etc in my state tree when using Immer?

A: Yes

Q: Is it fast?

A: Yes

Q: Idea! Can Immer freeze the state for me?

A: Yes

Credits

Special thanks to @Mendix, which supports its employees to experiment completely freely two full days a month, which formed the kick-start for this project.

Donations

A significant part of my OSS work is unpaid. So donations are greatly appreciated :)

================================================ FILE: package.json ================================================ { "name": "immer", "version": "10.0.3-beta", "description": "Create your next immutable state by mutating the current one", "main": "./dist/cjs/index.js", "module": "./dist/immer.legacy-esm.js", "exports": { "./package.json": "./package.json", ".": { "react-native": { "types": "./dist/immer.d.ts", "default": "./dist/immer.legacy-esm.js" }, "import": { "types": "./dist/immer.d.ts", "default": "./dist/immer.mjs" }, "require": { "types": "./dist/immer.d.ts", "default": "./dist/cjs/index.js" } } }, "jsnext:main": "dist/immer.mjs", "source": "src/immer.ts", "types": "./dist/immer.d.ts", "sideEffects": false, "scripts": { "test": "vitest run && yarn test:build && yarn test:flow", "test:perf": "cd __performance_tests__ && node add-data.mjs && node todo.mjs && node incremental.mjs && node large-obj.mjs", "test:flow": "yarn flow check __tests__/flow", "test:build": "yarn build && vitest run --config vitest.config.build.ts", "test:src": "vitest run", "watch": "vitest", "coverage": "vitest run --coverage", "coveralls": "vitest run --coverage && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf ./coverage", "build": "tsup", "publish-docs": "cd website && GIT_USER=mweststrate USE_SSH=true yarn docusaurus deploy", "start": "cd website && yarn start", "test:size": "yarn build && yarn import-size --report . produce enableMapSet enablePatches enableArrayMethods", "test:sizequick": "yarn build && yarn import-size . produce" }, "husky": { "hooks": { "pre-commit": "pretty-quick --staged" } }, "repository": { "type": "git", "url": "https://github.com/immerjs/immer.git" }, "keywords": [ "immutable", "mutable", "copy-on-write" ], "author": "Michel Weststrate ", "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" }, "bugs": { "url": "https://github.com/immerjs/immer/issues" }, "homepage": "https://github.com/immerjs/immer#readme", "files": [ "dist", "compat", "src" ], "devDependencies": { "@babel/core": "^7.21.3", "@types/node": "^24.3.1", "@vitest/coverage-v8": "2.1.9", "coveralls": "^3.0.0", "cpx2": "^3.0.0", "deep-freeze": "^0.0.1", "flow-bin": "^0.123.0", "husky": "^1.2.0", "immutable": "^3.8.2", "import-size": "^1.0.2", "lodash": "^4.17.4", "lodash.clonedeep": "^4.5.0", "prettier": "1.19.1", "pretty-quick": "^1.8.0", "redux": "^4.0.5", "rimraf": "^2.6.2", "seamless-immutable": "^7.1.3", "semantic-release": "^17.0.2", "tsup": "^6.7.0", "type-plus": "^7.6.2", "typescript": "^5.0.2", "vite": "^5.4.0", "vitest": "^2.0.0" } } ================================================ FILE: perf-testing/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? # CPU profiles *.cpuprofile # Yarn .yarn/* !.yarn/patches !.yarn/plugins !.yarn/releases !.yarn/sdks !.yarn/versions ================================================ FILE: perf-testing/README.md ================================================ # Immer Performance Testing This directory contains performance testing tools for Immer, allowing you to benchmark different versions of Immer and analyze CPU profiles to identify performance bottlenecks. ## Setup 1. **Install dependencies** (in this directory): ```bash yarn install ``` 2. **Build Immer first**: ```bash yarn build-immer ``` 3. **Build the benchmark bundle**: ```bash yarn build ``` Alternately, you can rebuild both Immer and the benchmarking script: ```bash yarn build-with-latest ``` ## Usage ### Running Benchmarks To run the performance benchmarks: ```bash # Run basic benchmarks, with relative version speed comparisons yarn benchmark # Run the benchmarks, but also generate a CPU profile yarn profile ``` ### Analyzing CPU Profiles After running `yarn profile`, you'll get a `.cpuprofile` file. To analyze it: ```bash # Analyze the most recent profile yarn analyze-profile your-profile.cpuprofile ``` ## What's Included - **immutability-benchmarks.mjs**: Main benchmark script comparing different Immer versions - **read-cpuprofile.js**: Advanced CPU profile analyzer with sourcemap support - **rolldown.config.js**: Bundler configuration that eliminates `process.env` overhead ## Benchmark Versions The benchmarks compare: - **immer7-10**: Historical Immer versions - **immer10Perf**: Current development version (references `../dist`) - **vanilla**: Pure JavaScript implementations for baseline comparison ## Key Features - **Sourcemap support**: CPU profile analysis includes original function names - **Version-aware analysis**: Breaks down performance by Immer version - **Production bundling**: Uses Rolldown to eliminate development overhead ================================================ FILE: perf-testing/immutability-benchmarks.mjs ================================================ /* eslint-disable no-inner-declarations */ import "source-map-support/register" import {produce as produce5, setAutoFreeze as setAutoFreeze5} from "immer5" import {produce as produce6, setAutoFreeze as setAutoFreeze6} from "immer6" import {produce as produce7, setAutoFreeze as setAutoFreeze7} from "immer7" import {produce as produce8, setAutoFreeze as setAutoFreeze8} from "immer8" import {produce as produce9, setAutoFreeze as setAutoFreeze9} from "immer9" import {produce as produce10, setAutoFreeze as setAutoFreeze10} from "immer10" import { produce as produce10Perf, setAutoFreeze as setAutoFreeze10Perf, enableArrayMethods as enableArrayMethods10Perf } from "immer10Perf" import {create as produceMutative} from "mutative" import { produce as produceMutativeCompat, setAutoFreeze as setAutoFreezeMutativeCompat } from "mutative-compat" import { produce as produceStructura, enableAutoFreeze as setAutoFreezeStructura } from "structurajs" import {produce as produceLimu, setAutoFreeze as setAutoFreezeLimu} from "limu" import {bench, run, group, summary} from "mitata" function createInitialState(arraySize = BENCHMARK_CONFIG.arraySize) { const initialState = { largeArray: Array.from({length: arraySize}, (_, i) => ({ id: i, value: Math.random(), nested: {key: `key-${i}`, data: Math.random()}, moreNested: { items: Array.from( {length: BENCHMARK_CONFIG.nestedArraySize}, (_, i) => ({id: i, name: String(i)}) ) } })), otherData: Array.from({length: arraySize}, (_, i) => ({ id: i, name: `name-${i}`, isActive: i % 2 === 0 })), largeObject1: createLargeObject(BENCHMARK_CONFIG.largeObjectSize1), largeObject2: createLargeObject(BENCHMARK_CONFIG.largeObjectSize2), api: { queries: {}, provided: { keys: {} }, subscriptions: {} } } return initialState } const MAX = 1 const BENCHMARK_CONFIG = { iterations: 1, arraySize: 100, nestedArraySize: 10, largeObjectSize1: 1000, largeObjectSize2: 3000, multiUpdateCount: 5, reuseStateIterations: 10 } // Utility functions for calculating array indices based on size const getValidIndex = (arraySize = BENCHMARK_CONFIG.arraySize) => { // Return a valid index (not the last one to avoid edge cases) return Math.min(arraySize - 2, Math.max(0, arraySize - 2)) } const getValidId = (arraySize = BENCHMARK_CONFIG.arraySize) => { // Return a valid ID that exists in the array return Math.min(arraySize - 2, Math.max(0, arraySize - 2)) } function createLargeObject(size = 100) { const obj = {} for (let i = 0; i < size; i++) { obj[`property${i}`] = { id: i, value: Math.random(), name: `item-${i}`, active: i % 2 === 0 } } return obj } const add = index => ({ type: "test/addItem", payload: {id: index, value: index, nested: {data: index}} }) const remove = index => ({type: "test/removeItem", payload: index}) const filter = percentToKeep => ({ type: "test/filterItem", payload: percentToKeep }) const update = index => ({ type: "test/updateItem", payload: {id: index, value: index, nestedData: index} }) const updateLargeObject1 = index => ({ type: "test/updateLargeObject1", payload: {value: index} }) const updateLargeObject2 = index => ({ type: "test/updateLargeObject2", payload: {value: index} }) const concat = index => ({ type: "test/concatArray", payload: Array.from({length: 500}, (_, i) => ({id: i, value: index})) }) const mapNested = () => ({ type: "test/mapNested" }) const updateHigh = index => ({ type: "test/updateHighIndex", payload: { id: Math.floor(BENCHMARK_CONFIG.arraySize * 0.8) + (index % Math.floor(BENCHMARK_CONFIG.arraySize * 0.2)), value: index, nestedData: index } }) const updateMultiple = index => ({ type: "test/updateMultiple", payload: Array.from({length: BENCHMARK_CONFIG.multiUpdateCount}, (_, i) => ({ id: (index + i) % BENCHMARK_CONFIG.arraySize, value: index + i, nestedData: index + i })) }) const removeHigh = index => ({ type: "test/removeHighIndex", payload: Math.floor(BENCHMARK_CONFIG.arraySize * 0.8) + (index % Math.floor(BENCHMARK_CONFIG.arraySize * 0.2)) }) const sortByIdReverse = () => ({ type: "test/sortByIdReverse" }) const reverseArray = () => ({ type: "test/reverseArray" }) // RTKQ-style action creators const rtkqPending = index => ({ type: "rtkq/pending", payload: { cacheKey: `some("test-${index}-")`, requestId: `req-${index}`, id: `test-${index}-` } }) const rtkqResolved = index => ({ type: "rtkq/resolved", payload: { cacheKey: `some("test-${index}-")`, requestId: `req-${index}`, id: `test-${index}-`, data: `test-${index}-1` } }) const actions = { add, remove, filter, update, concat, mapNested, // dash-named fields to improve readability in benchmark results "update-largeObject1": updateLargeObject1, "update-largeObject2": updateLargeObject2, "update-high": updateHigh, "update-multiple": updateMultiple, "remove-high": removeHigh, "sortById-reverse": sortByIdReverse, "reverse-array": reverseArray } const immerProducers = { // immer5: produce5, // immer6: produce6, // immer7: produce7, // immer8: produce8, // immer9: produce9, immer10: produce10, immer10Perf: produce10Perf // mutative: produceMutative, // mutativeCompat: produceMutativeCompat, // structura: produceStructura, // limu: produceLimu } const noop = () => {} const setAutoFreezes = { vanilla: noop, immer5: setAutoFreeze5, immer6: setAutoFreeze6, immer7: setAutoFreeze7, immer8: setAutoFreeze8, immer9: setAutoFreeze9, immer10: setAutoFreeze10, immer10Perf: setAutoFreeze10Perf, mutative: noop, mutativeCompat: setAutoFreezeMutativeCompat, structura: setAutoFreezeStructura, limu: setAutoFreezeLimu } const setStrictIteration = { vanilla: noop, immer5: noop, immer6: noop, immer7: noop, immer8: noop, immer9: noop, immer10: noop, immer10Perf: noop, // setUseStrictIteration10Perf, mutative: noop, mutativeCompat: noop, structura: noop, limu: noop } const setEnableArrayMethods = { vanilla: noop, immer5: noop, immer6: noop, immer7: noop, immer8: noop, immer9: noop, immer10: noop, immer10Perf: enableArrayMethods10Perf, mutative: noop, mutativeCompat: noop, structura: noop, limu: noop } // RTKQ-style separate reducer functions (simulating separate RTK slices) const updateQueries = (queries, action) => { switch (action.type) { case "rtkq/pending": return { ...queries, [action.payload.cacheKey]: { id: action.payload.id, status: "pending", data: undefined } } case "rtkq/resolved": return { ...queries, [action.payload.cacheKey]: { ...queries[action.payload.cacheKey], status: "fulfilled", data: action.payload.data } } default: return queries } } const updateProvided = (provided, action) => { switch (action.type) { case "rtkq/pending": case "rtkq/resolved": return { ...provided, keys: { ...provided.keys, [action.payload.cacheKey]: {} } } default: return provided } } const updateSubscriptions = (subscriptions, action) => { switch (action.type) { case "rtkq/pending": return { ...subscriptions, [action.payload.cacheKey]: { [action.payload.requestId]: { pollingInterval: 0, skipPollingIfUnfocused: false } } } case "rtkq/resolved": return subscriptions // No change on resolved default: return subscriptions } } const vanillaReducer = (state = createInitialState(), action) => { switch (action.type) { case "test/addItem": return { ...state, largeArray: [...state.largeArray, action.payload] } case "test/removeItem": { const newArray = state.largeArray.slice() newArray.splice(action.payload, 1) return { ...state, largeArray: newArray } } case "test/filterItem": { const keepPercentage = action.payload / 10 const length = state.largeArray.length const newArray = state.largeArray.filter( (item, i) => i / length < action.payload ) return { ...state, largeArray: newArray } } case "test/updateItem": { return { ...state, largeArray: state.largeArray.map(item => item.id === action.payload.id ? { ...item, value: action.payload.value, nested: {...item.nested, data: action.payload.nestedData} } : item ) } } case "test/updateLargeObject1": { return { ...state, largeObject1: { ...state.largeObject1, [`propertyAdded${action.payload.value}`]: { id: action.payload.value } } } } case "test/updateLargeObject2": { return { ...state, largeObject2: { ...state.largeObject2, [`propertyAdded${action.payload.value}`]: { id: action.payload.value } } } } case "test/concatArray": { const length = state.largeArray.length const newArray = action.payload.concat(state.largeArray) newArray.length = length return { ...state, largeArray: newArray } } case "test/mapNested": { // Extract nested data - common pattern for denormalization or view preparation const nestedData = state.largeArray.map(item => item.nested) return { ...state, otherData: nestedData // Store extracted nested objects } } case "test/updateHighIndex": { return { ...state, largeArray: state.largeArray.map(item => item.id === action.payload.id ? { ...item, value: action.payload.value, nested: {...item.nested, data: action.payload.nestedData} } : item ) } } case "test/updateMultiple": { const updates = new Map(action.payload.map(p => [p.id, p])) return { ...state, largeArray: state.largeArray.map(item => { const update = updates.get(item.id) return update ? { ...item, value: update.value, nested: {...item.nested, data: update.nestedData} } : item }) } } case "test/removeHighIndex": { const newArray = state.largeArray.slice() const indexToRemove = newArray.findIndex( item => item.id === action.payload ) if (indexToRemove !== -1) { newArray.splice(indexToRemove, 1) } return { ...state, largeArray: newArray } } case "test/sortByIdReverse": { const newArray = state.largeArray.slice() newArray.sort((a, b) => b.id - a.id) // Sort by ID in reverse order return { ...state, largeArray: newArray } } case "test/reverseArray": { const newArray = state.largeArray.slice() newArray.reverse() return { ...state, largeArray: newArray } } case "rtkq/pending": case "rtkq/resolved": { // Simulate separate RTK slice reducers with combined reducer pattern return { ...state, api: { queries: updateQueries(state.api.queries, action), provided: updateProvided(state.api.provided, action), subscriptions: updateSubscriptions(state.api.subscriptions, action) } } } default: return state } } const createImmerReducer = produce => { const immerReducer = (state = createInitialState(), action) => produce(state, draft => { switch (action.type) { case "test/addItem": draft.largeArray.push(action.payload) break case "test/removeItem": draft.largeArray.splice(action.payload, 1) break case "test/filterItem": { const keepPercentage = action.payload / 10 const length = state.largeArray.length draft.largeArray = draft.largeArray.filter( (item, i) => i / length < action.payload ) break } case "test/updateItem": { const item = draft.largeArray.find( item => item.id === action.payload.id ) item.value = action.payload.value item.nested.data = action.payload.nestedData break } case "test/updateLargeObject1": { draft.largeObject1[`propertyAdded${action.payload.value}`] = { id: action.payload.value } break } case "test/updateLargeObject2": { draft.largeObject2[`propertyAdded${action.payload.value}`] = { id: action.payload.value } break } case "test/concatArray": { const length = state.largeArray.length const newArray = action.payload.concat(state.largeArray) newArray.length = length draft.largeArray = newArray break } case "test/mapNested": { // Extract nested data draft.otherData = draft.largeArray.map(item => item.nested) break } case "test/updateHighIndex": { const item = draft.largeArray.find( item => item.id === action.payload.id ) if (item) { item.value = action.payload.value item.nested.data = action.payload.nestedData } break } case "test/updateMultiple": { action.payload.forEach(update => { const item = draft.largeArray.find(item => item.id === update.id) if (item) { item.value = update.value item.nested.data = update.nestedData } }) break } case "test/removeHighIndex": { const indexToRemove = draft.largeArray.findIndex( item => item.id === action.payload ) if (indexToRemove !== -1) { draft.largeArray.splice(indexToRemove, 1) } break } case "test/sortByIdReverse": { draft.largeArray.sort((a, b) => b.id - a.id) break } case "test/reverseArray": { draft.largeArray.reverse() break } case "rtkq/pending": { // Simulate separate RTK slice reducers with combined reducer pattern const cacheKey = action.payload.cacheKey draft.api.queries[cacheKey] = { id: action.payload.id, status: "pending", data: undefined } draft.api.provided.keys[cacheKey] = {} draft.api.subscriptions[cacheKey] = { [action.payload.requestId]: { pollingInterval: 0, skipPollingIfUnfocused: false } } break } case "rtkq/resolved": { const cacheKey = action.payload.cacheKey draft.api.queries[cacheKey].status = "fulfilled" draft.api.queries[cacheKey].data = action.payload.data // provided and subscriptions don't change on resolved break } } }) return immerReducer } function mapValues(obj, fn) { const result = {} for (const key in obj) { result[key] = fn(obj[key]) } return result } const reducers = { vanilla: vanillaReducer, ...mapValues(immerProducers, createImmerReducer) } const freeze = [false, true] function createBenchmarks() { // All single-operation benchmarks (fresh state each time) for (const action in actions) { summary(function() { bench(`$action: $version (freeze: $freeze)`, function*(args) { const version = args.get("version") const freeze = args.get("freeze") const action = args.get("action") const initialState = createInitialState() function benchMethod() { setAutoFreezes[version](freeze) setStrictIteration[version](false) setEnableArrayMethods[version]() for (let i = 0; i < MAX; i++) { reducers[version](initialState, actions[action](i)) } setAutoFreezes[version](false) } yield benchMethod }).args({ version: Object.keys(reducers), freeze, action: [action] }) }) } // State reuse benchmarks (tests performance on frozen/evolved state) const reuseActions = [ "update", "update-high", "remove", "remove-high", "update-largeObject1", "update-largeObject2" ] for (const action of reuseActions) { summary(function() { bench(`$action-reuse: $version (freeze: $freeze)`, function*(args) { const version = args.get("version") const freeze = args.get("freeze") const action = args.get("action") function benchMethod() { setAutoFreezes[version](freeze) setStrictIteration[version](false) setEnableArrayMethods[version]() let currentState = createInitialState() // Perform multiple operations on the same evolving state for (let i = 0; i < BENCHMARK_CONFIG.reuseStateIterations; i++) { currentState = reducers[version](currentState, actions[action](i)) } setAutoFreezes[version](false) } yield benchMethod }).args({ version: Object.keys(reducers), freeze, action: [action] }) }) } // Mixed operations sequence benchmark summary(function() { bench(`mixed-sequence: $version (freeze: $freeze)`, function*(args) { const version = args.get("version") const freeze = args.get("freeze") function benchMethod() { setAutoFreezes[version](freeze) setStrictIteration[version](false) setEnableArrayMethods[version]() let state = createInitialState() // Perform a sequence of different operations (typical workflow) state = reducers[version](state, actions.add(1)) state = reducers[version](state, actions.update(getValidId())) state = reducers[version](state, actions["update-high"](2)) state = reducers[version](state, actions["update-multiple"](3)) state = reducers[version](state, actions.remove(getValidIndex())) setAutoFreezes[version](false) } yield benchMethod }).args({ version: Object.keys(reducers), freeze }) }) // RTKQ-style benchmark - executes multiple reducer calls in sequence summary(function() { bench(`rtkq-sequence: $version (freeze: $freeze)`, function*(args) { const version = args.get("version") const freeze = args.get("freeze") function benchMethod() { setAutoFreezes[version](freeze) setStrictIteration[version](false) setEnableArrayMethods[version]() let state = createInitialState() // Use smaller array size for RTKQ benchmark due to exponential scaling // 100 items = ~15ms, 200 items = ~32ms, so 10000 would be impractical const arraySize = 100 // Phase 1: Execute all pending actions for (let i = 0; i < arraySize; i++) { state = reducers[version](state, rtkqPending(i)) } // Phase 2: Execute all resolved actions for (let i = 0; i < arraySize; i++) { state = reducers[version](state, rtkqResolved(i)) } setAutoFreezes[version](false) } yield benchMethod }).args({ version: Object.keys(reducers), freeze }) }) } // Summary table functionality function extractBenchmarkData(benchmarks) { const data = [] for (const trial of benchmarks) { for (const run of trial.runs) { if (run.error || !run.stats) continue // Parse benchmark name to extract scenario, version, and freeze setting // Expected format: "scenario: version (freeze: true/false)" const match = run.name.match( /^(.+?):\s*(.+?)\s*\(freeze:\s*(true|false)\)$/ ) if (!match) continue const [, scenario, version, freeze] = match const freezeIndicator = freeze === "true" ? "f+" : "f-" const versionKey = `${version.trim()}|${freezeIndicator}` data.push({ scenario: scenario.trim(), version: version.trim(), freeze: freeze === "true", freezeIndicator, versionKey, avgTime: run.stats.avg, stats: run.stats }) } } return data } function organizeBenchmarkMatrix(data) { const matrix = {} const scenarios = new Set() const versions = new Set() // Organize data into matrix structure for (const item of data) { scenarios.add(item.scenario) versions.add(item.versionKey) if (!matrix[item.scenario]) { matrix[item.scenario] = {} } matrix[item.scenario][item.versionKey] = { avgTime: item.avgTime, stats: item.stats } } return { matrix, scenarios: Array.from(scenarios).sort(), versions: Array.from(versions).sort() } } function calculateRelativePerformanceAndRankings(matrix, scenarios, versions) { const relativeData = {} const rankings = {} for (const scenario of scenarios) { const scenarioData = matrix[scenario] || {} const validVersions = versions.filter(v => scenarioData[v]) if (validVersions.length === 0) continue // Find fastest time for this scenario const times = validVersions.map(v => ({ version: v, time: scenarioData[v].avgTime })) times.sort((a, b) => a.time - b.time) const fastestTime = times[0].time // Calculate relative performance and rankings relativeData[scenario] = {} rankings[scenario] = {} times.forEach((item, index) => { const multiplier = item.time / fastestTime relativeData[scenario][item.version] = multiplier rankings[scenario][item.version] = index + 1 }) } return {relativeData, rankings} } function formatTime(nanoseconds) { // Use similar formatting to Mitata's $.time function, but more compact if (nanoseconds < 1) return `${(nanoseconds * 1e3).toFixed(1)}ps` if (nanoseconds < 1e3) return `${nanoseconds.toFixed(1)}ns` let ns = nanoseconds / 1000 if (ns < 1e3) return `${ns.toFixed(1)}µs` ns /= 1000 if (ns < 1e3) return `${ns.toFixed(1)}ms` ns /= 1000 if (ns < 1e3) return `${ns.toFixed(1)}s` return `${ns.toFixed(1)}s` } function formatRanking(rank) { const suffixes = ["th", "st", "nd", "rd"] const suffix = rank >= 11 && rank <= 13 ? "th" : suffixes[rank % 10] || "th" return `${rank}${suffix}` } function formatMultiplier(relative) { if (relative === 1) return "1.0x" // If the multiplier is 4+ digits (1000+), don't show decimals if (relative >= 1000) { return `${Math.round(relative)}x` } return `${relative.toFixed(1)}x` } function shortenVersionName(versionName) { // Special case common long version names to save space const shortNames = { immer10Perf: "i10Perf", immer10: "i10", immer5: "i5", immer6: "i6", immer7: "i7", immer8: "i8", immer9: "i9", mutativeCompat: "mutatv-c", mutative: "mutatv", structura: "struct", vanilla: "vanilla" } return shortNames[versionName] || versionName } function formatScenarioName(scenario, maxWidth) { // If the scenario contains hyphens and is too long, split on hyphens // and display on multiple lines within the cell if (scenario.includes("-") && scenario.length > maxWidth) { const parts = scenario.split("-") return parts } // For non-hyphenated scenarios, truncate if needed if (scenario.length > maxWidth) { return [scenario.substring(0, maxWidth - 2) + ".."] } return [scenario] } function printSummaryTable( matrix, scenarios, versions, relativeData, rankings ) { console.log("\n") console.log("=".repeat(80)) console.log("BENCHMARK SUMMARY TABLE") console.log("=".repeat(80)) if (scenarios.length === 0 || versions.length === 0) { console.log("No benchmark data available for summary table.") return } // Parse version keys to get version names and freeze indicators const versionInfo = versions.map(v => { const [versionName, freezeIndicator] = v.split("|") const shortName = shortenVersionName(versionName) return { key: v, name: shortName, freeze: freezeIndicator, originalName: versionName } }) // Fixed column widths for consistent alignment - 9 chars content + separators const scenarioWidth = 9 const versionWidth = 8 // Print header with 9-char content + padding let header = "┌" + "─".repeat(scenarioWidth + 2) for (let i = 0; i < versions.length; i++) { header += "┬" + "─".repeat(versionWidth) } header += "┐" console.log(header) // Print column headers - version names let headerRow1 = "│ " + "Scenario".padEnd(scenarioWidth) + " " for (const vInfo of versionInfo) { headerRow1 += "│" + vInfo.name.padEnd(versionWidth) } headerRow1 += "│" console.log(headerRow1) // Print column headers - freeze indicators let headerRow2 = "│ " + "".padEnd(scenarioWidth) + " " for (const vInfo of versionInfo) { headerRow2 += "│" + vInfo.freeze.padEnd(versionWidth) } headerRow2 += "│" console.log(headerRow2) // Print separator let separator = "├" + "─".repeat(scenarioWidth + 2) for (let i = 0; i < versions.length; i++) { separator += "┼" + "─".repeat(versionWidth) } separator += "┤" console.log(separator) // Print data rows (now 3+ lines per scenario depending on scenario name length) for (const scenario of scenarios) { const scenarioData = matrix[scenario] || {} // Format scenario name, potentially splitting on hyphens const scenarioParts = formatScenarioName(scenario, scenarioWidth) const maxLines = Math.max(3, scenarioParts.length) // At least 3 lines for data // Print all lines for this scenario for (let lineIndex = 0; lineIndex < maxLines; lineIndex++) { let row = "│ " // Scenario column content if (lineIndex < scenarioParts.length) { row += scenarioParts[lineIndex].padEnd(scenarioWidth) } else { row += "".padEnd(scenarioWidth) } row += " " // Version columns content for (const version of versions) { let cellContent = "" if (lineIndex === 0) { // First line: absolute times const data = scenarioData[version] let timeStr = data ? formatTime(data.avgTime) : "N/A" if (timeStr.length > versionWidth) { timeStr = timeStr.substring(0, versionWidth - 1) + "…" } cellContent = timeStr } else if (lineIndex === 1) { // Second line: relative performance multipliers const relative = relativeData[scenario]?.[version] if (relative) { cellContent = formatMultiplier(relative) } else { cellContent = "N/A" } if (cellContent.length > versionWidth) { cellContent = cellContent.substring(0, versionWidth - 1) + "…" } } else if (lineIndex === 2) { // Third line: rankings const ranking = rankings[scenario]?.[version] if (ranking) { cellContent = `(${formatRanking(ranking)})` } } // Lines beyond 2 are empty for version columns row += "│" + cellContent.padEnd(versionWidth) } row += "│" console.log(row) } // Add separator between scenarios (except for last one) if (scenario !== scenarios[scenarios.length - 1]) { let rowSep = "├" + "─".repeat(scenarioWidth + 2) for (let i = 0; i < versions.length; i++) { rowSep += "┼" + "─".repeat(versionWidth) } rowSep += "┤" console.log(rowSep) } } // Print footer let footer = "└" + "─".repeat(scenarioWidth + 2) for (let i = 0; i < versions.length; i++) { footer += "┴" + "─".repeat(versionWidth) } footer += "┘" console.log(footer) console.log("\nNotes:") console.log("- f+ = freeze enabled, f- = freeze disabled") console.log("- Line 1: absolute execution time") console.log("- Line 2: relative performance multiplier") console.log("- Line 3: ranking (1st = fastest, 2nd = second fastest, etc.)") console.log("- 1.00x indicates the fastest version for that scenario") } // Performance improvement analysis between immer10Perf and immer10 (freeze: true) function calculateImmer10PerfImprovement(matrix, scenarios) { const baselineKey = "immer10|f+" const improvedKey = "immer10Perf|f+" const improvements = [] for (const scenario of scenarios) { const scenarioData = matrix[scenario] || {} const baselineData = scenarioData[baselineKey] const improvedData = scenarioData[improvedKey] if (baselineData && improvedData) { const baselineTime = baselineData.avgTime const improvedTime = improvedData.avgTime // Calculate percentage improvement: ((baseline - improved) / baseline) * 100 // Positive = improvement, negative = regression const improvement = ((baselineTime - improvedTime) / baselineTime) * 100 improvements.push({ scenario, baselineTime, improvedTime, improvement }) } } if (improvements.length === 0) { return null } const improvementValues = improvements.map(i => i.improvement) const minImprovement = Math.min(...improvementValues) const maxImprovement = Math.max(...improvementValues) const avgImprovement = improvementValues.reduce((sum, val) => sum + val, 0) / improvementValues.length return { improvements, stats: { min: minImprovement, max: maxImprovement, avg: avgImprovement, count: improvements.length } } } // Calculate overall version scores using geometric mean of relative performance function calculateOverallVersionScores(relativeData, scenarios, versions) { const versionScores = [] for (const version of versions) { const multipliers = [] // Collect all relative performance multipliers for this version for (const scenario of scenarios) { const relative = relativeData[scenario]?.[version] if (relative && relative > 0) { multipliers.push(relative) } } if (multipliers.length === 0) continue // Calculate geometric mean: nth root of product of all values // For performance data, geometric mean is more appropriate than arithmetic mean const product = multipliers.reduce((prod, val) => prod * val, 1) const geometricMean = Math.pow(product, 1 / multipliers.length) versionScores.push({ version, geometricMean, scenarioCount: multipliers.length }) } // Sort by geometric mean (lower is better - closer to 1.0x means consistently fast) versionScores.sort((a, b) => a.geometricMean - b.geometricMean) // Add rankings versionScores.forEach((score, index) => { score.rank = index + 1 }) return versionScores } function printImmer10PerfComparison(improvementData) { console.log("\n") console.log("=".repeat(80)) console.log("IMMER10PERF vs IMMER10 PERFORMANCE COMPARISON (freeze: true)") console.log("=".repeat(80)) if (!improvementData) { console.log( "No comparable data found between immer10Perf and immer10 (freeze: true)" ) return } const {stats, improvements} = improvementData console.log(`\nSummary Statistics (${stats.count} scenarios):`) console.log( ` Average Improvement: ${stats.avg >= 0 ? "+" : ""}${stats.avg.toFixed( 1 )}%` ) console.log( ` Best Improvement: ${stats.max >= 0 ? "+" : ""}${stats.max.toFixed( 1 )}%` ) console.log( ` Worst Improvement: ${stats.min >= 0 ? "+" : ""}${stats.min.toFixed( 1 )}%` ) // Show per-scenario breakdown console.log("\nPer-Scenario Breakdown:") console.log( "┌─────────────────────┬──────────────┬──────────────┬─────────────┐" ) console.log( "│ Scenario │ immer10 │ immer10Perf │ Improvement │" ) console.log( "├─────────────────────┼──────────────┼──────────────┼─────────────┤" ) // Sort by improvement (best first) const sortedImprovements = [...improvements].sort( (a, b) => b.improvement - a.improvement ) for (const item of sortedImprovements) { const scenario = item.scenario.padEnd(19).substring(0, 19) const baseline = formatTime(item.baselineTime).padStart(12) const improved = formatTime(item.improvedTime).padStart(12) const improvement = `${ item.improvement >= 0 ? "+" : "" }${item.improvement.toFixed(1)}%`.padStart(11) console.log(`│ ${scenario} │ ${baseline} │ ${improved} │ ${improvement} │`) } console.log( "└─────────────────────┴──────────────┴──────────────┴─────────────┘" ) // Interpretation if (stats.avg > 0) { console.log( `\n✓ immer10Perf shows an average ${stats.avg.toFixed( 1 )}% performance improvement over immer10` ) } else { console.log( `\n⚠ immer10Perf shows an average ${Math.abs(stats.avg).toFixed( 1 )}% performance regression vs immer10` ) } } function printOverallVersionRankings(versionScores) { console.log("\n") console.log("=".repeat(80)) console.log( "OVERALL VERSION RANKINGS (Geometric Mean of Relative Performance)" ) console.log("=".repeat(80)) if (versionScores.length === 0) { console.log("No version data available for overall rankings.") return } console.log("\n┌──────┬─────────────────────┬─────────────────┬───────────┐") console.log("│ Rank │ Version │ Geometric Mean │ Scenarios │") console.log("├──────┼─────────────────────┼─────────────────┼───────────┤") for (const score of versionScores) { const [versionName, freezeIndicator] = score.version.split("|") const shortName = shortenVersionName(versionName) const displayName = `${shortName} (${freezeIndicator})` .padEnd(19) .substring(0, 19) const rank = score.rank.toString().padStart(4) const geoMean = `${score.geometricMean.toFixed(2)}x`.padStart(15) const scenarios = score.scenarioCount.toString().padStart(9) console.log(`│ ${rank} │ ${displayName} │ ${geoMean} │ ${scenarios} │`) } console.log("└──────┴─────────────────────┴─────────────────┴───────────┘") } function printBenchmarkSummaryTable(benchmarks) { try { const data = extractBenchmarkData(benchmarks) if (data.length === 0) { console.log("\nNo valid benchmark data found for summary table.") return } const {matrix, scenarios, versions} = organizeBenchmarkMatrix(data) const {relativeData, rankings} = calculateRelativePerformanceAndRankings( matrix, scenarios, versions ) // Print main summary table printSummaryTable(matrix, scenarios, versions, relativeData, rankings) // Print immer10Perf vs immer10 comparison const improvementData = calculateImmer10PerfImprovement(matrix, scenarios) printImmer10PerfComparison(improvementData) // Print overall version rankings const versionScores = calculateOverallVersionScores( relativeData, scenarios, versions ) printOverallVersionRankings(versionScores) } catch (error) { console.error("\nError generating summary table:", error.message) } } async function main() { createBenchmarks() const results = await run() // Generate and print summary table printBenchmarkSummaryTable(results.benchmarks) process.exit(0) } main() ================================================ FILE: perf-testing/immutability-profiling.mjs ================================================ /* eslint-disable no-inner-declarations */ import {produce, setAutoFreeze, enableArrayMethods} from "../dist/immer.mjs" enableArrayMethods() // ============================================================================ // CONFIGURATION // ============================================================================ const PROFILING_CONFIG = { // How many times to run each scenario (can be overridden via CLI) iterations: parseInt(process.argv[2]) || 100, // Which scenarios to run scenarios: [ // Single operations "add", "remove", "update", "update-high", "update-multiple", "remove-high", "update-largeObject1", "update-largeObject2", "concat", "mapNested", "sortById-reverse", "reverse-array", // Reuse scenarios (state evolution) "update-reuse", "update-high-reuse", "remove-reuse", "remove-high-reuse", "update-largeObject1-reuse", "update-largeObject2-reuse", // Complex sequences "mixed-sequence", "rtkq-sequence" ] } const BENCHMARK_CONFIG = { arraySize: 100, nestedArraySize: 10, largeObjectSize1: 1000, largeObjectSize2: 3000, multiUpdateCount: 5, reuseStateIterations: 10 } const MAX = 1 // ============================================================================ // UTILITY FUNCTIONS // ============================================================================ function createInitialState(arraySize = BENCHMARK_CONFIG.arraySize) { const initialState = { largeArray: Array.from({length: arraySize}, (_, i) => ({ id: i, value: Math.random(), nested: {key: `key-${i}`, data: Math.random()}, moreNested: { items: Array.from( {length: BENCHMARK_CONFIG.nestedArraySize}, (_, i) => ({id: i, name: String(i)}) ) } })), otherData: Array.from({length: arraySize}, (_, i) => ({ id: i, name: `name-${i}`, isActive: i % 2 === 0 })), largeObject1: createLargeObject(BENCHMARK_CONFIG.largeObjectSize1), largeObject2: createLargeObject(BENCHMARK_CONFIG.largeObjectSize2), api: { queries: {}, provided: { keys: {} }, subscriptions: {} } } return initialState } function createLargeObject(size = 100) { const obj = {} for (let i = 0; i < size; i++) { obj[`property${i}`] = { id: i, value: Math.random(), name: `item-${i}`, active: i % 2 === 0 } } return obj } const getValidIndex = (arraySize = BENCHMARK_CONFIG.arraySize) => { return Math.min(arraySize - 2, Math.max(0, arraySize - 2)) } const getValidId = (arraySize = BENCHMARK_CONFIG.arraySize) => { return Math.min(arraySize - 2, Math.max(0, arraySize - 2)) } // ============================================================================ // ACTION CREATORS // ============================================================================ const add = index => ({ type: "test/addItem", payload: {id: index, value: index, nested: {data: index}} }) const remove = index => ({type: "test/removeItem", payload: index}) const update = index => ({ type: "test/updateItem", payload: {id: index, value: index, nestedData: index} }) const updateLargeObject1 = index => ({ type: "test/updateLargeObject1", payload: {value: index} }) const updateLargeObject2 = index => ({ type: "test/updateLargeObject2", payload: {value: index} }) const concat = index => ({ type: "test/concatArray", payload: Array.from({length: 500}, (_, i) => ({id: i, value: index})) }) const mapNested = () => ({ type: "test/mapNested" }) const updateHigh = index => ({ type: "test/updateHighIndex", payload: { id: Math.floor(BENCHMARK_CONFIG.arraySize * 0.8) + (index % Math.floor(BENCHMARK_CONFIG.arraySize * 0.2)), value: index, nestedData: index } }) const updateMultiple = index => ({ type: "test/updateMultiple", payload: Array.from({length: BENCHMARK_CONFIG.multiUpdateCount}, (_, i) => ({ id: (index + i) % BENCHMARK_CONFIG.arraySize, value: index + i, nestedData: index + i })) }) const removeHigh = index => ({ type: "test/removeHighIndex", payload: Math.floor(BENCHMARK_CONFIG.arraySize * 0.8) + (index % Math.floor(BENCHMARK_CONFIG.arraySize * 0.2)) }) const sortByIdReverse = () => ({ type: "test/sortByIdReverse" }) const reverseArray = () => ({ type: "test/reverseArray" }) const rtkqPending = index => ({ type: "rtkq/pending", payload: { cacheKey: `some("test-${index}-")`, requestId: `req-${index}`, id: `test-${index}-` } }) const rtkqResolved = index => ({ type: "rtkq/resolved", payload: { cacheKey: `some("test-${index}-")`, requestId: `req-${index}`, id: `test-${index}-`, data: `test-${index}-1` } }) const actions = { add, remove, update, concat, mapNested, "update-largeObject1": updateLargeObject1, "update-largeObject2": updateLargeObject2, "update-high": updateHigh, "update-multiple": updateMultiple, "remove-high": removeHigh, "sortById-reverse": sortByIdReverse, "reverse-array": reverseArray } // ============================================================================ // REDUCER IMPLEMENTATION // ============================================================================ const immerReducer = (state = createInitialState(), action) => produce(state, draft => { switch (action.type) { case "test/addItem": draft.largeArray.push(action.payload) break case "test/removeItem": draft.largeArray.splice(action.payload, 1) break case "test/updateItem": { const item = draft.largeArray.find( item => item.id === action.payload.id ) item.value = action.payload.value item.nested.data = action.payload.nestedData break } case "test/updateLargeObject1": { draft.largeObject1[`propertyAdded${action.payload.value}`] = { id: action.payload.value } break } case "test/updateLargeObject2": { draft.largeObject2[`propertyAdded${action.payload.value}`] = { id: action.payload.value } break } case "test/concatArray": { const length = state.largeArray.length const newArray = action.payload.concat(state.largeArray) newArray.length = length draft.largeArray = newArray break } case "test/mapNested": { draft.otherData = draft.largeArray.map(item => item.nested) break } case "test/updateHighIndex": { const item = draft.largeArray.find( item => item.id === action.payload.id ) if (item) { item.value = action.payload.value item.nested.data = action.payload.nestedData } break } case "test/updateMultiple": { action.payload.forEach(update => { const item = draft.largeArray.find(item => item.id === update.id) if (item) { item.value = update.value item.nested.data = update.nestedData } }) break } case "test/removeHighIndex": { const indexToRemove = draft.largeArray.findIndex( item => item.id === action.payload ) if (indexToRemove !== -1) { draft.largeArray.splice(indexToRemove, 1) } break } case "test/sortByIdReverse": { draft.largeArray.sort((a, b) => b.id - a.id) break } case "test/reverseArray": { draft.largeArray.reverse() break } case "rtkq/pending": { const cacheKey = action.payload.cacheKey draft.api.queries[cacheKey] = { id: action.payload.id, status: "pending", data: undefined } draft.api.provided.keys[cacheKey] = {} draft.api.subscriptions[cacheKey] = { [action.payload.requestId]: { pollingInterval: 0, skipPollingIfUnfocused: false } } break } case "rtkq/resolved": { const cacheKey = action.payload.cacheKey draft.api.queries[cacheKey].status = "fulfilled" draft.api.queries[cacheKey].data = action.payload.data break } } }) // ============================================================================ // SCENARIO FUNCTIONS // ============================================================================ // Single operation scenarios - execute once function scenario_add() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions.add(j)) } } function scenario_remove() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions.remove(j)) } } function scenario_update() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions.update(j)) } } function scenario_update_high() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions["update-high"](j)) } } function scenario_update_multiple() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions["update-multiple"](j)) } } function scenario_remove_high() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions["remove-high"](j)) } } function scenario_update_largeObject1() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions["update-largeObject1"](j)) } } function scenario_update_largeObject2() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions["update-largeObject2"](j)) } } function scenario_concat() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions.concat(j)) } } function scenario_mapNested() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions.mapNested()) } } function scenario_sortById_reverse() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions["sortById-reverse"]()) } } function scenario_reverse_array() { const initialState = createInitialState() for (let j = 0; j < MAX; j++) { immerReducer(initialState, actions["reverse-array"]()) } } // Reuse scenarios - execute full state evolution sequence once function scenario_update_reuse() { let currentState = createInitialState() for (let j = 0; j < BENCHMARK_CONFIG.reuseStateIterations; j++) { currentState = immerReducer(currentState, actions.update(j)) } } function scenario_update_high_reuse() { let currentState = createInitialState() for (let j = 0; j < BENCHMARK_CONFIG.reuseStateIterations; j++) { currentState = immerReducer(currentState, actions["update-high"](j)) } } function scenario_remove_reuse() { let currentState = createInitialState() for (let j = 0; j < BENCHMARK_CONFIG.reuseStateIterations; j++) { currentState = immerReducer(currentState, actions.remove(j)) } } function scenario_remove_high_reuse() { let currentState = createInitialState() for (let j = 0; j < BENCHMARK_CONFIG.reuseStateIterations; j++) { currentState = immerReducer(currentState, actions["remove-high"](j)) } } function scenario_update_largeObject1_reuse() { let currentState = createInitialState() for (let j = 0; j < BENCHMARK_CONFIG.reuseStateIterations; j++) { currentState = immerReducer(currentState, actions["update-largeObject1"](j)) } } function scenario_update_largeObject2_reuse() { let currentState = createInitialState() for (let j = 0; j < BENCHMARK_CONFIG.reuseStateIterations; j++) { currentState = immerReducer(currentState, actions["update-largeObject2"](j)) } } // Complex sequence scenarios - execute full sequence once function scenario_mixed_sequence() { let state = createInitialState() state = immerReducer(state, actions.add(1)) state = immerReducer(state, actions.update(getValidId())) state = immerReducer(state, actions["update-high"](2)) state = immerReducer(state, actions["update-multiple"](3)) state = immerReducer(state, actions.remove(getValidIndex())) } function scenario_rtkq_sequence() { let state = createInitialState() const arraySize = 100 // Phase 1: Execute all pending actions for (let j = 0; j < arraySize; j++) { state = immerReducer(state, rtkqPending(j)) } // Phase 2: Execute all resolved actions for (let j = 0; j < arraySize; j++) { state = immerReducer(state, rtkqResolved(j)) } } // ============================================================================ // SCENARIO REGISTRY // ============================================================================ const scenarios = { // Single operations add: scenario_add, remove: scenario_remove, update: scenario_update, "update-high": scenario_update_high, "update-multiple": scenario_update_multiple, "remove-high": scenario_remove_high, "update-largeObject1": scenario_update_largeObject1, "update-largeObject2": scenario_update_largeObject2, concat: scenario_concat, mapNested: scenario_mapNested, "sortById-reverse": scenario_sortById_reverse, "reverse-array": scenario_reverse_array, // Reuse scenarios "update-reuse": scenario_update_reuse, "update-high-reuse": scenario_update_high_reuse, "remove-reuse": scenario_remove_reuse, "remove-high-reuse": scenario_remove_high_reuse, "update-largeObject1-reuse": scenario_update_largeObject1_reuse, "update-largeObject2-reuse": scenario_update_largeObject2_reuse, // Complex sequences "mixed-sequence": scenario_mixed_sequence, "rtkq-sequence": scenario_rtkq_sequence } // ============================================================================ // MAIN EXECUTION // ============================================================================ function main() { // Set freeze to true (default Immer behavior) setAutoFreeze(true) console.log("=".repeat(80)) console.log("IMMER PROFILING SCRIPT (freeze: true)") console.log("=".repeat(80)) console.log(`Iterations per scenario: ${PROFILING_CONFIG.iterations}`) console.log(`Total scenarios: ${PROFILING_CONFIG.scenarios.length}`) console.log("=".repeat(80)) console.log() let completed = 0 for (const scenarioName of PROFILING_CONFIG.scenarios) { const scenarioFn = scenarios[scenarioName] if (!scenarioFn) { console.log(`⚠ Skipping unknown scenario: ${scenarioName}`) continue } const start = performance.now() // Driver loop handles iterations for (let i = 0; i < PROFILING_CONFIG.iterations; i++) { scenarioFn() } const duration = performance.now() - start completed++ console.log( `[${completed}/${ PROFILING_CONFIG.scenarios.length }] ✓ ${scenarioName} - ${duration.toFixed(2)}ms` ) } console.log() console.log("=".repeat(80)) console.log("Profiling complete!") console.log("=".repeat(80)) } main() ================================================ FILE: perf-testing/package.json ================================================ { "name": "immer-perf-testing", "private": true, "version": "0.0.0", "type": "module", "scripts": { "benchmark": "cross-env NO_COLOR=true node --expose-gc --enable-source-maps dist/immutability-benchmarks.js", "build": "rolldown -c rolldown.config.js", "profile": "node --cpu-prof --expose-gc dist/immutability-benchmarks.js", "analyze-profile": "node read-cpuprofile.js", "build-immer": "cd .. && yarn build", "build-with-latest": "yarn build-immer && yarn build", "build-and-benchmark": "yarn build-with-latest && yarn benchmark", "build-and-profile": "yarn build-with-latest && yarn profile" }, "dependencies": { "cross-env": "^7.0.3", "immer10": "npm:immer@10", "immer5": "npm:immer@5", "immer6": "npm:immer@6", "immer7": "npm:immer@7", "immer8": "npm:immer@8", "immer9": "npm:immer@9", "limu": "^4.1.1", "mitata": "^1.0.34", "mutative": "^1.3.0", "mutative-compat": "^0.1.2", "pprof-format": "^2.2.1", "source-map": "^0.7.4", "source-map-support": "^0.5.21", "structurajs": "^0.12.6" }, "devDependencies": { "rolldown": "1.0.0-beta.23" } } ================================================ FILE: perf-testing/read-cpuprofile.js ================================================ import fs from "fs" import {SourceMapConsumer} from "source-map" let profileName = process.argv[2] if (!profileName) { const cpuProfiles = fs.readdirSync(".").filter(f => f.endsWith(".cpuprofile")) const [lastProfile] = cpuProfiles.slice(-1) if (!lastProfile) { console.error("Usage: node read-cpuprofile.js ") process.exit(1) } console.log("Using latest profile: ", lastProfile) profileName = lastProfile } const profile = JSON.parse(fs.readFileSync(profileName, "utf8")) // Load multiple sourcemaps for better function name resolution const sourceMapConsumers = new Map() // Load main bundled sourcemap try { const mainSourceMapPath = "dist/immutability-benchmarks.js.map" if (fs.existsSync(mainSourceMapPath)) { const sourceMapContent = fs.readFileSync(mainSourceMapPath, "utf8") const consumer = await SourceMapConsumer.with( sourceMapContent, null, consumer => consumer ) sourceMapConsumers.set("main", consumer) } } catch (error) { console.warn("Could not load main sourcemap:", error.message) } const cjsMinMap = "immer.cjs.production.min.js.map" const cjsProdMap = "cjs/immer.cjs.production.js.map" const immerVersionMaps = { 5: cjsMinMap, 6: cjsMinMap, 7: cjsMinMap, 8: cjsMinMap, 9: cjsMinMap, 10: cjsProdMap, "10Perf": cjsProdMap } // Load individual Immer version sourcemaps for (const [version, mapName] of Object.entries(immerVersionMaps)) { try { const immerParentPath = version === "10Perf" ? ".." : `./node_modules/immer${version}` const sourcemapPath = `${immerParentPath}/dist/${mapName}` if (fs.existsSync(sourcemapPath)) { const sourceMapContent = fs.readFileSync(sourcemapPath, "utf8") const consumer = await SourceMapConsumer.with( sourceMapContent, null, consumer => consumer ) sourceMapConsumers.set(`v${version}`, consumer) console.log(`Loaded sourcemap for Immer v${version}`) } } catch (error) { console.warn( `Could not load sourcemap for Immer v${version}:`, error.message ) } } console.log(`Loaded ${sourceMapConsumers.size} sourcemaps total\n`) // Function to extract Immer version from source path function extractImmerVersion(sourcePath) { if (!sourcePath) return "unknown" // Match patterns like: immer@7.0.15, immer@8.0.1, etc. const versionMatch = sourcePath.match(/immer@(\d+(?:\.\d+)*)/) if (versionMatch) return `v${versionMatch[1]}` // Match patterns like: immer5, immer6, immer7, etc. const simpleVersionMatch = sourcePath.match(/immer(\d+(?:Perf)?)/) if (simpleVersionMatch) return `v${simpleVersionMatch[1]}` // Check for local builds if (sourcePath.includes("../../dist")) return "v10Perf" return "unknown" } // Function to categorize function types for better analysis function categorizeFunctionType(functionName, sourcePath, location) { const lowerName = functionName.toLowerCase() const lowerSource = (sourcePath || "").toLowerCase() // Node.js internal functions const nodeInternals = [ "requirebuiltin", "compileforiternalloader", "writegeneric", "writestream", "getheapstatistics", "open", "read", "write", "stat", "close", "readdir", "createreadstream", "createwritestream", "emitwarning", "process", "nextick", "setimmediate", "settimeout", "clearimmediate", "cleartimeout" ] if (nodeInternals.some(internal => lowerName.includes(internal))) { return "node-internal" } // V8 engine functions const v8Functions = [ "get", "set", "value", "call", "apply", "bind", "construct", "defineProperty", "getownpropertydescriptor", "hasownproperty" ] if (v8Functions.some(v8fn => lowerName === v8fn) && location === "unknown") { return "v8-internal" } // Benchmark/test code const benchmarkFunctions = [ "benchmethod", "main", "immerreducer", "vanillareducer", "createimmerreducer", "createbenchmarks", "run", "bench", "group", "summary" ] if (benchmarkFunctions.some(bench => lowerName.includes(bench))) { return "benchmark" } // Third-party libraries (from node_modules) if ( lowerSource.includes("node_modules") || sourcePath?.includes("node_modules") ) { return "third-party" } // Immer functions if ( lowerName.includes("immer") || lowerName.includes("produce") || lowerName.includes("preparecopy") || lowerName.includes("finalize") || lowerName.includes("isdraft") || lowerName.includes("current") || lowerName.includes("proxy") ) { return "immer" } // Anonymous functions in known files if ( functionName === "(anonymous)" && (location.includes("main.mjs") || location.includes("lib.mjs")) ) { return "benchmark" } return "application" } // Enhanced minified function name mapping based on common patterns const minifiedFunctionPatterns = { // Common Immer function patterns across versions n$1: "prepareCopy", e$1: "finalize", M$2: "finalizeProperty", t$1: "isDraft", r$1: "current", o$1: "isPlainObject", i$1: "shallowCopy", a$1: "each", u$1: "readPropFromProto", s$1: "createProxy", c$1: "createProxyProxy", l$1: "markChanged", f$1: "freeze", d$1: "die" } // TODO Not sure if this actually helps function enhanceMinifiedName(functionName, version) { // Try direct pattern matching first if (minifiedFunctionPatterns[functionName]) { return minifiedFunctionPatterns[functionName] } // Try pattern matching with version-specific adjustments const basePattern = functionName.replace(/\$\d+$/, "") for (const [pattern, realName] of Object.entries(minifiedFunctionPatterns)) { if (pattern.startsWith(basePattern)) { return realName } } return functionName } // Function to resolve minified function names using appropriate sourcemap function resolveOriginalName(callFrame) { if (!callFrame.url || !callFrame.url.includes("immutability-benchmarks.js")) { return { name: callFrame.functionName || "(anonymous)", version: "unknown", location: "unknown" } } // First try main sourcemap const mainConsumer = sourceMapConsumers.get("main") if (mainConsumer) { try { const originalPosition = mainConsumer.originalPositionFor({ line: callFrame.lineNumber + 1, // V8 uses 0-based, sourcemap uses 1-based column: callFrame.columnNumber }) if (originalPosition.source) { const sourceFile = originalPosition.source.split("/").pop() || "unknown" let version = extractImmerVersion(originalPosition.source) let functionName = originalPosition.name || callFrame.functionName || "(anonymous)" const location = `${sourceFile}:${originalPosition.line}` // Enhanced version detection for better accuracy if (version === "unknown") { // Check for node_modules path pattern like ../node_modules/mitata/src/lib.mjs const nodeModulesMatch = originalPosition.source.match( /node_modules\/([^\/]+)/ ) if (nodeModulesMatch) { version = nodeModulesMatch[1] // Extract library name like "mitata" } else { version = categorizeFunctionType( functionName, originalPosition.source, location ) } } // If we detected a specific Immer version, try to get better resolution from that version's sourcemap if (version !== "unknown") { const versionConsumer = sourceMapConsumers.get(version) if (versionConsumer) { try { // For minified functions, try to resolve using the version-specific sourcemap if ( functionName.length <= 3 || /^[a-zA-Z]\$?\d*$/.test(functionName) ) { const versionPosition = versionConsumer.originalPositionFor({ line: 1, // Most minified files are single line column: callFrame.columnNumber }) if ( versionPosition.name && versionPosition.name !== functionName ) { return { name: versionPosition.name, version: version, location: `${versionPosition.source?.split("/").pop() || sourceFile}:${versionPosition.line}` } } } } catch (error) { // Continue with main sourcemap result } } } return { name: functionName, version: version, location: location } } } catch (error) { // Fallback to original name if sourcemap resolution fails } } return { name: callFrame.functionName || "(anonymous)", version: "unknown", location: "unknown" } } // Extract function call statistics const functionStats = new Map() const versionStats = new Map() // Track stats by Immer version const categoryStats = new Map() // Track stats by function category const samples = profile.samples || [] const timeDeltas = profile.timeDeltas || [] // Process samples to count function calls samples.forEach((nodeId, index) => { const node = profile.nodes[nodeId] if (node && node.callFrame) { const resolved = resolveOriginalName(node.callFrame) const fileName = node.callFrame.url || "" const sampleCount = timeDeltas[index] || 1 // Categorize the function const category = categorizeFunctionType( resolved.name, resolved.source || fileName, resolved.location ) // Create key with version info const key = `${resolved.name} [${resolved.version}] (${resolved.location})` functionStats.set(key, (functionStats.get(key) || 0) + sampleCount) // Track by version if (!versionStats.has(resolved.version)) { versionStats.set(resolved.version, new Map()) } const versionMap = versionStats.get(resolved.version) const versionKey = `${resolved.name} (${resolved.location})` versionMap.set(versionKey, (versionMap.get(versionKey) || 0) + sampleCount) // Track by category if (!categoryStats.has(category)) { categoryStats.set(category, new Map()) } const categoryMap = categoryStats.get(category) const categoryKey = `${resolved.name} [${resolved.version}] (${resolved.location})` categoryMap.set( categoryKey, (categoryMap.get(categoryKey) || 0) + sampleCount ) } }) // Show breakdown by Immer version console.log("\n\nBreakdown by Immer Version:") console.log("===========================") const sortedVersions = Array.from(versionStats.entries()) .map(([version, funcMap]) => { const totalSamples = Array.from(funcMap.values()).reduce( (sum, count) => sum + count, 0 ) return {version, totalSamples, functions: funcMap} }) .sort((a, b) => b.totalSamples - a.totalSamples) // don't log "mitata" or "node" sortedVersions .filter(sv => sv.version.startsWith("v")) .forEach(({version, totalSamples, functions}) => { if (totalSamples < 25000) return // Skip low-impact versions console.log(`\n${version}: ${totalSamples} total samples`) const topFunctions = Array.from(functions.entries()) .sort((a, b) => b[1] - a[1]) .slice(0, 20) topFunctions.forEach(([func, samples], index) => { console.log(` ${index + 1}. ${func}: ${samples} samples`) }) }) // Performance comparison between versions for key functions console.log("\n\nPerformance Comparison - Key Functions by Version:") console.log("==================================================") const keyFunctions = [ "prepareCopy", "finalize", "finalizeProperty", "each", "isPlainObject" ] keyFunctions.forEach(funcName => { console.log(`\n${funcName}:`) const versionComparison = [] versionStats.forEach((functions, version) => { let totalSamples = 0 functions.forEach((samples, func) => { if (func.toLowerCase().includes(funcName.toLowerCase())) { totalSamples += samples } }) if (totalSamples > 0) { versionComparison.push({version, samples: totalSamples}) } }) versionComparison .sort((a, b) => b.samples - a.samples) .forEach(({version, samples}) => { console.log(` ${version}: ${samples} samples`) }) }) // // Analysis by function category // console.log("\n\nBreakdown by Function Category:") // console.log("===============================") // const sortedCategories = Array.from(categoryStats.entries()) // .map(([category, funcMap]) => { // const totalSamples = Array.from(funcMap.values()).reduce( // (sum, count) => sum + count, // 0 // ) // return {category, totalSamples, functions: funcMap} // }) // .sort((a, b) => b.totalSamples - a.totalSamples) // const totalSamples = Array.from(functionStats.values()).reduce( // (sum, samples) => sum + samples, // 0 // ) // sortedCategories.forEach(({category, totalSamples: catSamples, functions}) => { // const percentage = ((catSamples / totalSamples) * 100).toFixed(1) // console.log(`\n${category}: ${catSamples} samples (${percentage}%)`) // // Show top functions in this category // const topFunctions = Array.from(functions.entries()) // .sort((a, b) => b[1] - a[1]) // .slice(0, 10) // topFunctions.forEach(([func, samples], index) => { // const funcPercentage = ((samples / catSamples) * 100).toFixed(1) // console.log( // ` ${index + // 1}. ${func}: ${samples} samples (${funcPercentage}% of category)` // ) // }) // }) // // Analysis of truly uncategorized functions // console.log("\n\nAnalysis of uncategorized functions:") // console.log("====================================") // // Get functions that are still in the 'application' category with unknown version // // These are the ones that need better categorization // const uncategorizedStats = [] // categoryStats.get("application")?.forEach((samples, funcKey) => { // if (funcKey.includes("[unknown]")) { // uncategorizedStats.push([funcKey, samples]) // } // }) // // Also check for any functions that might have been missed entirely // const versionUnknownStats = Array.from(functionStats.entries()).filter( // ([func]) => { // // Only include functions that are both version unknown AND not properly categorized // if (!func.includes("[unknown]")) return false // // Check if this function was categorized as something other than 'application' // const funcName = func.split(" [")[0] // const category = categorizeFunctionType(funcName, "", "unknown") // return category === "application" // } // ) // // Combine and deduplicate // const allUncategorized = new Map() // uncategorizedStats.forEach(([func, samples]) => { // allUncategorized.set(func, samples) // }) // versionUnknownStats.forEach(([func, samples]) => { // if (!allUncategorized.has(func)) { // allUncategorized.set(func, samples) // } // }) // const sortedUncategorized = Array.from(allUncategorized.entries()) // .sort((a, b) => b[1] - a[1]) // .slice(0, 15) // if (sortedUncategorized.length > 0) { // console.log( // "Top uncategorized functions (may need better categorization logic):" // ) // sortedUncategorized.forEach(([func, samples], index) => { // console.log(` ${index + 1}. ${func}: ${samples} samples`) // }) // const totalUncategorizedSamples = sortedUncategorized.reduce( // (sum, [, samples]) => sum + samples, // 0 // ) // const totalSamples = Array.from(functionStats.values()).reduce( // (sum, samples) => sum + samples, // 0 // ) // const uncategorizedPercentage = ( // (totalUncategorizedSamples / totalSamples) * // 100 // ).toFixed(1) // console.log( // `\nTotal uncategorized samples: ${totalUncategorizedSamples} (${uncategorizedPercentage}% of total)` // ) // } else { // console.log("All functions are properly categorized!") // } // Summary statistics console.log("\n\nSummary Statistics:") console.log("===================") const totalSamples = Array.from(functionStats.values()).reduce( (sum, samples) => sum + samples, 0 ) console.log(`Total CPU samples analyzed: ${totalSamples}`) const versionBreakdown = Array.from(versionStats.entries()) .map(([version, funcMap]) => { const samples = Array.from(funcMap.values()).reduce( (sum, count) => sum + count, 0 ) const percentage = ((samples / totalSamples) * 100).toFixed(1) return {version, samples, percentage} }) .sort((a, b) => b.samples - a.samples) console.log("\nVersion breakdown:") versionBreakdown.forEach(({version, samples, percentage}) => { if (samples < 25000) return // Skip low-impact versions console.log(` ${version}: ${samples} samples (${percentage}%)`) }) // Clean up sourcemap consumers sourceMapConsumers.forEach(consumer => { consumer.destroy() }) ================================================ FILE: perf-testing/rolldown.config.js ================================================ export default { input: "immutability-benchmarks.mjs", output: { file: "dist/immutability-benchmarks.js", sourcemap: true }, platform: "node", define: { "process.env.NODE_ENV": JSON.stringify("production") }, external: ["bun:jsc", "@mitata/counters"], resolve: { alias: { immer10Perf: "../dist/immer.mjs", immer: "../dist/immer.mjs" } } } ================================================ FILE: readme.md ================================================ # Immer [![npm](https://img.shields.io/npm/v/immer.svg)](https://www.npmjs.com/package/immer) [![Build Status](https://github.com/immerjs/immer/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/immerjs/immer/actions?query=branch%3Amain) [![Coverage Status](https://coveralls.io/repos/github/immerjs/immer/badge.svg?branch=main)](https://coveralls.io/github/immerjs/immer?branch=main) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) [![OpenCollective](https://opencollective.com/immer/backers/badge.svg)](#backers) [![OpenCollective](https://opencollective.com/immer/sponsors/badge.svg)](#sponsors) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/immerjs/immer) _Create the next immutable state tree by simply modifying the current tree_ Winner of the "Breakthrough of the year" [React open source award](https://osawards.com/react/) and "Most impactful contribution" [JavaScript open source award](https://osawards.com/javascript/) in 2019 ## Contribute using one-click online setup You can use Gitpod (a free online VSCode like IDE) for contributing online. With a single click it will launch a workspace and automatically: - clone the immer repo. - install the dependencies. - run `yarn run start`. so that you can start coding straight away. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) ## Documentation The documentation of this package is hosted at https://immerjs.github.io/immer/ ## Support Did Immer make a difference to your project? Join the open collective at https://opencollective.com/immer! ## Release notes https://github.com/immerjs/immer/releases ================================================ FILE: src/core/current.ts ================================================ import { die, isDraft, shallowCopy, each, DRAFT_STATE, set, ImmerState, isDraftable, isFrozen } from "../internal" /** Takes a snapshot of the current state of a draft and finalizes it (but without freezing). This is a great utility to print the current state during debugging (no Proxies in the way). The output of current can also be safely leaked outside the producer. */ export function current(value: T): T export function current(value: any): any { if (!isDraft(value)) die(10, value) return currentImpl(value) } function currentImpl(value: any): any { if (!isDraftable(value) || isFrozen(value)) return value const state: ImmerState | undefined = value[DRAFT_STATE] let copy: any let strict = true // Default to strict for compatibility if (state) { if (!state.modified_) return state.base_ // Optimization: avoid generating new drafts during copying state.finalized_ = true copy = shallowCopy(value, state.scope_.immer_.useStrictShallowCopy_) strict = state.scope_.immer_.shouldUseStrictIteration() } else { copy = shallowCopy(value, true) } // recurse each( copy, (key, childValue) => { set(copy, key, currentImpl(childValue)) }, strict ) if (state) { state.finalized_ = false } return copy } ================================================ FILE: src/core/finalize.ts ================================================ import { ImmerScope, DRAFT_STATE, isDraftable, NOTHING, PatchPath, each, freeze, ImmerState, isDraft, SetState, set, ArchType, getPlugin, die, revokeScope, isFrozen, get, Patch, latest, prepareCopy, getFinalValue, getValue, ProxyArrayState } from "../internal" export function processResult(result: any, scope: ImmerScope) { scope.unfinalizedDrafts_ = scope.drafts_.length const baseDraft = scope.drafts_![0] const isReplaced = result !== undefined && result !== baseDraft if (isReplaced) { if (baseDraft[DRAFT_STATE].modified_) { revokeScope(scope) die(4) } if (isDraftable(result)) { // Finalize the result in case it contains (or is) a subset of the draft. result = finalize(scope, result) } const {patchPlugin_} = scope if (patchPlugin_) { patchPlugin_.generateReplacementPatches_( baseDraft[DRAFT_STATE].base_, result, scope ) } } else { // Finalize the base draft. result = finalize(scope, baseDraft) } maybeFreeze(scope, result, true) revokeScope(scope) if (scope.patches_) { scope.patchListener_!(scope.patches_, scope.inversePatches_!) } return result !== NOTHING ? result : undefined } function finalize(rootScope: ImmerScope, value: any) { // Don't recurse in tho recursive data structures if (isFrozen(value)) return value const state: ImmerState = value[DRAFT_STATE] if (!state) { const finalValue = handleValue(value, rootScope.handledSet_, rootScope) return finalValue } // Never finalize drafts owned by another scope if (!isSameScope(state, rootScope)) { return value } // Unmodified draft, return the (frozen) original if (!state.modified_) { return state.base_ } if (!state.finalized_) { // Execute all registered draft finalization callbacks const {callbacks_} = state if (callbacks_) { while (callbacks_.length > 0) { const callback = callbacks_.pop()! callback(rootScope) } } generatePatchesAndFinalize(state, rootScope) } // By now the root copy has been fully updated throughout its tree return state.copy_ } function maybeFreeze(scope: ImmerScope, value: any, deep = false) { // we never freeze for a non-root scope; as it would prevent pruning for drafts inside wrapping objects if (!scope.parent_ && scope.immer_.autoFreeze_ && scope.canAutoFreeze_) { freeze(value, deep) } } function markStateFinalized(state: ImmerState) { state.finalized_ = true state.scope_.unfinalizedDrafts_-- } let isSameScope = (state: ImmerState, rootScope: ImmerScope) => state.scope_ === rootScope // A reusable empty array to avoid allocations const EMPTY_LOCATIONS_RESULT: (string | symbol | number)[] = [] // Updates all references to a draft in its parent to the finalized value. // This handles cases where the same draft appears multiple times in the parent, or has been moved around. export function updateDraftInParent( parent: ImmerState, draftValue: any, finalizedValue: any, originalKey?: string | number | symbol ): void { const parentCopy = latest(parent) const parentType = parent.type_ // Fast path: Check if draft is still at original key if (originalKey !== undefined) { const currentValue = get(parentCopy, originalKey, parentType) if (currentValue === draftValue) { // Still at original location, just update it set(parentCopy, originalKey, finalizedValue, parentType) return } } // Slow path: Build reverse mapping of all children // to their indices in the parent, so that we can // replace all locations where this draft appears. // We only have to build this once per parent. if (!parent.draftLocations_) { const draftLocations = (parent.draftLocations_ = new Map()) // Use `each` which works on Arrays, Maps, and Objects each(parentCopy, (key, value) => { if (isDraft(value)) { const keys = draftLocations.get(value) || [] keys.push(key) draftLocations.set(value, keys) } }) } // Look up all locations where this draft appears const locations = parent.draftLocations_.get(draftValue) ?? EMPTY_LOCATIONS_RESULT // Update all locations for (const location of locations) { set(parentCopy, location, finalizedValue, parentType) } } // Register a callback to finalize a child draft when the parent draft is finalized. // This assumes there is a parent -> child relationship between the two drafts, // and we have a key to locate the child in the parent. export function registerChildFinalizationCallback( parent: ImmerState, child: ImmerState, key: string | number | symbol ) { parent.callbacks_.push(function childCleanup(rootScope) { const state: ImmerState = child // Can only continue if this is a draft owned by this scope if (!state || !isSameScope(state, rootScope)) { return } // Handle potential set value finalization first rootScope.mapSetPlugin_?.fixSetContents(state) const finalizedValue = getFinalValue(state) // Update all locations in the parent that referenced this draft updateDraftInParent(parent, state.draft_ ?? state, finalizedValue, key) generatePatchesAndFinalize(state, rootScope) }) } function generatePatchesAndFinalize(state: ImmerState, rootScope: ImmerScope) { const shouldFinalize = state.modified_ && !state.finalized_ && (state.type_ === ArchType.Set || (state.type_ === ArchType.Array && (state as ProxyArrayState).allIndicesReassigned_) || (state.assigned_?.size ?? 0) > 0) if (shouldFinalize) { const {patchPlugin_} = rootScope if (patchPlugin_) { const basePath = patchPlugin_!.getPath(state) if (basePath) { patchPlugin_!.generatePatches_(state, basePath, rootScope) } } markStateFinalized(state) } } export function handleCrossReference( target: ImmerState, key: string | number | symbol, value: any ) { const {scope_} = target // Check if value is a draft from this scope if (isDraft(value)) { const state: ImmerState = value[DRAFT_STATE] if (isSameScope(state, scope_)) { // Register callback to update this location when the draft finalizes state.callbacks_.push(function crossReferenceCleanup() { // Update the target location with finalized value prepareCopy(target) const finalizedValue = getFinalValue(state) updateDraftInParent(target, value, finalizedValue, key) }) } } else if (isDraftable(value)) { // Handle non-draft objects that might contain drafts target.callbacks_.push(function nestedDraftCleanup() { const targetCopy = latest(target) // For Sets, check if value is still in the set if (target.type_ === ArchType.Set) { if (targetCopy.has(value)) { // Process the value to replace any nested drafts handleValue(value, scope_.handledSet_, scope_) } } else { // Maps/objects if (get(targetCopy, key, target.type_) === value) { if ( scope_.drafts_.length > 1 && ((target as Exclude).assigned_!.get(key) ?? false) === true && target.copy_ ) { // This might be a non-draft value that has drafts // inside. We do need to recurse here to handle those. handleValue( get(target.copy_, key, target.type_), scope_.handledSet_, scope_ ) } } } }) } } export function handleValue( target: any, handledSet: Set, rootScope: ImmerScope ) { if (!rootScope.immer_.autoFreeze_ && rootScope.unfinalizedDrafts_ < 1) { // optimization: if an object is not a draft, and we don't have to // deepfreeze everything, and we are sure that no drafts are left in the remaining object // cause we saw and finalized all drafts already; we can stop visiting the rest of the tree. // This benefits especially adding large data tree's without further processing. // See add-data.js perf test return target } // Skip if already handled, frozen, or not draftable if ( isDraft(target) || handledSet.has(target) || !isDraftable(target) || isFrozen(target) ) { return target } handledSet.add(target) // Process ALL properties/entries each(target, (key, value) => { if (isDraft(value)) { const state: ImmerState = value[DRAFT_STATE] if (isSameScope(state, rootScope)) { // Replace draft with finalized value const updatedValue = getFinalValue(state) set(target, key, updatedValue, target.type_) markStateFinalized(state) } } else if (isDraftable(value)) { // Recursively handle nested values handleValue(value, handledSet, rootScope) } }) return target } ================================================ FILE: src/core/immerClass.ts ================================================ import { IProduceWithPatches, IProduce, ImmerState, Drafted, isDraftable, processResult, Patch, Objectish, DRAFT_STATE, Draft, PatchListener, isDraft, isMap, isSet, createProxyProxy, getPlugin, die, enterScope, revokeScope, leaveScope, usePatchesInScope, getCurrentScope, NOTHING, freeze, current, ImmerScope, registerChildFinalizationCallback, ArchType, MapSetPlugin, AnyMap, AnySet, isObjectish, isFunction, isBoolean, PluginMapSet, PluginPatches } from "../internal" interface ProducersFns { produce: IProduce produceWithPatches: IProduceWithPatches } export type StrictMode = boolean | "class_only" export class Immer implements ProducersFns { autoFreeze_: boolean = true useStrictShallowCopy_: StrictMode = false useStrictIteration_: boolean = false constructor(config?: { autoFreeze?: boolean useStrictShallowCopy?: StrictMode useStrictIteration?: boolean }) { if (isBoolean(config?.autoFreeze)) this.setAutoFreeze(config!.autoFreeze) if (isBoolean(config?.useStrictShallowCopy)) this.setUseStrictShallowCopy(config!.useStrictShallowCopy) if (isBoolean(config?.useStrictIteration)) this.setUseStrictIteration(config!.useStrictIteration) } /** * The `produce` function takes a value and a "recipe function" (whose * return value often depends on the base state). The recipe function is * free to mutate its first argument however it wants. All mutations are * only ever applied to a __copy__ of the base state. * * Pass only a function to create a "curried producer" which relieves you * from passing the recipe function every time. * * Only plain objects and arrays are made mutable. All other objects are * considered uncopyable. * * Note: This function is __bound__ to its `Immer` instance. * * @param {any} base - the initial state * @param {Function} recipe - function that receives a proxy of the base state as first argument and which can be freely modified * @param {Function} patchListener - optional function that will be called with all the patches produced here * @returns {any} a new state, or the initial state if nothing was modified */ produce: IProduce = (base: any, recipe?: any, patchListener?: any) => { // curried invocation if (isFunction(base) && !isFunction(recipe)) { const defaultBase = recipe recipe = base const self = this return function curriedProduce( this: any, base = defaultBase, ...args: any[] ) { return self.produce(base, (draft: Drafted) => recipe.call(this, draft, ...args)) // prettier-ignore } } if (!isFunction(recipe)) die(6) if (patchListener !== undefined && !isFunction(patchListener)) die(7) let result // Only plain objects, arrays, and "immerable classes" are drafted. if (isDraftable(base)) { const scope = enterScope(this) const proxy = createProxy(scope, base, undefined) let hasError = true try { result = recipe(proxy) hasError = false } finally { // finally instead of catch + rethrow better preserves original stack if (hasError) revokeScope(scope) else leaveScope(scope) } usePatchesInScope(scope, patchListener) return processResult(result, scope) } else if (!base || !isObjectish(base)) { result = recipe(base) if (result === undefined) result = base if (result === NOTHING) result = undefined if (this.autoFreeze_) freeze(result, true) if (patchListener) { const p: Patch[] = [] const ip: Patch[] = [] getPlugin(PluginPatches).generateReplacementPatches_(base, result, { patches_: p, inversePatches_: ip } as ImmerScope) // dummy scope patchListener(p, ip) } return result } else die(1, base) } produceWithPatches: IProduceWithPatches = (base: any, recipe?: any): any => { // curried invocation if (isFunction(base)) { return (state: any, ...args: any[]) => this.produceWithPatches(state, (draft: any) => base(draft, ...args)) } let patches: Patch[], inversePatches: Patch[] const result = this.produce(base, recipe, (p: Patch[], ip: Patch[]) => { patches = p inversePatches = ip }) return [result, patches!, inversePatches!] } createDraft(base: T): Draft { if (!isDraftable(base)) die(8) if (isDraft(base)) base = current(base) const scope = enterScope(this) const proxy = createProxy(scope, base, undefined) proxy[DRAFT_STATE].isManual_ = true leaveScope(scope) return proxy as any } finishDraft>( draft: D, patchListener?: PatchListener ): D extends Draft ? T : never { const state: ImmerState = draft && (draft as any)[DRAFT_STATE] if (!state || !state.isManual_) die(9) const {scope_: scope} = state usePatchesInScope(scope, patchListener) return processResult(undefined, scope) } /** * Pass true to automatically freeze all copies created by Immer. * * By default, auto-freezing is enabled. */ setAutoFreeze(value: boolean) { this.autoFreeze_ = value } /** * Pass true to enable strict shallow copy. * * By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties. */ setUseStrictShallowCopy(value: StrictMode) { this.useStrictShallowCopy_ = value } /** * Pass false to use faster iteration that skips non-enumerable properties * but still handles symbols for compatibility. * * By default, strict iteration is enabled (includes all own properties). */ setUseStrictIteration(value: boolean) { this.useStrictIteration_ = value } shouldUseStrictIteration(): boolean { return this.useStrictIteration_ } applyPatches(base: T, patches: readonly Patch[]): T { // If a patch replaces the entire state, take that replacement as base // before applying patches let i: number for (i = patches.length - 1; i >= 0; i--) { const patch = patches[i] if (patch.path.length === 0 && patch.op === "replace") { base = patch.value break } } // If there was a patch that replaced the entire state, start from the // patch after that. if (i > -1) { patches = patches.slice(i + 1) } const applyPatchesImpl = getPlugin(PluginPatches).applyPatches_ if (isDraft(base)) { // N.B: never hits if some patch a replacement, patches are never drafts return applyPatchesImpl(base, patches) } // Otherwise, produce a copy of the base state. return this.produce(base, (draft: Drafted) => applyPatchesImpl(draft, patches) ) } } export function createProxy( rootScope: ImmerScope, value: T, parent?: ImmerState, key?: string | number | symbol ): Drafted { // precondition: createProxy should be guarded by isDraftable, so we know we can safely draft // returning a tuple here lets us skip a proxy access // to DRAFT_STATE later const [draft, state] = isMap(value) ? getPlugin(PluginMapSet).proxyMap_(value, parent) : isSet(value) ? getPlugin(PluginMapSet).proxySet_(value, parent) : createProxyProxy(value, parent) const scope = parent?.scope_ ?? getCurrentScope() scope.drafts_.push(draft) // Ensure the parent callbacks are passed down so we actually // track all callbacks added throughout the tree state.callbacks_ = parent?.callbacks_ ?? [] state.key_ = key if (parent && key !== undefined) { registerChildFinalizationCallback(parent, state, key) } else { // It's a root draft, register it with the scope state.callbacks_.push(function rootDraftCleanup(rootScope) { rootScope.mapSetPlugin_?.fixSetContents(state) const {patchPlugin_} = rootScope if (state.modified_ && patchPlugin_) { patchPlugin_.generatePatches_(state, [], rootScope) } }) } return draft as any } ================================================ FILE: src/core/proxy.ts ================================================ import { has, is, isDraftable, shallowCopy, latest, ImmerBaseState, ImmerState, Drafted, AnyObject, AnyArray, Objectish, getCurrentScope, getPrototypeOf, DRAFT_STATE, die, createProxy, ArchType, handleCrossReference, WRITABLE, CONFIGURABLE, ENUMERABLE, VALUE, isArray, isArrayIndex } from "../internal" interface ProxyBaseState extends ImmerBaseState { parent_?: ImmerState revoke_(): void } export interface ProxyObjectState extends ProxyBaseState { type_: ArchType.Object base_: any copy_: any draft_: Drafted } export interface ProxyArrayState extends ProxyBaseState { type_: ArchType.Array base_: AnyArray copy_: AnyArray | null draft_: Drafted operationMethod?: string allIndicesReassigned_?: boolean } type ProxyState = ProxyObjectState | ProxyArrayState /** * Returns a new draft of the `base` object. * * The second argument is the parent draft-state (used internally). */ export function createProxyProxy( base: T, parent?: ImmerState ): [Drafted, ProxyState] { const baseIsArray = isArray(base) const state: ProxyState = { type_: baseIsArray ? ArchType.Array : (ArchType.Object as any), // Track which produce call this is associated with. scope_: parent ? parent.scope_ : getCurrentScope()!, // True for both shallow and deep changes. modified_: false, // Used during finalization. finalized_: false, // Track which properties have been assigned (true) or deleted (false). // actually instantiated in `prepareCopy()` assigned_: undefined, // The parent draft state. parent_: parent, // The base state. base_: base, // The base proxy. draft_: null as any, // set below // The base copy with any updated values. copy_: null, // Called by the `produce` function. revoke_: null as any, isManual_: false, // `callbacks` actually gets assigned in `createProxy` callbacks_: undefined as any } // the traps must target something, a bit like the 'real' base. // but also, we need to be able to determine from the target what the relevant state is // (to avoid creating traps per instance to capture the state in closure, // and to avoid creating weird hidden properties as well) // So the trick is to use 'state' as the actual 'target'! (and make sure we intercept everything) // Note that in the case of an array, we put the state in an array to have better Reflect defaults ootb let target: T = state as any let traps: ProxyHandler> = objectTraps if (baseIsArray) { target = [state] as any traps = arrayTraps } const {revoke, proxy} = Proxy.revocable(target, traps) state.draft_ = proxy as any state.revoke_ = revoke return [proxy as any, state] } /** * Object drafts */ export const objectTraps: ProxyHandler = { get(state, prop) { if (prop === DRAFT_STATE) return state let arrayPlugin = state.scope_.arrayMethodsPlugin_ const isArrayWithStringProp = state.type_ === ArchType.Array && typeof prop === "string" // Intercept array methods so that we can override // behavior and skip proxy creation for perf if (isArrayWithStringProp) { if (arrayPlugin?.isArrayOperationMethod(prop)) { return arrayPlugin.createMethodInterceptor(state, prop) } } const source = latest(state) if (!has(source, prop, state.type_)) { // non-existing or non-own property... return readPropFromProto(state, source, prop) } const value = source[prop] if (state.finalized_ || !isDraftable(value)) { return value } // During mutating array operations, defer proxy creation for array elements // This optimization avoids creating unnecessary proxies during sort/reverse if ( isArrayWithStringProp && (state as ProxyArrayState).operationMethod && arrayPlugin?.isMutatingArrayMethod( (state as ProxyArrayState).operationMethod! ) && isArrayIndex(prop) ) { // Return raw value during mutating operations, create proxy only if modified return value } // Check for existing draft in modified state. // Assigned values are never drafted. This catches any drafts we created, too. if (value === peek(state.base_, prop)) { prepareCopy(state) // Ensure array keys are always numbers const childKey = state.type_ === ArchType.Array ? +(prop as string) : prop const childDraft = createProxy(state.scope_, value, state, childKey) return (state.copy_![childKey] = childDraft) } return value }, has(state, prop) { return prop in latest(state) }, ownKeys(state) { return Reflect.ownKeys(latest(state)) }, set( state: ProxyObjectState, prop: string /* strictly not, but helps TS */, value ) { const desc = getDescriptorFromProto(latest(state), prop) if (desc?.set) { // special case: if this write is captured by a setter, we have // to trigger it with the correct context desc.set.call(state.draft_, value) return true } if (!state.modified_) { // the last check is because we need to be able to distinguish setting a non-existing to undefined (which is a change) // from setting an existing property with value undefined to undefined (which is not a change) const current = peek(latest(state), prop) // special case, if we assigning the original value to a draft, we can ignore the assignment const currentState: ProxyObjectState = current?.[DRAFT_STATE] if (currentState && currentState.base_ === value) { state.copy_![prop] = value state.assigned_!.set(prop, false) return true } if ( is(value, current) && (value !== undefined || has(state.base_, prop, state.type_)) ) return true prepareCopy(state) markChanged(state) } if ( (state.copy_![prop] === value && // special case: handle new props with value 'undefined' (value !== undefined || prop in state.copy_)) || // special case: NaN (Number.isNaN(value) && Number.isNaN(state.copy_![prop])) ) return true // @ts-ignore state.copy_![prop] = value state.assigned_!.set(prop, true) handleCrossReference(state, prop, value) return true }, deleteProperty(state, prop: string) { prepareCopy(state) // The `undefined` check is a fast path for pre-existing keys. if (peek(state.base_, prop) !== undefined || prop in state.base_) { state.assigned_!.set(prop, false) markChanged(state) } else { // if an originally not assigned property was deleted state.assigned_!.delete(prop) } if (state.copy_) { delete state.copy_[prop] } return true }, // Note: We never coerce `desc.value` into an Immer draft, because we can't make // the same guarantee in ES5 mode. getOwnPropertyDescriptor(state, prop) { const owner = latest(state) const desc = Reflect.getOwnPropertyDescriptor(owner, prop) if (!desc) return desc return { [WRITABLE]: true, [CONFIGURABLE]: state.type_ !== ArchType.Array || prop !== "length", [ENUMERABLE]: desc[ENUMERABLE], [VALUE]: owner[prop] } }, defineProperty() { die(11) }, getPrototypeOf(state) { return getPrototypeOf(state.base_) }, setPrototypeOf() { die(12) } } /** * Array drafts */ const arrayTraps: ProxyHandler<[ProxyArrayState]> = {} // Use `for..in` instead of `each` to work around a weird // prod test suite issue for (let key in objectTraps) { let fn = objectTraps[key as keyof typeof objectTraps] as Function // @ts-ignore arrayTraps[key] = function() { const args = arguments args[0] = args[0][0] return fn.apply(this, args) } } arrayTraps.deleteProperty = function(state, prop) { if (process.env.NODE_ENV !== "production" && isNaN(parseInt(prop as any))) die(13) // @ts-ignore return arrayTraps.set!.call(this, state, prop, undefined) } arrayTraps.set = function(state, prop, value) { if ( process.env.NODE_ENV !== "production" && prop !== "length" && isNaN(parseInt(prop as any)) ) die(14) return objectTraps.set!.call(this, state[0], prop, value, state[0]) } // Access a property without creating an Immer draft. function peek(draft: Drafted, prop: PropertyKey) { const state = draft[DRAFT_STATE] const source = state ? latest(state) : draft return source[prop] } function readPropFromProto(state: ImmerState, source: any, prop: PropertyKey) { const desc = getDescriptorFromProto(source, prop) return desc ? VALUE in desc ? desc[VALUE] : // This is a very special case, if the prop is a getter defined by the // prototype, we should invoke it with the draft as context! desc.get?.call(state.draft_) : undefined } function getDescriptorFromProto( source: any, prop: PropertyKey ): PropertyDescriptor | undefined { // 'in' checks proto! if (!(prop in source)) return undefined let proto = getPrototypeOf(source) while (proto) { const desc = Object.getOwnPropertyDescriptor(proto, prop) if (desc) return desc proto = getPrototypeOf(proto) } return undefined } export function markChanged(state: ImmerState) { if (!state.modified_) { state.modified_ = true if (state.parent_) { markChanged(state.parent_) } } } export function prepareCopy(state: ImmerState) { if (!state.copy_) { // Actually create the `assigned_` map now that we // know this is a modified draft. state.assigned_ = new Map() state.copy_ = shallowCopy( state.base_, state.scope_.immer_.useStrictShallowCopy_ ) } } ================================================ FILE: src/core/scope.ts ================================================ import { Patch, PatchListener, Drafted, Immer, DRAFT_STATE, ImmerState, ArchType, getPlugin, PatchesPlugin, MapSetPlugin, isPluginLoaded, PluginMapSet, PluginPatches, ArrayMethodsPlugin, PluginArrayMethods } from "../internal" /** Each scope represents a `produce` call. */ export interface ImmerScope { patches_?: Patch[] inversePatches_?: Patch[] patchPlugin_?: PatchesPlugin mapSetPlugin_?: MapSetPlugin arrayMethodsPlugin_?: ArrayMethodsPlugin canAutoFreeze_: boolean drafts_: any[] parent_?: ImmerScope patchListener_?: PatchListener immer_: Immer unfinalizedDrafts_: number handledSet_: Set processedForPatches_: Set } let currentScope: ImmerScope | undefined export let getCurrentScope = () => currentScope! let createScope = ( parent_: ImmerScope | undefined, immer_: Immer ): ImmerScope => ({ drafts_: [], parent_, immer_, // Whenever the modified draft contains a draft from another scope, we // need to prevent auto-freezing so the unowned draft can be finalized. canAutoFreeze_: true, unfinalizedDrafts_: 0, handledSet_: new Set(), processedForPatches_: new Set(), mapSetPlugin_: isPluginLoaded(PluginMapSet) ? getPlugin(PluginMapSet) : undefined, arrayMethodsPlugin_: isPluginLoaded(PluginArrayMethods) ? getPlugin(PluginArrayMethods) : undefined }) export function usePatchesInScope( scope: ImmerScope, patchListener?: PatchListener ) { if (patchListener) { scope.patchPlugin_ = getPlugin(PluginPatches) // assert we have the plugin scope.patches_ = [] scope.inversePatches_ = [] scope.patchListener_ = patchListener } } export function revokeScope(scope: ImmerScope) { leaveScope(scope) scope.drafts_.forEach(revokeDraft) // @ts-ignore scope.drafts_ = null } export function leaveScope(scope: ImmerScope) { if (scope === currentScope) { currentScope = scope.parent_ } } export let enterScope = (immer: Immer) => (currentScope = createScope(currentScope, immer)) function revokeDraft(draft: Drafted) { const state: ImmerState = draft[DRAFT_STATE] if (state.type_ === ArchType.Object || state.type_ === ArchType.Array) state.revoke_() else state.revoked_ = true } ================================================ FILE: src/immer.ts ================================================ import { IProduce, IProduceWithPatches, Immer, Draft, Immutable } from "./internal" export { Draft, WritableDraft, Immutable, Patch, PatchListener, Producer, original, current, isDraft, isDraftable, NOTHING as nothing, DRAFTABLE as immerable, freeze, Objectish, StrictMode } from "./internal" const immer = new Immer() /** * The `produce` function takes a value and a "recipe function" (whose * return value often depends on the base state). The recipe function is * free to mutate its first argument however it wants. All mutations are * only ever applied to a __copy__ of the base state. * * Pass only a function to create a "curried producer" which relieves you * from passing the recipe function every time. * * Only plain objects and arrays are made mutable. All other objects are * considered uncopyable. * * Note: This function is __bound__ to its `Immer` instance. * * @param {any} base - the initial state * @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified * @param {Function} patchListener - optional function that will be called with all the patches produced here * @returns {any} a new state, or the initial state if nothing was modified */ export const produce: IProduce = /* @__PURE__ */ immer.produce /** * Like `produce`, but `produceWithPatches` always returns a tuple * [nextState, patches, inversePatches] (instead of just the next state) */ export const produceWithPatches: IProduceWithPatches = /* @__PURE__ */ immer.produceWithPatches.bind( immer ) /** * Pass true to automatically freeze all copies created by Immer. * * Always freeze by default, even in production mode */ export const setAutoFreeze = /* @__PURE__ */ immer.setAutoFreeze.bind(immer) /** * Pass true to enable strict shallow copy. * * By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties. */ export const setUseStrictShallowCopy = /* @__PURE__ */ immer.setUseStrictShallowCopy.bind( immer ) /** * Pass false to use loose iteration that only processes enumerable string properties. * This skips symbols and non-enumerable properties for maximum performance. * * By default, strict iteration is enabled (includes all own properties). */ export const setUseStrictIteration = /* @__PURE__ */ immer.setUseStrictIteration.bind( immer ) /** * Apply an array of Immer patches to the first argument. * * This function is a producer, which means copy-on-write is in effect. */ export const applyPatches = /* @__PURE__ */ immer.applyPatches.bind(immer) /** * Create an Immer draft from the given base state, which may be a draft itself. * The draft can be modified until you finalize it with the `finishDraft` function. */ export const createDraft = /* @__PURE__ */ immer.createDraft.bind(immer) /** * Finalize an Immer draft from a `createDraft` call, returning the base state * (if no changes were made) or a modified copy. The draft must *not* be * mutated afterwards. * * Pass a function as the 2nd argument to generate Immer patches based on the * changes that were made. */ export const finishDraft = /* @__PURE__ */ immer.finishDraft.bind(immer) /** * This function is actually a no-op, but can be used to cast an immutable type * to an draft type and make TypeScript happy * * @param value */ export let castDraft = (value: T): Draft => value as any /** * This function is actually a no-op, but can be used to cast a mutable type * to an immutable type and make TypeScript happy * @param value */ export let castImmutable = (value: T): Immutable => value as any export {Immer} export {enablePatches} from "./plugins/patches" export {enableMapSet} from "./plugins/mapset" export {enableArrayMethods} from "./plugins/arrayMethods" ================================================ FILE: src/internal.ts ================================================ export * from "./utils/env" export * from "./utils/errors" export * from "./types/types-external" export * from "./types/types-internal" export * from "./utils/common" export * from "./utils/plugins" export * from "./core/scope" export * from "./core/finalize" export * from "./core/proxy" export * from "./core/immerClass" export * from "./core/current" ================================================ FILE: src/plugins/arrayMethods.ts ================================================ import { PluginArrayMethods, latest, loadPlugin, markChanged, prepareCopy, handleCrossReference, ProxyArrayState } from "../internal" /** * Methods that directly modify the array in place. * These operate on the copy without creating per-element proxies: * - `push`, `pop`: Add/remove from end * - `shift`, `unshift`: Add/remove from start (marks all indices reassigned) * - `splice`: Add/remove at arbitrary position (marks all indices reassigned) * - `reverse`, `sort`: Reorder elements (marks all indices reassigned) */ type MutatingArrayMethod = | "push" | "pop" | "shift" | "unshift" | "splice" | "reverse" | "sort" /** * Methods that read from the array without modifying it. * These fall into distinct categories based on return semantics: * * **Subset operations** (return drafts - mutations propagate): * - `filter`, `slice`: Return array of draft proxies * - `find`, `findLast`: Return single draft proxy or undefined * * **Transform operations** (return base values - mutations don't track): * - `concat`, `flat`: Create new structures, not subsets of original * * **Primitive-returning** (no draft needed): * - `findIndex`, `findLastIndex`, `indexOf`, `lastIndexOf`: Return numbers * - `some`, `every`, `includes`: Return booleans * - `join`, `toString`, `toLocaleString`: Return strings */ type NonMutatingArrayMethod = | "filter" | "slice" | "concat" | "flat" | "find" | "findIndex" | "findLast" | "findLastIndex" | "some" | "every" | "indexOf" | "lastIndexOf" | "includes" | "join" | "toString" | "toLocaleString" /** Union of all array operation methods handled by the plugin. */ export type ArrayOperationMethod = MutatingArrayMethod | NonMutatingArrayMethod /** * Enables optimized array method handling for Immer drafts. * * This plugin overrides array methods to avoid unnecessary Proxy creation during iteration, * significantly improving performance for array-heavy operations. * * **Mutating methods** (push, pop, shift, unshift, splice, sort, reverse): * Operate directly on the copy without creating per-element proxies. * * **Non-mutating methods** fall into categories: * - **Subset operations** (filter, slice, find, findLast): Return draft proxies - mutations track * - **Transform operations** (concat, flat): Return base values - mutations don't track * - **Primitive-returning** (indexOf, includes, some, every, etc.): Return primitives * * **Important**: Callbacks for overridden methods receive base values, not drafts. * This is the core performance optimization. * * @example * ```ts * import { enableArrayMethods, produce } from "immer" * * enableArrayMethods() * * const next = produce(state, draft => { * // Optimized - no proxy creation per element * draft.items.sort((a, b) => a.value - b.value) * * // filter returns drafts - mutations propagate * const filtered = draft.items.filter(x => x.value > 5) * filtered[0].value = 999 // Affects draft.items[originalIndex] * }) * ``` * * @see https://immerjs.github.io/immer/array-methods */ export function enableArrayMethods() { const SHIFTING_METHODS = new Set(["shift", "unshift"]) const QUEUE_METHODS = new Set(["push", "pop"]) const RESULT_RETURNING_METHODS = new Set([ ...QUEUE_METHODS, ...SHIFTING_METHODS ]) const REORDERING_METHODS = new Set(["reverse", "sort"]) // Optimized method detection using array-based lookup const MUTATING_METHODS = new Set([ ...RESULT_RETURNING_METHODS, ...REORDERING_METHODS, "splice" ]) const FIND_METHODS = new Set(["find", "findLast"]) const NON_MUTATING_METHODS = new Set([ "filter", "slice", "concat", "flat", ...FIND_METHODS, "findIndex", "findLastIndex", "some", "every", "indexOf", "lastIndexOf", "includes", "join", "toString", "toLocaleString" ]) // Type guard for method detection function isMutatingArrayMethod( method: string ): method is MutatingArrayMethod { return MUTATING_METHODS.has(method as any) } function isNonMutatingArrayMethod( method: string ): method is NonMutatingArrayMethod { return NON_MUTATING_METHODS.has(method as any) } function isArrayOperationMethod( method: string ): method is ArrayOperationMethod { return isMutatingArrayMethod(method) || isNonMutatingArrayMethod(method) } function enterOperation( state: ProxyArrayState, method: ArrayOperationMethod ) { state.operationMethod = method } function exitOperation(state: ProxyArrayState) { state.operationMethod = undefined } // Shared utility functions for array method handlers function executeArrayMethod( state: ProxyArrayState, operation: () => T, markLength = true ): T { prepareCopy(state) const result = operation() markChanged(state) if (markLength) state.assigned_!.set("length", true) return result } function markAllIndicesReassigned(state: ProxyArrayState) { state.allIndicesReassigned_ = true } function normalizeSliceIndex(index: number, length: number): number { if (index < 0) { return Math.max(length + index, 0) } return Math.min(index, length) } /** * Calls handleCrossReference for each value being inserted into the array, * and marks the corresponding indices as assigned in `assigned_`. * * This ensures nested drafts inside inserted values (e.g. from spreading * a draft object) are properly finalized, matching the behavior of the * proxy set trap which calls handleCrossReference on every assignment. * * Without this, values containing draft proxies (like `{...state[0]}`) * pushed via the array methods plugin would have their nested drafts * revoked during finalization without being replaced by final values. */ function handleInsertedValues( state: ProxyArrayState, startIndex: number, values: any[] ) { for (let i = 0; i < values.length; i++) { const index = startIndex + i state.assigned_!.set(index, true) handleCrossReference(state, index, values[i]) } } /** * Handles mutating operations that add/remove elements (push, pop, shift, unshift, splice). * * Operates directly on `state.copy_` without creating per-element proxies. * For shifting methods (shift, unshift), marks all indices as reassigned since * indices shift. * * @returns For push/pop/shift/unshift: the native method result. For others: the draft. */ function handleSimpleOperation( state: ProxyArrayState, method: string, args: any[] ) { return executeArrayMethod(state, () => { // For push/unshift, capture the length before the operation // so we can compute insertion indices for handleCrossReference const lengthBefore = state.copy_!.length const result = (state.copy_! as any)[method](...args) // Handle index reassignment for shifting methods if (SHIFTING_METHODS.has(method as MutatingArrayMethod)) { markAllIndicesReassigned(state) } // Handle cross-references for newly inserted values. // push appends at the end, unshift inserts at the beginning. if (method === "push" && args.length > 0) { handleInsertedValues(state, lengthBefore, args) } else if (method === "unshift" && args.length > 0) { handleInsertedValues(state, 0, args) } // Return appropriate value based on method return RESULT_RETURNING_METHODS.has(method as MutatingArrayMethod) ? result : state.draft_ }) } /** * Handles reordering operations (reverse, sort) that change element order. * * Operates directly on `state.copy_` and marks all indices as reassigned * since element positions change. Does not mark length as changed since * these operations preserve array length. * * @returns The draft proxy for method chaining. */ function handleReorderingOperation( state: ProxyArrayState, method: string, args: any[] ) { return executeArrayMethod( state, () => { ;(state.copy_! as any)[method](...args) markAllIndicesReassigned(state) return state.draft_ }, false ) // Don't mark length as changed } /** * Creates an interceptor function for a specific array method. * * The interceptor wraps array method calls to: * 1. Set `state.operationMethod` flag during execution (allows proxy `get` trap * to detect we're inside an optimized method and skip proxy creation) * 2. Route to appropriate handler based on method type * 3. Clean up the operation flag in `finally` block * * The `operationMethod` flag is the key mechanism that enables the proxy's `get` * trap to return base values instead of creating nested proxies during iteration. * * @param state - The proxy array state * @param originalMethod - Name of the array method being intercepted * @returns Interceptor function that handles the method call */ function createMethodInterceptor( state: ProxyArrayState, originalMethod: string ) { return function interceptedMethod(...args: any[]) { // Enter operation mode - this flag tells the proxy's get trap to return // base values instead of creating nested proxies during iteration const method = originalMethod as ArrayOperationMethod enterOperation(state, method) try { // Check if this is a mutating method if (isMutatingArrayMethod(method)) { // Direct method dispatch - no configuration lookup needed if (RESULT_RETURNING_METHODS.has(method)) { return handleSimpleOperation(state, method, args) } if (REORDERING_METHODS.has(method)) { return handleReorderingOperation(state, method, args) } if (method === "splice") { const res = executeArrayMethod(state, () => state.copy_!.splice(...(args as [number, number, ...any[]])) ) markAllIndicesReassigned(state) // Handle cross-references for inserted values (args from index 2+) if (args.length > 2) { const startIndex = normalizeSliceIndex( args[0] ?? 0, state.copy_!.length ) handleInsertedValues(state, startIndex, args.slice(2)) } return res } } else { // Handle non-mutating methods return handleNonMutatingOperation(state, method, args) } } finally { // Always exit operation mode - must be in finally to handle exceptions exitOperation(state) } } } /** * Handles non-mutating array methods with different return semantics. * * **Subset operations** return draft proxies for mutation tracking: * - `filter`, `slice`: Return `state.draft_[i]` for each selected element * - `find`, `findLast`: Return `state.draft_[i]` for the found element * * This allows mutations on returned elements to propagate back to the draft: * ```ts * const filtered = draft.items.filter(x => x.value > 5) * filtered[0].value = 999 // Mutates draft.items[originalIndex] * ``` * * **Transform operations** return base values (no draft tracking): * - `concat`, `flat`: These create NEW arrays rather than selecting subsets. * Since the result structure differs from the original, tracking mutations * back to specific draft indices would be impractical/impossible. * * **Primitive operations** return the native result directly: * - `indexOf`, `includes`, `some`, `every`, `join`, etc. * * @param state - The proxy array state * @param method - The non-mutating method name * @param args - Arguments passed to the method * @returns Drafts for subset operations, base values for transforms, primitives otherwise */ function handleNonMutatingOperation( state: ProxyArrayState, method: NonMutatingArrayMethod, args: any[] ) { const source = latest(state) // Methods that return arrays with selected items - need to return drafts if (method === "filter") { const predicate = args[0] const result: any[] = [] // First pass: call predicate on base values to determine which items pass for (let i = 0; i < source.length; i++) { if (predicate(source[i], i, source)) { // Only create draft for items that passed the predicate result.push(state.draft_[i]) } } return result } if (FIND_METHODS.has(method)) { const predicate = args[0] const isForward = method === "find" const step = isForward ? 1 : -1 const start = isForward ? 0 : source.length - 1 for (let i = start; i >= 0 && i < source.length; i += step) { if (predicate(source[i], i, source)) { return state.draft_[i] } } return undefined } if (method === "slice") { const rawStart = args[0] ?? 0 const rawEnd = args[1] ?? source.length // Normalize negative indices const start = normalizeSliceIndex(rawStart, source.length) const end = normalizeSliceIndex(rawEnd, source.length) const result: any[] = [] // Return drafts for items in the slice range for (let i = start; i < end; i++) { result.push(state.draft_[i]) } return result } // For other methods, call on base array directly: // - indexOf, includes, join, toString: Return primitives, no draft needed // - concat, flat: Return NEW arrays (not subsets). Elements are base values. // This is intentional - concat/flat create new data structures rather than // selecting subsets of the original, making draft tracking impractical. return source[method as keyof typeof Array.prototype](...args) } loadPlugin(PluginArrayMethods, { createMethodInterceptor, isArrayOperationMethod, isMutatingArrayMethod }) } ================================================ FILE: src/plugins/mapset.ts ================================================ // types only! import { ImmerState, AnyMap, AnySet, MapState, SetState, DRAFT_STATE, getCurrentScope, latest, isDraftable, createProxy, loadPlugin, markChanged, die, ArchType, each, getValue, PluginMapSet, handleCrossReference } from "../internal" export function enableMapSet() { class DraftMap extends Map { [DRAFT_STATE]: MapState constructor(target: AnyMap, parent?: ImmerState) { super() this[DRAFT_STATE] = { type_: ArchType.Map, parent_: parent, scope_: parent ? parent.scope_ : getCurrentScope()!, modified_: false, finalized_: false, copy_: undefined, assigned_: undefined, base_: target, draft_: this as any, isManual_: false, revoked_: false, callbacks_: [] } } get size(): number { return latest(this[DRAFT_STATE]).size } has(key: any): boolean { return latest(this[DRAFT_STATE]).has(key) } set(key: any, value: any) { const state: MapState = this[DRAFT_STATE] assertUnrevoked(state) if (!latest(state).has(key) || latest(state).get(key) !== value) { prepareMapCopy(state) markChanged(state) state.assigned_!.set(key, true) state.copy_!.set(key, value) state.assigned_!.set(key, true) handleCrossReference(state, key, value) } return this } delete(key: any): boolean { if (!this.has(key)) { return false } const state: MapState = this[DRAFT_STATE] assertUnrevoked(state) prepareMapCopy(state) markChanged(state) if (state.base_.has(key)) { state.assigned_!.set(key, false) } else { state.assigned_!.delete(key) } state.copy_!.delete(key) return true } clear() { const state: MapState = this[DRAFT_STATE] assertUnrevoked(state) if (latest(state).size) { prepareMapCopy(state) markChanged(state) state.assigned_ = new Map() each(state.base_, key => { state.assigned_!.set(key, false) }) state.copy_!.clear() } } forEach(cb: (value: any, key: any, self: any) => void, thisArg?: any) { const state: MapState = this[DRAFT_STATE] latest(state).forEach((_value: any, key: any, _map: any) => { cb.call(thisArg, this.get(key), key, this) }) } get(key: any): any { const state: MapState = this[DRAFT_STATE] assertUnrevoked(state) const value = latest(state).get(key) if (state.finalized_ || !isDraftable(value)) { return value } if (value !== state.base_.get(key)) { return value // either already drafted or reassigned } // despite what it looks, this creates a draft only once, see above condition const draft = createProxy(state.scope_, value, state, key) prepareMapCopy(state) state.copy_!.set(key, draft) return draft } keys(): IterableIterator { return latest(this[DRAFT_STATE]).keys() } values(): IterableIterator { const iterator = this.keys() return { [Symbol.iterator]: () => this.values(), next: () => { const r = iterator.next() /* istanbul ignore next */ if (r.done) return r const value = this.get(r.value) return { done: false, value } } } as any } entries(): IterableIterator<[any, any]> { const iterator = this.keys() return { [Symbol.iterator]: () => this.entries(), next: () => { const r = iterator.next() /* istanbul ignore next */ if (r.done) return r const value = this.get(r.value) return { done: false, value: [r.value, value] } } } as any } [Symbol.iterator]() { return this.entries() } } function proxyMap_( target: T, parent?: ImmerState ): [T, MapState] { // @ts-ignore const map = new DraftMap(target, parent) return [map as any, map[DRAFT_STATE]] } function prepareMapCopy(state: MapState) { if (!state.copy_) { state.assigned_ = new Map() state.copy_ = new Map(state.base_) } } class DraftSet extends Set { [DRAFT_STATE]: SetState constructor(target: AnySet, parent?: ImmerState) { super() this[DRAFT_STATE] = { type_: ArchType.Set, parent_: parent, scope_: parent ? parent.scope_ : getCurrentScope()!, modified_: false, finalized_: false, copy_: undefined, base_: target, draft_: this, drafts_: new Map(), revoked_: false, isManual_: false, assigned_: undefined, callbacks_: [] } } get size(): number { return latest(this[DRAFT_STATE]).size } has(value: any): boolean { const state: SetState = this[DRAFT_STATE] assertUnrevoked(state) // bit of trickery here, to be able to recognize both the value, and the draft of its value if (!state.copy_) { return state.base_.has(value) } if (state.copy_.has(value)) return true if (state.drafts_.has(value) && state.copy_.has(state.drafts_.get(value))) return true return false } add(value: any): any { const state: SetState = this[DRAFT_STATE] assertUnrevoked(state) if (!this.has(value)) { prepareSetCopy(state) markChanged(state) state.copy_!.add(value) handleCrossReference(state, value, value) } return this } delete(value: any): any { if (!this.has(value)) { return false } const state: SetState = this[DRAFT_STATE] assertUnrevoked(state) prepareSetCopy(state) markChanged(state) return ( state.copy_!.delete(value) || (state.drafts_.has(value) ? state.copy_!.delete(state.drafts_.get(value)) : /* istanbul ignore next */ false) ) } clear() { const state: SetState = this[DRAFT_STATE] assertUnrevoked(state) if (latest(state).size) { prepareSetCopy(state) markChanged(state) state.copy_!.clear() } } values(): IterableIterator { const state: SetState = this[DRAFT_STATE] assertUnrevoked(state) prepareSetCopy(state) return state.copy_!.values() } entries(): IterableIterator<[any, any]> { const state: SetState = this[DRAFT_STATE] assertUnrevoked(state) prepareSetCopy(state) return state.copy_!.entries() } keys(): IterableIterator { return this.values() } [Symbol.iterator]() { return this.values() } forEach(cb: any, thisArg?: any) { const iterator = this.values() let result = iterator.next() while (!result.done) { cb.call(thisArg, result.value, result.value, this) result = iterator.next() } } } function proxySet_( target: T, parent?: ImmerState ): [T, SetState] { // @ts-ignore const set = new DraftSet(target, parent) return [set as any, set[DRAFT_STATE]] } function prepareSetCopy(state: SetState) { if (!state.copy_) { // create drafts for all entries to preserve insertion order state.copy_ = new Set() state.base_.forEach(value => { if (isDraftable(value)) { const draft = createProxy(state.scope_, value, state, value) state.drafts_.set(value, draft) state.copy_!.add(draft) } else { state.copy_!.add(value) } }) } } function assertUnrevoked(state: any /*ES5State | MapState | SetState*/) { if (state.revoked_) die(3, JSON.stringify(latest(state))) } function fixSetContents(target: ImmerState) { // For sets we clone before iterating, otherwise we can get in endless loop due to modifying during iteration, see #628 // To preserve insertion order in all cases we then clear the set if (target.type_ === ArchType.Set && target.copy_) { const copy = new Set(target.copy_) target.copy_.clear() copy.forEach(value => { target.copy_!.add(getValue(value)) }) } } loadPlugin(PluginMapSet, {proxyMap_, proxySet_, fixSetContents}) } ================================================ FILE: src/plugins/patches.ts ================================================ import {immerable} from "../immer" import { ImmerState, Patch, SetState, ProxyArrayState, MapState, ProxyObjectState, PatchPath, get, each, has, getArchtype, getPrototypeOf, isSet, isMap, loadPlugin, ArchType, die, isDraft, isDraftable, NOTHING, errors, DRAFT_STATE, getProxyDraft, ImmerScope, isObjectish, isFunction, CONSTRUCTOR, PluginPatches, isArray, PROTOTYPE } from "../internal" export function enablePatches() { const errorOffset = 16 if (process.env.NODE_ENV !== "production") { errors.push( 'Sets cannot have "replace" patches.', function(op: string) { return "Unsupported patch operation: " + op }, function(path: string) { return "Cannot apply patch, path doesn't resolve: " + path }, "Patching reserved attributes like __proto__, prototype and constructor is not allowed" ) } function getPath(state: ImmerState, path: PatchPath = []): PatchPath | null { // Step 1: Check if state has a stored key if (state.key_ !== undefined) { // Step 2: Validate the key is still valid in parent const parentCopy = state.parent_!.copy_ ?? state.parent_!.base_ const proxyDraft = getProxyDraft(get(parentCopy, state.key_!)) const valueAtKey = get(parentCopy, state.key_!) if (valueAtKey === undefined) { return null } // Check if the value at the key is still related to this draft // It should be either the draft itself, the base, or the copy if ( valueAtKey !== state.draft_ && valueAtKey !== state.base_ && valueAtKey !== state.copy_ ) { return null // Value was replaced with something else } if (proxyDraft != null && proxyDraft.base_ !== state.base_) { return null // Different draft } // Step 3: Handle Set case specially const isSet = state.parent_!.type_ === ArchType.Set let key: string | number if (isSet) { // For Sets, find the index in the drafts_ map const setParent = state.parent_ as SetState key = Array.from(setParent.drafts_.keys()).indexOf(state.key_) } else { key = state.key_ as string | number } // Step 4: Validate key still exists in parent if (!((isSet && parentCopy.size > key) || has(parentCopy, key))) { return null // Key deleted } // Step 5: Add key to path path.push(key) } // Step 6: Recurse to parent if exists if (state.parent_) { return getPath(state.parent_, path) } // Step 7: At root - reverse path and validate path.reverse() try { // Validate path can be resolved from ROOT resolvePath(state.copy_, path) } catch (e) { return null // Path invalid } return path } // NEW: Add resolvePath helper function function resolvePath(base: any, path: PatchPath): any { let current = base for (let i = 0; i < path.length - 1; i++) { const key = path[i] current = get(current, key) if (!isObjectish(current) || current === null) { throw new Error(`Cannot resolve path at '${path.join("/")}'`) } } return current } const REPLACE = "replace" const ADD = "add" const REMOVE = "remove" function generatePatches_( state: ImmerState, basePath: PatchPath, scope: ImmerScope ): void { if (state.scope_.processedForPatches_.has(state)) { return } state.scope_.processedForPatches_.add(state) const {patches_, inversePatches_} = scope switch (state.type_) { case ArchType.Object: case ArchType.Map: return generatePatchesFromAssigned( state, basePath, patches_!, inversePatches_! ) case ArchType.Array: return generateArrayPatches( state, basePath, patches_!, inversePatches_! ) case ArchType.Set: return generateSetPatches( (state as any) as SetState, basePath, patches_!, inversePatches_! ) } } function generateArrayPatches( state: ProxyArrayState, basePath: PatchPath, patches: Patch[], inversePatches: Patch[] ) { let {base_, assigned_} = state let copy_ = state.copy_! // Reduce complexity by ensuring `base` is never longer. if (copy_.length < base_.length) { // @ts-ignore ;[base_, copy_] = [copy_, base_] ;[patches, inversePatches] = [inversePatches, patches] } const allReassigned = state.allIndicesReassigned_ === true // Process replaced indices. for (let i = 0; i < base_.length; i++) { const copiedItem = copy_[i] const baseItem = base_[i] const isAssigned = allReassigned || assigned_?.get(i.toString()) if (isAssigned && copiedItem !== baseItem) { const childState = copiedItem?.[DRAFT_STATE] if (childState && childState.modified_) { // Skip - let the child generate its own patches continue } const path = basePath.concat([i]) patches.push({ op: REPLACE, path, // Need to maybe clone it, as it can in fact be the original value // due to the base/copy inversion at the start of this function value: clonePatchValueIfNeeded(copiedItem) }) inversePatches.push({ op: REPLACE, path, value: clonePatchValueIfNeeded(baseItem) }) } } // Process added indices. for (let i = base_.length; i < copy_.length; i++) { const path = basePath.concat([i]) patches.push({ op: ADD, path, // Need to maybe clone it, as it can in fact be the original value // due to the base/copy inversion at the start of this function value: clonePatchValueIfNeeded(copy_[i]) }) } for (let i = copy_.length - 1; base_.length <= i; --i) { const path = basePath.concat([i]) inversePatches.push({ op: REMOVE, path }) } } // This is used for both Map objects and normal objects. function generatePatchesFromAssigned( state: MapState | ProxyObjectState, basePath: PatchPath, patches: Patch[], inversePatches: Patch[] ) { const {base_, copy_, type_} = state each(state.assigned_!, (key, assignedValue) => { const origValue = get(base_, key, type_) const value = get(copy_!, key, type_) const op = !assignedValue ? REMOVE : has(base_, key) ? REPLACE : ADD if (origValue === value && op === REPLACE) return const path = basePath.concat(key as any) patches.push( op === REMOVE ? {op, path} : {op, path, value: clonePatchValueIfNeeded(value)} ) inversePatches.push( op === ADD ? {op: REMOVE, path} : op === REMOVE ? {op: ADD, path, value: clonePatchValueIfNeeded(origValue)} : {op: REPLACE, path, value: clonePatchValueIfNeeded(origValue)} ) }) } function generateSetPatches( state: SetState, basePath: PatchPath, patches: Patch[], inversePatches: Patch[] ) { let {base_, copy_} = state let i = 0 base_.forEach((value: any) => { if (!copy_!.has(value)) { const path = basePath.concat([i]) patches.push({ op: REMOVE, path, value }) inversePatches.unshift({ op: ADD, path, value }) } i++ }) i = 0 copy_!.forEach((value: any) => { if (!base_.has(value)) { const path = basePath.concat([i]) patches.push({ op: ADD, path, value }) inversePatches.unshift({ op: REMOVE, path, value }) } i++ }) } function generateReplacementPatches_( baseValue: any, replacement: any, scope: ImmerScope ): void { const {patches_, inversePatches_} = scope patches_!.push({ op: REPLACE, path: [], value: replacement === NOTHING ? undefined : replacement }) inversePatches_!.push({ op: REPLACE, path: [], value: baseValue }) } function applyPatches_(draft: T, patches: readonly Patch[]): T { patches.forEach(patch => { const {path, op} = patch let base: any = draft for (let i = 0; i < path.length - 1; i++) { const parentType = getArchtype(base) let p = path[i] if (typeof p !== "string" && typeof p !== "number") { p = "" + p } // See #738, avoid prototype pollution if ( (parentType === ArchType.Object || parentType === ArchType.Array) && (p === "__proto__" || p === CONSTRUCTOR) ) die(errorOffset + 3) if (isFunction(base) && p === PROTOTYPE) die(errorOffset + 3) base = get(base, p) if (!isObjectish(base)) die(errorOffset + 2, path.join("/")) } const type = getArchtype(base) const value = deepClonePatchValue(patch.value) // used to clone patch to ensure original patch is not modified, see #411 const key = path[path.length - 1] switch (op) { case REPLACE: switch (type) { case ArchType.Map: return base.set(key, value) /* istanbul ignore next */ case ArchType.Set: die(errorOffset) default: // if value is an object, then it's assigned by reference // in the following add or remove ops, the value field inside the patch will also be modifyed // so we use value from the cloned patch // @ts-ignore return (base[key] = value) } case ADD: switch (type) { case ArchType.Array: return key === "-" ? base.push(value) : base.splice(key as any, 0, value) case ArchType.Map: return base.set(key, value) case ArchType.Set: return base.add(value) default: return (base[key] = value) } case REMOVE: switch (type) { case ArchType.Array: return base.splice(key as any, 1) case ArchType.Map: return base.delete(key) case ArchType.Set: return base.delete(patch.value) default: return delete base[key] } default: die(errorOffset + 1, op) } }) return draft } // optimize: this is quite a performance hit, can we detect intelligently when it is needed? // E.g. auto-draft when new objects from outside are assigned and modified? // (See failing test when deepClone just returns obj) function deepClonePatchValue(obj: T): T function deepClonePatchValue(obj: any) { if (!isDraftable(obj)) return obj if (isArray(obj)) return obj.map(deepClonePatchValue) if (isMap(obj)) return new Map( Array.from(obj.entries()).map(([k, v]) => [k, deepClonePatchValue(v)]) ) if (isSet(obj)) return new Set(Array.from(obj).map(deepClonePatchValue)) const cloned = Object.create(getPrototypeOf(obj)) for (const key in obj) cloned[key] = deepClonePatchValue(obj[key]) if (has(obj, immerable)) cloned[immerable] = obj[immerable] return cloned } function clonePatchValueIfNeeded(obj: T): T { if (isDraft(obj)) { return deepClonePatchValue(obj) } else return obj } loadPlugin(PluginPatches, { applyPatches_, generatePatches_, generateReplacementPatches_, getPath }) } ================================================ FILE: src/types/globals.d.ts ================================================ declare const __DEV__: boolean ================================================ FILE: src/types/index.js.flow ================================================ // @flow export interface Patch { op: "replace" | "remove" | "add"; path: (string | number)[]; value?: any; } export type PatchListener = (patches: Patch[], inversePatches: Patch[]) => void type Base = {...} | Array interface IProduce { /** * Immer takes a state, and runs a function against it. * That function can freely mutate the state, as it will create copies-on-write. * This means that the original state will stay unchanged, and once the function finishes, the modified state is returned. * * If the first argument is a function, this is interpreted as the recipe, and will create a curried function that will execute the recipe * any time it is called with the current state. * * @param currentState - the state to start with * @param recipe - function that receives a proxy of the current state as first argument and which can be freely modified * @param initialState - if a curried function is created and this argument was given, it will be used as fallback if the curried function is called with a state of undefined * @returns The next state: a new state, or the current state if nothing was modified */ ( currentState: S, recipe: (draftState: S) => S | void, patchListener?: PatchListener ): S; // curried invocations with initial state ( recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void, initialState: S ): (currentState: S | void, a: A, b: B, c: C, ...extraArgs: any[]) => S; // curried invocations without initial state ( recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void ): (currentState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S; } interface IProduceWithPatches { /** * Like `produce`, but instead of just returning the new state, * a tuple is returned with [nextState, patches, inversePatches] * * Like produce, this function supports currying */ ( currentState: S, recipe: (draftState: S) => S | void ): [S, Patch[], Patch[]]; // curried invocations with initial state ( recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void, initialState: S ): (currentState: S | void, a: A, b: B, c: C, ...extraArgs: any[]) => [S, Patch[], Patch[]]; // curried invocations without initial state ( recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void ): (currentState: S, a: A, b: B, c: C, ...extraArgs: any[]) => [S, Patch[], Patch[]]; } declare export var produce: IProduce declare export var produceWithPatches: IProduceWithPatches declare export var nothing: typeof undefined declare export var immerable: Symbol /** * Automatically freezes any state trees generated by immer. * This protects against accidental modifications of the state tree outside of an immer function. * This comes with a performance impact, so it is recommended to disable this option in production. * By default it is turned on during local development, and turned off in production. */ declare export function setAutoFreeze(autoFreeze: boolean): void /** * Pass false to disable strict shallow copy. * * By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties. */ declare export function setUseStrictShallowCopy(useStrictShallowCopy: boolean): void declare export function applyPatches(state: S, patches: Patch[]): S declare export function original(value: S): S declare export function current(value: S): S declare export function isDraft(value: any): boolean /** * Creates a mutable draft from an (immutable) object / array. * The draft can be modified until `finishDraft` is called */ declare export function createDraft(base: T): T /** * Given a draft that was created using `createDraft`, * finalizes the draft into a new immutable object. * Optionally a patch-listener can be provided to gather the patches that are needed to construct the object. */ declare export function finishDraft(base: T, listener?: PatchListener): T declare export function enableMapSet(): void declare export function enablePatches(): void declare export function enableArrayMethods(): void declare export function freeze(obj: T, freeze?: boolean): T ================================================ FILE: src/types/types-external.ts ================================================ import {NOTHING} from "../internal" type AnyFunc = (...args: any[]) => any type PrimitiveType = number | string | boolean /** Object types that should never be mapped */ type AtomicObject = Function | Promise | Date | RegExp /** * If the lib "ES2015.Collection" is not included in tsconfig.json, * types like ReadonlyArray, WeakMap etc. fall back to `any` (specified nowhere) * or `{}` (from the node types), in both cases entering an infinite recursion in * pattern matching type mappings * This type can be used to cast these types to `void` in these cases. */ export type IfAvailable = // fallback if any true | false extends (T extends never ? true : false) ? Fallback // fallback if empty type : keyof T extends never ? Fallback // original type : T /** * These should also never be mapped but must be tested after regular Map and * Set */ type WeakReferences = IfAvailable> | IfAvailable> export type WritableDraft = T extends any[] ? number extends T["length"] ? Draft[] : WritableNonArrayDraft : WritableNonArrayDraft type WritableNonArrayDraft = { -readonly [K in keyof T]: T[K] extends infer V ? V extends object ? Draft : V : never } /** Convert a readonly type into a mutable type, if possible */ export type Draft = T extends PrimitiveType ? T : T extends AtomicObject ? T : T extends ReadonlyMap // Map extends ReadonlyMap ? Map, Draft> : T extends ReadonlySet // Set extends ReadonlySet ? Set> : T extends WeakReferences ? T : T extends object ? WritableDraft : T /** Convert a mutable type into a readonly type */ export type Immutable = T extends PrimitiveType ? T : T extends AtomicObject ? T : T extends ReadonlyMap // Map extends ReadonlyMap ? ReadonlyMap, Immutable> : T extends ReadonlySet // Set extends ReadonlySet ? ReadonlySet> : T extends WeakReferences ? T : T extends object ? {readonly [K in keyof T]: Immutable} : T export interface Patch { op: "replace" | "remove" | "add" path: (string | number)[] value?: any } export type PatchListener = (patches: Patch[], inversePatches: Patch[]) => void /** Converts `nothing` into `undefined` */ type FromNothing = T extends typeof NOTHING ? undefined : T /** The inferred return type of `produce` */ export type Produced = Return extends void ? Base : FromNothing /** * Utility types */ type PatchesTuple = readonly [T, Patch[], Patch[]] type ValidRecipeReturnType = | State | void | undefined | (State extends undefined ? typeof NOTHING : never) type ReturnTypeWithPatchesIfNeeded< State, UsePatches extends boolean > = UsePatches extends true ? PatchesTuple : State /** * Core Producer inference */ type InferRecipeFromCurried = Curried extends ( base: infer State, ...rest: infer Args ) => any // extra assertion to make sure this is a proper curried function (state, args) => state ? ReturnType extends State ? ( draft: Draft, ...rest: Args ) => ValidRecipeReturnType> : never : never type InferInitialStateFromCurried = Curried extends ( base: infer State, ...rest: any[] ) => any // extra assertion to make sure this is a proper curried function (state, args) => state ? State : never type InferCurriedFromRecipe< Recipe, UsePatches extends boolean > = Recipe extends (draft: infer DraftState, ...args: infer RestArgs) => any // verify return type ? ReturnType extends ValidRecipeReturnType ? ( base: Immutable, ...args: RestArgs ) => ReturnTypeWithPatchesIfNeeded // N.b. we return mutable draftstate, in case the recipe's first arg isn't read only, and that isn't expected as output either : never // incorrect return type : never // not a function type InferCurriedFromInitialStateAndRecipe< State, Recipe, UsePatches extends boolean > = Recipe extends ( draft: Draft, ...rest: infer RestArgs ) => ValidRecipeReturnType ? ( base?: State | undefined, ...args: RestArgs ) => ReturnTypeWithPatchesIfNeeded : never // recipe doesn't match initial state /** * The `produce` function takes a value and a "recipe function" (whose * return value often depends on the base state). The recipe function is * free to mutate its first argument however it wants. All mutations are * only ever applied to a __copy__ of the base state. * * Pass only a function to create a "curried producer" which relieves you * from passing the recipe function every time. * * Only plain objects and arrays are made mutable. All other objects are * considered uncopyable. * * Note: This function is __bound__ to its `Immer` instance. * * @param {any} base - the initial state * @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified * @param {Function} patchListener - optional function that will be called with all the patches produced here * @returns {any} a new state, or the initial state if nothing was modified */ export interface IProduce { /** Curried producer that infers the recipe from the curried output function (e.g. when passing to setState) */ ( recipe: InferRecipeFromCurried, initialState?: InferInitialStateFromCurried ): Curried /** Curried producer that infers curried from the recipe */ (recipe: Recipe): InferCurriedFromRecipe< Recipe, false > /** Curried producer that infers curried from the State generic, which is explicitly passed in. */ ( recipe: ( state: Draft, initialState: State ) => ValidRecipeReturnType ): (state?: State) => State ( recipe: ( state: Draft, ...args: Args ) => ValidRecipeReturnType, initialState: State ): (state?: State, ...args: Args) => State (recipe: (state: Draft) => ValidRecipeReturnType): ( state: State ) => State ( recipe: (state: Draft, ...args: Args) => ValidRecipeReturnType ): (state: State, ...args: Args) => State /** Curried producer with initial state, infers recipe from initial state */ ( recipe: Recipe, initialState: State ): InferCurriedFromInitialStateAndRecipe /** Normal producer */ >( // By using a default inferred D, rather than Draft in the recipe, we can override it. base: Base, recipe: (draft: D) => ValidRecipeReturnType, listener?: PatchListener ): Base } /** * Like `produce`, but instead of just returning the new state, * a tuple is returned with [nextState, patches, inversePatches] * * Like produce, this function supports currying */ export interface IProduceWithPatches { // Types copied from IProduce, wrapped with PatchesTuple (recipe: Recipe): InferCurriedFromRecipe ( recipe: Recipe, initialState: State ): InferCurriedFromInitialStateAndRecipe >( base: Base, recipe: (draft: D) => ValidRecipeReturnType, listener?: PatchListener ): PatchesTuple } /** * The type for `recipe function` */ export type Producer = (draft: Draft) => ValidRecipeReturnType> // Fixes #507: bili doesn't export the types of this file if there is no actual source in it.. // hopefully it get's tree-shaken away for everyone :) export function never_used() {} ================================================ FILE: src/types/types-internal.ts ================================================ import { SetState, ImmerScope, ProxyObjectState, ProxyArrayState, MapState, DRAFT_STATE, Patch, PatchPath } from "../internal" export type Objectish = AnyObject | AnyArray | AnyMap | AnySet export type ObjectishNoSet = AnyObject | AnyArray | AnyMap export type AnyObject = {[key: string]: any} export type AnyArray = Array export type AnySet = Set export type AnyMap = Map export const enum ArchType { Object, Array, Map, Set } export interface ImmerBaseState { parent_?: ImmerState scope_: ImmerScope modified_: boolean finalized_: boolean isManual_: boolean assigned_: Map | undefined key_?: string | number | symbol callbacks_: ((scope: ImmerScope) => void)[] draftLocations_?: Map } export type ImmerState = | ProxyObjectState | ProxyArrayState | MapState | SetState // The _internal_ type used for drafts (not to be confused with Draft, which is public facing) export type Drafted = { [DRAFT_STATE]: T } & Base export type GeneratePatches = ( state: ImmerState, basePath: PatchPath, patches: Patch[], inversePatches: Patch[] ) => void ================================================ FILE: src/utils/common.ts ================================================ import { DRAFT_STATE, DRAFTABLE, Objectish, Drafted, AnyObject, AnyMap, AnySet, ImmerState, ArchType, die, StrictMode } from "../internal" const O = Object export const getPrototypeOf = O.getPrototypeOf export const CONSTRUCTOR = "constructor" export const PROTOTYPE = "prototype" export const CONFIGURABLE = "configurable" export const ENUMERABLE = "enumerable" export const WRITABLE = "writable" export const VALUE = "value" /** Returns true if the given value is an Immer draft */ /*#__PURE__*/ export let isDraft = (value: any): boolean => !!value && !!value[DRAFT_STATE] /** Returns true if the given value can be drafted by Immer */ /*#__PURE__*/ export function isDraftable(value: any): boolean { if (!value) return false return ( isPlainObject(value) || isArray(value) || !!value[DRAFTABLE] || !!value[CONSTRUCTOR]?.[DRAFTABLE] || isMap(value) || isSet(value) ) } const objectCtorString = O[PROTOTYPE][CONSTRUCTOR].toString() const cachedCtorStrings = new WeakMap() /*#__PURE__*/ export function isPlainObject(value: any): boolean { if (!value || !isObjectish(value)) return false const proto = getPrototypeOf(value) if (proto === null || proto === O[PROTOTYPE]) return true const Ctor = O.hasOwnProperty.call(proto, CONSTRUCTOR) && proto[CONSTRUCTOR] if (Ctor === Object) return true if (!isFunction(Ctor)) return false let ctorString = cachedCtorStrings.get(Ctor) if (ctorString === undefined) { ctorString = Function.toString.call(Ctor) cachedCtorStrings.set(Ctor, ctorString) } return ctorString === objectCtorString } /** Get the underlying object that is represented by the given draft */ /*#__PURE__*/ export function original(value: T): T | undefined export function original(value: Drafted): any { if (!isDraft(value)) die(15, value) return value[DRAFT_STATE].base_ } /** * Each iterates a map, set or array. * Or, if any other kind of object, all of its own properties. * * @param obj The object to iterate over * @param iter The iterator function * @param strict When true (default), includes symbols and non-enumerable properties. * When false, uses looseiteration over only enumerable string properties. */ export function each( obj: T, iter: (key: string | number, value: any, source: T) => void, strict?: boolean ): void export function each(obj: any, iter: any, strict: boolean = true) { if (getArchtype(obj) === ArchType.Object) { // If strict, we do a full iteration including symbols and non-enumerable properties // Otherwise, we only iterate enumerable string properties for performance const keys = strict ? Reflect.ownKeys(obj) : O.keys(obj) keys.forEach(key => { iter(key, obj[key], obj) }) } else { obj.forEach((entry: any, index: any) => iter(index, entry, obj)) } } /*#__PURE__*/ export function getArchtype(thing: any): ArchType { const state: undefined | ImmerState = thing[DRAFT_STATE] return state ? state.type_ : isArray(thing) ? ArchType.Array : isMap(thing) ? ArchType.Map : isSet(thing) ? ArchType.Set : ArchType.Object } /*#__PURE__*/ export let has = ( thing: any, prop: PropertyKey, type = getArchtype(thing) ): boolean => type === ArchType.Map ? thing.has(prop) : O[PROTOTYPE].hasOwnProperty.call(thing, prop) /*#__PURE__*/ export let get = ( thing: AnyMap | AnyObject, prop: PropertyKey, type = getArchtype(thing) ): any => // @ts-ignore type === ArchType.Map ? thing.get(prop) : thing[prop] /*#__PURE__*/ export let set = ( thing: any, propOrOldValue: PropertyKey, value: any, type = getArchtype(thing) ) => { if (type === ArchType.Map) thing.set(propOrOldValue, value) else if (type === ArchType.Set) { thing.add(value) } else thing[propOrOldValue] = value } /*#__PURE__*/ export function is(x: any, y: any): boolean { // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js if (x === y) { return x !== 0 || 1 / x === 1 / y } else { return x !== x && y !== y } } export let isArray = Array.isArray /*#__PURE__*/ export let isMap = (target: any): target is AnyMap => target instanceof Map /*#__PURE__*/ export let isSet = (target: any): target is AnySet => target instanceof Set export let isObjectish = (target: any) => typeof target === "object" export let isFunction = (target: any): target is Function => typeof target === "function" export let isBoolean = (target: any): target is boolean => typeof target === "boolean" export function isArrayIndex(value: string | number): value is number | string { const n = +value return Number.isInteger(n) && String(n) === value } export let getProxyDraft = (value: T): ImmerState | null => { if (!isObjectish(value)) return null return (value as {[DRAFT_STATE]: any})?.[DRAFT_STATE] } /*#__PURE__*/ export let latest = (state: ImmerState): any => state.copy_ || state.base_ export let getValue = (value: T): T => { const proxyDraft = getProxyDraft(value) return proxyDraft ? proxyDraft.copy_ ?? proxyDraft.base_ : value } export let getFinalValue = (state: ImmerState): any => state.modified_ ? state.copy_ : state.base_ /*#__PURE__*/ export function shallowCopy(base: any, strict: StrictMode) { if (isMap(base)) { return new Map(base) } if (isSet(base)) { return new Set(base) } if (isArray(base)) return Array[PROTOTYPE].slice.call(base) const isPlain = isPlainObject(base) if (strict === true || (strict === "class_only" && !isPlain)) { // Perform a strict copy const descriptors = O.getOwnPropertyDescriptors(base) delete descriptors[DRAFT_STATE as any] let keys = Reflect.ownKeys(descriptors) for (let i = 0; i < keys.length; i++) { const key: any = keys[i] const desc = descriptors[key] if (desc[WRITABLE] === false) { desc[WRITABLE] = true desc[CONFIGURABLE] = true } // like object.assign, we will read any _own_, get/set accessors. This helps in dealing // with libraries that trap values, like mobx or vue // unlike object.assign, non-enumerables will be copied as well if (desc.get || desc.set) descriptors[key] = { [CONFIGURABLE]: true, [WRITABLE]: true, // could live with !!desc.set as well here... [ENUMERABLE]: desc[ENUMERABLE], [VALUE]: base[key] } } return O.create(getPrototypeOf(base), descriptors) } else { // perform a sloppy copy const proto = getPrototypeOf(base) if (proto !== null && isPlain) { return {...base} // assumption: better inner class optimization than the assign below } const obj = O.create(proto) return O.assign(obj, base) } } /** * Freezes draftable objects. Returns the original object. * By default freezes shallowly, but if the second argument is `true` it will freeze recursively. * * @param obj * @param deep */ export function freeze(obj: T, deep?: boolean): T export function freeze(obj: any, deep: boolean = false): T { if (isFrozen(obj) || isDraft(obj) || !isDraftable(obj)) return obj if (getArchtype(obj) > 1 /* Map or Set */) { O.defineProperties(obj, { set: dontMutateMethodOverride, add: dontMutateMethodOverride, clear: dontMutateMethodOverride, delete: dontMutateMethodOverride }) } O.freeze(obj) if (deep) // See #590, don't recurse into non-enumerable / Symbol properties when freezing // So use Object.values (only string-like, enumerables) instead of each() each( obj, (_key, value) => { freeze(value, true) }, false ) return obj } function dontMutateFrozenCollections() { die(2) } const dontMutateMethodOverride = { [VALUE]: dontMutateFrozenCollections } export function isFrozen(obj: any): boolean { // Fast path: primitives and null/undefined are always "frozen" if (obj === null || !isObjectish(obj)) return true return O.isFrozen(obj) } ================================================ FILE: src/utils/env.ts ================================================ // Should be no imports here! /** * The sentinel value returned by producers to replace the draft with undefined. */ export const NOTHING: unique symbol = Symbol.for("immer-nothing") /** * To let Immer treat your class instances as plain immutable objects * (albeit with a custom prototype), you must define either an instance property * or a static property on each of your custom classes. * * Otherwise, your class instance will never be drafted, which means it won't be * safe to mutate in a produce callback. */ export const DRAFTABLE: unique symbol = Symbol.for("immer-draftable") export const DRAFT_STATE: unique symbol = Symbol.for("immer-state") ================================================ FILE: src/utils/errors.ts ================================================ import {isFunction} from "../internal" export const errors = process.env.NODE_ENV !== "production" ? [ // All error codes, starting by 0: function(plugin: string) { return `The plugin for '${plugin}' has not been loaded into Immer. To enable the plugin, import and call \`enable${plugin}()\` when initializing your application.` }, function(thing: string) { return `produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '${thing}'` }, "This object has been frozen and should not be mutated", function(data: any) { return ( "Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + data ) }, "An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.", "Immer forbids circular references", "The first or second argument to `produce` must be a function", "The third argument to `produce` must be a function or undefined", "First argument to `createDraft` must be a plain object, an array, or an immerable object", "First argument to `finishDraft` must be a draft returned by `createDraft`", function(thing: string) { return `'current' expects a draft, got: ${thing}` }, "Object.defineProperty() cannot be used on an Immer draft", "Object.setPrototypeOf() cannot be used on an Immer draft", "Immer only supports deleting array indices", "Immer only supports setting array indices and the 'length' property", function(thing: string) { return `'original' expects a draft, got: ${thing}` } // Note: if more errors are added, the errorOffset in Patches.ts should be increased // See Patches.ts for additional errors ] : [] export function die(error: number, ...args: any[]): never { if (process.env.NODE_ENV !== "production") { const e = errors[error] const msg = isFunction(e) ? e.apply(null, args as any) : e throw new Error(`[Immer] ${msg}`) } throw new Error( `[Immer] minified error nr: ${error}. Full error at: https://bit.ly/3cXEKWf` ) } ================================================ FILE: src/utils/plugins.ts ================================================ import { ImmerState, Patch, Drafted, ImmerBaseState, AnyMap, AnySet, ArchType, die, ImmerScope, ProxyArrayState } from "../internal" export const PluginMapSet = "MapSet" export const PluginPatches = "Patches" export const PluginArrayMethods = "ArrayMethods" export type PatchesPlugin = { generatePatches_( state: ImmerState, basePath: PatchPath, rootScope: ImmerScope ): void generateReplacementPatches_( base: any, replacement: any, rootScope: ImmerScope ): void applyPatches_(draft: T, patches: readonly Patch[]): T getPath: (state: ImmerState) => PatchPath | null } export type MapSetPlugin = { proxyMap_(target: T, parent?: ImmerState): [T, ImmerState] proxySet_(target: T, parent?: ImmerState): [T, ImmerState] fixSetContents: (state: ImmerState) => void } export type ArrayMethodsPlugin = { createMethodInterceptor: (state: ProxyArrayState, method: string) => Function isArrayOperationMethod: (method: string) => boolean isMutatingArrayMethod: (method: string) => boolean } /** Plugin utilities */ const plugins: { Patches?: PatchesPlugin MapSet?: MapSetPlugin ArrayMethods?: ArrayMethodsPlugin } = {} type Plugins = typeof plugins export function getPlugin( pluginKey: K ): Exclude { const plugin = plugins[pluginKey] if (!plugin) { die(0, pluginKey) } // @ts-ignore return plugin } export let isPluginLoaded = (pluginKey: K): boolean => !!plugins[pluginKey] export let clearPlugin = (pluginKey: K): void => { delete plugins[pluginKey] } export function loadPlugin( pluginKey: K, implementation: Plugins[K] ): void { if (!plugins[pluginKey]) plugins[pluginKey] = implementation } /** Map / Set plugin */ export interface MapState extends ImmerBaseState { type_: ArchType.Map copy_: AnyMap | undefined base_: AnyMap revoked_: boolean draft_: Drafted } export interface SetState extends ImmerBaseState { type_: ArchType.Set copy_: AnySet | undefined base_: AnySet drafts_: Map // maps the original value to the draft value in the new set revoked_: boolean draft_: Drafted } /** Patches plugin */ export type PatchPath = (string | number)[] ================================================ FILE: tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "strict": true, "declaration": true, "importHelpers": false, "noImplicitAny": true, "esModuleInterop": true, "noUnusedLocals": false, "sourceMap": true, "declarationMap": true, "noEmit": true, "module": "ES6", "allowJs": true }, "files": ["./src/immer.ts", "./src/plugins/mapset.ts", "./src/plugins/patches.ts", "src/types/globals.d.ts"] } ================================================ FILE: tsup.config.ts ================================================ import {defineConfig, Options} from "tsup" import fs from "fs" export default defineConfig(options => { const commonOptions: Partial = { entry: { immer: "src/immer.ts" }, sourcemap: true, ...options } const productionOptions = { minify: true, esbuildOptions(options, _context) { options.mangleProps = /_$/ }, define: { "process.env.NODE_ENV": JSON.stringify("production") } } return [ // ESM, standard bundler dev, embedded `process` references { ...commonOptions, format: ["esm"], dts: true, clean: true, sourcemap: true, onSuccess() { // Support Flow types fs.copyFileSync("src/types/index.js.flow", "dist/cjs/index.js.flow") } }, // ESM, Webpack 4 support. Target ES2018 syntax to compile away optional chaining and spreads { ...commonOptions, entry: { "immer.legacy-esm": "src/immer.ts" }, // ESBuild outputs `'.mjs'` by default for the 'esm' format. Force '.js' outExtension: () => ({js: ".js"}), target: "es2017", format: ["esm"], sourcemap: true }, // ESM for use in browsers. Minified, with `process` compiled away { ...commonOptions, ...productionOptions, entry: { "immer.production": "src/immer.ts" }, format: ["esm"], outExtension: () => ({js: ".mjs"}) }, // CJS development { ...commonOptions, entry: { "immer.cjs.development": "src/immer.ts" }, format: "cjs", outDir: "./dist/cjs/" }, // CJS production { ...commonOptions, ...productionOptions, entry: { "immer.cjs.production": "src/immer.ts" }, format: "cjs", outDir: "./dist/cjs/", onSuccess: () => { // Write the CJS index file fs.writeFileSync( "dist/cjs/index.js", ` 'use strict' if (process.env.NODE_ENV === 'production') { module.exports = require('./immer.cjs.production.js') } else { module.exports = require('./immer.cjs.development.js') }` ) } } ] }) ================================================ FILE: vitest-custom-reporter.ts ================================================ import {Reporter} from "vitest" export default class CustomReporter implements Reporter { onFinished(files: any[], errors: unknown[]) { // Replicate the logic from ignoreObseleteSnapshots.js // Don't count obsolete snapshots as failures, just check if there are no failing tests const hasFailingTests = files.some( (file: any) => file.result?.state === "fail" && file.tasks?.some((task: any) => task.result?.state === "fail") ) if (!hasFailingTests && errors.length === 0) { // Override success status similar to the original Jest processor process.exitCode = 0 } } } ================================================ FILE: vitest.config.build.ts ================================================ import {defineConfig} from "vitest/config" import path from "path" const prodCJSPath = path.resolve(__dirname, "dist/cjs/immer.cjs.production.js") export default defineConfig({ resolve: { // // Make all `immer` imports use the production build alias: [ { find: /^src\/(.*)/, replacement: prodCJSPath }, { find: "../src/immer", replacement: prodCJSPath }, { find: "immer", replacement: prodCJSPath } ], // Ensure only one copy of immer is used throughout the dependency tree dedupe: ["immer"] }, // Force Vite to process immer so our alias applies to dependencies too optimizeDeps: { include: ["immer"], // Force re-bundling to pick up our alias force: true }, // SSR settings are needed because Vitest runs in Node environment ssr: { // Don't externalize immer - this makes our alias apply to it noExternal: ["immer"] }, define: { "global.USES_BUILD": true, "process.env.NODE_ENV": '"production"' }, test: { environment: "node", include: ["**/__tests__/**/*.[jt]s?(x)"], globals: true, resolveSnapshotPath: (testPath: string, snapExtension: string) => testPath.replace("__tests__", "__tests__/__prod_snapshots__") + snapExtension, reporters: ["default", "./vitest-custom-reporter.ts"], // Ensure deps are processed through Vite's transform pipeline deps: { optimizer: { // For SSR (Node) environment, include immer so it's transformed ssr: { include: ["immer"] } } } } }) ================================================ FILE: vitest.config.ts ================================================ import {defineConfig} from "vitest/config" export default defineConfig({ test: { environment: "node", include: ["**/__tests__/**/*.[jt]s?(x)"], globals: true, setupFiles: [], coverage: { provider: "v8", // default in Vitest 3 reporter: ["text", "lcov"], // add "lcov" here reportsDirectory: "./coverage" // makes sure lcov.info lands here } } }) ================================================ FILE: website/docs/api.md ================================================ --- id: api title: API overview ---
| Exported name | Description | Section | | --- | --- | --- | | `produce` | The core API of Immer: `import {produce} from "immer"` | [Produce](./produce.mdx) | | `applyPatches` | Given a base state or draft, and a set of patches, applies the patches | [Patches](./patches.mdx) | | `castDraft` | Converts any immutable type to its mutable counterpart. This is just a cast and doesn't actually do anything. | [TypeScript](./typescript.mdx) | | `castImmutable` | Converts any mutable type to its immutable counterpart. This is just a cast and doesn't actually do anything. | [TypeScript](./typescript.mdx) | | `createDraft` | Given a base state, creates a mutable draft for which any modifications will be recorded | [Async](./async.mdx) | | `current` | Given a draft object (doesn't have to be a tree root), takes a snapshot of the current state of the draft | [Current](./current.md) | | `Draft` | Exposed TypeScript type to convert an immutable type to a mutable type | [TypeScript](./typescript.mdx) | | `enableArrayMethods()` | Enables optimized array method handling for improved performance with array-heavy operations. | [Array Methods](./array-methods.md) | | `enableMapSet()` | Enables support for `Map` and `Set` collections. | [Installation](./installation.mdx#pick-your-immer-version) | | `enablePatches()` | Enables support for JSON patches. | [Installation](./installation#pick-your-immer-version) | | `finishDraft` | Given an draft created using `createDraft`, seals the draft and produces and returns the next immutable state that captures all the changes | [Async](./async.mdx) | | `freeze(obj, deep?)` | Freezes draftable objects. Returns the original object. By default freezes shallowly, but if the second argument is `true` it will freeze recursively. | | `Immer` | constructor that can be used to create a second "immer" instance (exposing all APIs listed in this instance), that doesn't share its settings with global instance. | | `immerable` | Symbol that can be added to a constructor or prototype, to indicate that Immer should treat the class as something that can be safely drafted | [Classes](./complex-objects.md) | | `Immutable` | Exposed TypeScript type to convert mutable types to immutable types | | | `isDraft` | Returns true if the given object is a draft object | | | `isDraftable` | Returns true if Immer is capable of turning this object into a draft. Which is true for: arrays, objects without prototype, objects with `Object` as their prototype, objects that have the `immerable` symbol on their constructor or prototype | | | `nothing` | Value that can be returned from a recipe, to indicate that the value `undefined` should be produced | [Return](./return.mdx) | | `original` | Given a draft object (doesn't have to be a tree root), returns the original object at the same path in the original state tree, if present | [Original](./original.md) | | `Patch` | Exposed TypeScript type, describes the shape of an (inverse) patch object | [Patches](./patches.mdx) | | `produceWithPatches` | Works the same as `produce`, but instead of just returning the produced object, it returns a tuple, consisting of `[result, patches, inversePatches]`. | [Patches](./patches.mdx) | | `setAutoFreeze` | Enables / disables automatic freezing of the trees produces. By default enabled. | [Freezing](./freezing.mdx) | | `setUseStrictShallowCopy` | Can be used to enable strict shallow copy. If enable, immer copies non-enumerable properties as much as possible. | [Classes](./complex-objects.md) | | `setUseStrictIteration` | Controls iteration behavior: pass `false` for loose iteration (enumerable properties only, better performance) or `true` for strict iteration (includes symbols and non-enumerable properties). By default disabled (loose iteration). | | ## Importing immer In most cases, the only thing you need to import from Immer is `produce`: ```javascript import {produce} from "immer" ``` Note that in older versions, `produce` was also available as default export (e.g. `import produce from "immer"` was also valid, but that is no longer the case to improve eco system compatibility. ================================================ FILE: website/docs/array-methods.md ================================================ --- id: array-methods title: Array Methods Plugin ---
## Overview The Array Methods Plugin (`enableArrayMethods()`) optimizes array operations within Immer producers by avoiding unnecessary Proxy creation during iteration. This provides significant performance improvements for array-heavy operations. **Why does this matter?** Without the plugin, every array element access during iteration (e.g., in `filter`, `find`, `slice`) creates a Proxy object. For a 1000-element array, this means 1000+ proxy trap invocations just to iterate. With the plugin enabled, callbacks receive base (non-proxied) values, and proxies are only created as needed for mutation tracking. ## Installation Enable the plugin once at your application's entry point: ```javascript import {enableArrayMethods} from "immer" enableArrayMethods() ``` This adds approximately **2KB** to your bundle size. ## Mutating Methods These methods modify the array in-place and operate directly on the draft's internal copy without creating per-element proxies: | Method | Returns | Description | | ----------- | ---------------- | ------------------------------------- | | `push()` | New length | Adds elements to the end | | `pop()` | Removed element | Removes and returns the last element | | `shift()` | Removed element | Removes and returns the first element | | `unshift()` | New length | Adds elements to the beginning | | `splice()` | Removed elements | Adds/removes elements at any position | | `sort()` | The draft array | Sorts elements in place | | `reverse()` | The draft array | Reverses the array in place | ```javascript import {produce, enableArrayMethods} from "immer" enableArrayMethods() const base = {items: [3, 1, 4, 1, 5]} const result = produce(base, draft => { draft.items.push(9) // Adds 9 to end draft.items.sort() // Sorts: [1, 1, 3, 4, 5, 9] draft.items.reverse() // Reverses: [9, 5, 4, 3, 1, 1] }) ``` ## Non-Mutating Methods Non-mutating methods are categorized based on what they return: ### Subset Operations (Return Drafts) These methods select items that exist in the original array and **create draft proxies** for the returned items. The callbacks receive **base values** (the optimization), but the **returned array** contains newly created draft proxies that point back to the original positions. **Mutations to returned items WILL affect the draft state.** | Method | Returns | Drafts? | | ------------ | ---------------------------------- | ------- | | `filter()` | Array of matching items | ✅ Yes | | `slice()` | Array of items in range | ✅ Yes | | `find()` | First matching item or `undefined` | ✅ Yes | | `findLast()` | Last matching item or `undefined` | ✅ Yes | ```javascript const base = { items: [ {id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 30} ] } const result = produce(base, draft => { // filter returns drafts - mutations track back to original const filtered = draft.items.filter(item => item.value > 15) filtered[0].value = 999 // This WILL affect draft.items[1] // find returns a draft - mutations track back const found = draft.items.find(item => item.id === 3) if (found) { found.value = 888 // This WILL affect draft.items[2] } // slice returns drafts const sliced = draft.items.slice(0, 2) sliced[0].value = 777 // This WILL affect draft.items[0] }) console.log(result.items[0].value) // 777 console.log(result.items[1].value) // 999 console.log(result.items[2].value) // 888 ``` ### Transform Operations (Return Base Values) These methods create **new arrays** that may include external items or restructured data. They return **base values**, NOT drafts. **Mutations to returned items will NOT track back to the draft state.** | Method | Returns | Drafts? | | ---------- | ------------------- | ------- | | `concat()` | New combined array | ❌ No | | `flat()` | New flattened array | ❌ No | ```javascript const base = {items: [{id: 1, value: 10}]} const result = produce(base, draft => { // concat returns base values - mutations DON'T track const concatenated = draft.items.concat([{id: 2, value: 20}]) concatenated[0].value = 999 // This will NOT affect draft.items[0] // To actually use concat results, assign them: draft.items = draft.items.concat([{id: 2, value: 20}]) }) // Original unchanged because concat result wasn't assigned console.log(result.items[0].value) // 10 (unchanged) ``` **Why the distinction?** - **Subset operations** (`filter`, `slice`, `find`) select items that exist in the original array. Returning drafts allows mutations to propagate back to the source. - **Transform operations** (`concat`, `flat`) create new data structures that may include external items or restructured data, making draft tracking impractical. ### Primitive-Returning Methods These methods return primitive values (numbers, booleans, strings). No tracking issues since primitives aren't draftable: | Method | Returns | | ------------------ | -------------------- | | `indexOf()` | Number (index or -1) | | `lastIndexOf()` | Number (index or -1) | | `includes()` | Boolean | | `some()` | Boolean | | `every()` | Boolean | | `findIndex()` | Number (index or -1) | | `findLastIndex()` | Number (index or -1) | | `join()` | String | | `toString()` | String | | `toLocaleString()` | String | ```javascript const base = { items: [ {id: 1, active: true}, {id: 2, active: false} ] } const result = produce(base, draft => { const index = draft.items.findIndex(item => item.id === 2) const hasActive = draft.items.some(item => item.active) const allActive = draft.items.every(item => item.active) console.log(index) // 1 console.log(hasActive) // true console.log(allActive) // false }) ``` ## Methods NOT Overridden The following methods are **not** intercepted by the plugin and work through standard Proxy behavior. Callbacks receive drafts, and mutations track normally: | Method | Description | | --------------- | --------------------------------- | | `map()` | Transform each element | | `flatMap()` | Map then flatten | | `forEach()` | Execute callback for each element | | `reduce()` | Reduce to single value | | `reduceRight()` | Reduce from right to left | ```javascript const base = { items: [ {id: 1, value: 10, nested: {count: 0}}, {id: 2, value: 20, nested: {count: 0}} ] } const result = produce(base, draft => { // forEach receives drafts - mutations work normally draft.items.forEach(item => { item.value *= 2 }) // map is NOT overridden - callbacks receive drafts // The returned array items are also drafts (extracted from draft.items) const mapped = draft.items.map(item => item.nested) // Mutations to the result array propagate back mapped[0].count = 999 // ✅ This affects draft.items[0].nested.count }) console.log(result.items[0].nested.count) // 999 ``` ## Callback Behavior For overridden methods, callbacks receive **base values** (not drafts). This is the core optimization - it avoids creating proxies for every element during iteration. ```javascript const base = { items: [ {id: 1, value: 10}, {id: 2, value: 20} ] } produce(base, draft => { draft.items.filter(item => { // `item` is a base value here, NOT a draft // Reading properties works fine return item.value > 15 // But direct mutation here won't be tracked: // item.value = 999 // ❌ Won't affect draft }) // Instead, use the returned draft: const filtered = draft.items.filter(item => item.value > 15) filtered[0].value = 999 // ✅ This works because filtered[0] is a draft }) ``` ## Method Return Behavior Summary | Category | Methods | Returns | Mutations Track? | | --- | --- | --- | --- | | **Subset** | `filter`, `slice`, `find`, `findLast` | Draft proxies | ✅ Yes | | **Transform** | `concat`, `flat` | Base values | ❌ No | | **Primitive** | `indexOf`, `includes`, `some`, `every`, `findIndex`, `findLastIndex`, `lastIndexOf`, `join`, `toString`, `toLocaleString` | Primitives | N/A | | **Mutating** | `push`, `pop`, `shift`, `unshift`, `splice`, `sort`, `reverse` | Various | ✅ Yes (modifies draft) | | **Not Overridden** | `map`, `flatMap`, `forEach`, `reduce`, `reduceRight` | Standard behavior | ✅ Yes (callbacks get drafts) | ## When to Use Enable the Array Methods Plugin when: - Your application has significant array iteration within producers - You frequently use methods like `filter`, `find`, `some`, `every` on large arrays - Performance profiling shows array operations as a bottleneck The plugin is most beneficial for: - Large arrays (100+ elements) - Frequent producer calls with array operations - Read-heavy operations (filtering, searching) where most elements aren't modified ## Performance Benefit **Without the plugin:** - Every array element access during iteration creates a Proxy - A `filter()` on 1000 elements = 1000+ proxy creations **With the plugin:** - Callbacks receive base values directly - Proxies only created for the specific elements you actually mutate, or that match filtering predicates ```javascript // Without plugin: ~3000+ proxy trap invocations // With plugin: ~10-20 proxy trap invocations const result = produce(largeState, draft => { const filtered = draft.items.filter(x => x.value > threshold) // Only items you mutate get proxied filtered.forEach(item => { item.processed = true }) }) ``` ================================================ FILE: website/docs/async.mdx ================================================ --- id: async title: createDraft / finishDraft sidebar_label: createDraft / finishDraft ---
egghead.io lesson 11: Creating async producers (and why you shouldn’t)
Hosted on egghead.io
## `createDraft` and `finishDraft` `createDraft` and `finishDraft` are two low-level functions that are mostly useful for libraries that build abstractions on top of immer. It avoids the need to always create a function in order to work with drafts. Instead, one can create a draft, modify it, and at some time in the future finish the draft, in which case the next immutable state will be produced. Beyond that, `createDraft` / `finishDraft` could be used to express async updates to drafts: ```javascript import {createDraft, finishDraft} from "immer" const user = { name: "michel", todos: [] } const draft = createDraft(user) draft.todos = await (await window.fetch("http://host/" + draft.name)).json() const loadedUser = finishDraft(draft) ``` Note: The above is an anti-pattern! First fetch data instead, then draft the `user`. Otherwise updates to user that happen during the async process, would be "missed" by the draft. Note: `finishDraft` takes a `patchListener` as second argument, which can be used to record the patches, similarly to `produce`. _Warning: in general, we recommend to use `produce` instead of the `createDraft` / `finishDraft` combo, `produce` is less error prone in usage, and more clearly separates the concepts of mutability and immutability in your code base._ ================================================ FILE: website/docs/built-with.md ================================================ --- id: built-with title: Built with Immer ---
- [react-copy-write](https://github.com/aweary/react-copy-write) _Immutable state with a mutable API_ - [redux-toolkit](https://github.com/reduxjs/redux-toolkit) _The official, opinionated, batteries-included toolset for efficient Redux development_ - [immer based handleActions](https://gist.github.com/kitze/fb65f527803a93fb2803ce79a792fff8) _Boilerplate free actions for Redux_ - [redux-box](https://github.com/anish000kumar/redux-box) _Modular and easy-to-grasp redux based state management, with least boilerplate_ - [quick-redux](https://github.com/jeffreyyoung/quick-redux) _tools to make redux development quicker and easier_ - [bey](https://github.com/jamiebuilds/bey) _Simple immutable state for React using Immer_ - [cool-store](https://github.com/Maxvien/cool-store) _CoolStore is an immutable state store built on top of ImmerJS and RxJS_ - [immer-wieder](https://github.com/drcmda/immer-wieder#readme) _State management lib that combines React 16 Context and immer for Redux semantics_ - [robodux](https://github.com/neurosnap/robodux) _flexible way to reduce redux boilerplate_ - [immer-reducer](https://github.com/epeli/immer-reducer) _Type-safe and terse React (useReducer()) and Redux reducers with Typescript_ - [redux-ts-utils](https://github.com/knpwrs/redux-ts-utils) _Everything you need to create type-safe applications with Redux with a strong emphasis on simplicity_ - [react-state-tree](https://github.com/suchipi/react-state-tree) _Drop-in replacement for useState that persists your state into a redux-like state tree_ - [redux-immer](https://github.com/salvoravida/redux-immer) _is used to create an equivalent function of Redux combineReducers that works with `immer` state. Like `redux-immutable` but for `immer`_ - [ngrx-wieder](https://github.com/nilsmehlhorn/ngrx-wieder) _Lightweight yet configurable solution for implementing undo-redo in Angular apps on top of NgRx and Immer_ - [immer-yjs](https://github.com/sep2/immer-yjs) _Combine `immer` with CRDT library `y.js` for easy json data manipulation_ - [immerhin](https://github.com/webstudio-is/immerhin) Sync state with undo/redo - ... and [many more](https://www.npmjs.com/browse/depended/immer) ================================================ FILE: website/docs/complex-objects.md ================================================ --- id: complex-objects title: Classes ---
Plain objects (objects without a prototype), arrays, `Map`s and `Set`s are always drafted by Immer. Every other object must use the `immerable` symbol to mark itself as compatible with Immer. When one of these objects is mutated within a producer, its prototype is preserved between copies. ```js import {immerable} from "immer" class Foo { [immerable] = true // Option 1 constructor() { this[immerable] = true // Option 2 } } Foo[immerable] = true // Option 3 ``` ### Example ```js import {immerable, produce} from "immer" class Clock { [immerable] = true constructor(hour, minute) { this.hour = hour this.minute = minute } get time() { return `${this.hour}:${this.minute}` } tick() { return produce(this, draft => { draft.minute++ }) } } const clock1 = new Clock(12, 10) const clock2 = clock1.tick() console.log(clock1.time) // 12:10 console.log(clock2.time) // 12:11 console.log(clock2 instanceof Clock) // true ``` ### Semantics in detail The semantics on how classes are drafted are as follows: 1. A draft of a class is a fresh object but with the same prototype as the original object. 1. When creating a draft, Immer will copy all _own_ properties from the base to the draft.This includes (in strict mode) non-enumerable and symbolic properties. 1. _Own_ getters will be invoked during the copy process, just like `Object.assign` would. 1. Inherited getters and methods will remain as is and be inherited by the draft, as they are stored on the prototype which is untouched. 1. Immer will not invoke constructor functions. 1. The final instance will be constructed with the same mechanism as the draft was created. 1. Only getters that have a setter as well will be writable in the draft, as otherwise the value can't be copied back. Because Immer will dereference own getters of objects into normal properties, it is possible to use objects that use getter/setter traps on their fields, like MobX and Vue do. Note that, by default, Immer does not strictly handle object's non-enumerable properties such as getters/setters for performance reason. If you want this behavior to be strict, you can opt-in with `useStrictShallowCopy(config)`. Use `true` to always copy strict, or `"class_only"` to only copy class instances strictly but use the faster loose copying for plain objects. The default is `false`. (Remember, regardless of strict mode, own getters / setters are always copied _by value_. There is currently no config to copy descriptors as-is. Feature request / PR welcome). Immer does not support exotic / engine native objects such as DOM Nodes or Buffers, nor is subclassing Map, Set or arrays supported and the `immerable` symbol can't be used on them. So when working for example with `Date` objects, you should always create a new `Date` instance instead of mutating an existing `Date` object. ================================================ FILE: website/docs/current.md ================================================ --- id: current title: Extracting the current state from a draft sidebar_label: Current ---
Immer exposes a named export `current` that creates a copy of the current state of the draft. This can be very useful for debugging purposes (as those objects won't be Proxy objects and not be logged as such). Also, references to `current` can be safely leaked from a produce function. Put differently, `current` provides a snapshot of the current state of a draft. Objects generated by `current` work similar to the objects created by produce itself. 1. Unmodified objects will be structurally shared with the original objects. 1. If no changes are made to a draft, generally it holds that `original(draft) === current(draft)`, but this is not guaranteed. 1. Future changes to the draft won't be reflected in the object produced by `current` (except for references to undraftable objects) 1. Unlike `produce` objects created by `current` will _not_ be frozen. Use `current` sparingly, it can be a potentially expensive operation, especially when using ES5. Note that `current` cannot be invoked on objects that aren't drafts. ### Example The following example shows the effect of `current` (and `original`): ```js const base = { x: 0 } const next = produce(base, draft => { draft.x++ const orig = original(draft) const copy = current(draft) console.log(orig.x) console.log(copy.x) setTimeout(() => { // this will execute after the produce has finished! console.log(orig.x) console.log(copy.x) }, 100) draft.x++ console.log(draft.x) }) console.log(next.x) // This will print // 0 (orig.x) // 1 (copy.x) // 2 (draft.x) // 2 (next.x) // 0 (after timeout, orig.x) // 1 (after timeout, copy.x) ``` ================================================ FILE: website/docs/curried-produce.mdx ================================================ --- id: curried-produce title: Curried producers ---
egghead.io lesson 6: Simplify code by using curried _reduce_
Hosted on egghead.io
Passing a function as the first argument to `produce` creates a function that doesn't apply `produce` yet to a specific state, but rather creates a function that will apply `produce` to any state that is passed to it in the future. This generally is called _currying_. Take for example the following example: ```javascript import {produce} from "immer" function toggleTodo(state, id) { return produce(state, draft => { const todo = draft.find(todo => todo.id === id) todo.done = !todo.done }) } const baseState = [ { id: "JavaScript", title: "Learn TypeScript", done: true }, { id: "Immer", title: "Try Immer", done: false } ] const nextState = toggleTodo(baseState, "Immer") ``` The above pattern of `toggleTodo` is quite typical; pass an existing state to `produce`, modify the `draft`, and then return the result. Since `state` isn't used for anything else than passing it on to `produce`, the above example can be simplified by using the _curried_ form of `produce`, where you pass `produce` only the recipe function, and `produce` will return a new function that will apply recipe to the base state. This allows us to shorten the above `toggleTodo` definition. ```javascript import {produce} from "immer" // curried producer: const toggleTodo = produce((draft, id) => { const todo = draft.find(todo => todo.id === id) todo.done = !todo.done }) const baseState = [ /* as is */ ] const nextState = toggleTodo(baseState, "Immer") ``` Note that the `id` param has now become part of the recipe function! This pattern of having curried producers combines really neatly with for example the `useState` hook from React, as we will see on the next page. ================================================ FILE: website/docs/example-setstate.mdx ================================================ --- id: example-setstate title: React & Immer ---
egghead.io lesson 8: Using Immer with _useState_. Or: _useImmer_
Hosted on egghead.io
## useState + Immer The `useState` hook assumes any state that is stored inside it is treated as immutable. Deep updates in the state of React components can be greatly simplified as by using Immer. The following example shows how to use `produce` in combination with `useState`, and can be tried on [CodeSandbox](https://codesandbox.io/s/immer-usestate-ujkgg?file=/src/index.js). ```javascript import React, { useCallback, useState } from "react"; import {produce} from "immer"; const TodoList = () => { const [todos, setTodos] = useState([ { id: "React", title: "Learn React", done: true }, { id: "Immer", title: "Try Immer", done: false } ]); const handleToggle = useCallback((id) => { setTodos( produce((draft) => { const todo = draft.find((todo) => todo.id === id); todo.done = !todo.done; }) ); }, []); const handleAdd = useCallback(() => { setTodos( produce((draft) => { draft.push({ id: "todo_" + Math.random(), title: "A new todo", done: false }); }) ); }, []); return (
{*/ See CodeSandbox */}
) } ``` ## useImmer Since all state updaters follow the same pattern where the update function is wrapped in `produce`, it is also possible to simplify the above by leveraging the [use-immer](https://www.npmjs.com/package/use-immer) package that will wrap updater functions in `produce` automatically: ```javascript import React, { useCallback } from "react"; import { useImmer } from "use-immer"; const TodoList = () => { const [todos, setTodos] = useImmer([ { id: "React", title: "Learn React", done: true }, { id: "Immer", title: "Try Immer", done: false } ]); const handleToggle = useCallback((id) => { setTodos((draft) => { const todo = draft.find((todo) => todo.id === id); todo.done = !todo.done; }); }, []); const handleAdd = useCallback(() => { setTodos((draft) => { draft.push({ id: "todo_" + Math.random(), title: "A new todo", done: false }); }); }, []); // etc ``` For the full demo see [CodeSandbox](https://codesandbox.io/s/use-immer-bvd5v?file=/src/index.js). ## useReducer + Immer Similarly to `useState`, `useReducer` combines neatly with Immer as well, as demonstrated in this [CodeSandbox](https://codesandbox.io/s/immer-usereducer-bqpzn?file=/src/index.js:0-1018): ```javascript import React, {useCallback, useReducer} from "react" import {produce} from "immer" const TodoList = () => { const [todos, dispatch] = useReducer( produce((draft, action) => { switch (action.type) { case "toggle": const todo = draft.find(todo => todo.id === action.id) todo.done = !todo.done break case "add": draft.push({ id: action.id, title: "A new todo", done: false }) break default: break } }), [ /* initial todos */ ] ) const handleToggle = useCallback(id => { dispatch({ type: "toggle", id }) }, []) const handleAdd = useCallback(() => { dispatch({ type: "add", id: "todo_" + Math.random() }) }, []) // etc } ``` ## useImmerReducer ...which again, can be slightly shorted by `useImmerReducer` from the `use-immer` package ([demo](https://codesandbox.io/s/useimmerreducer-sycpb?file=/src/index.js)): ```javascript import React, { useCallback } from "react"; import { useImmerReducer } from "use-immer"; const TodoList = () => { const [todos, dispatch] = useImmerReducer( (draft, action) => { switch (action.type) { case "toggle": const todo = draft.find((todo) => todo.id === action.id); todo.done = !todo.done; break; case "add": draft.push({ id: action.id, title: "A new todo", done: false }); break; default: break; } }, [ /* initial todos */ ] ); //etc ``` ## Redux + Immer Redux + Immer is extensively covered in the documentation of [Redux Toolkit](https://redux-toolkit.js.org/usage/immer-reducers). For Redux without Redux Toolkit, the same trick as applied to `useReducer` above can be applied: wrap the reducer function with `produce`, and you can safely mutate the draft! For example: ```javascript import {produce} from "immer" // Reducer with initial state const INITIAL_STATE = [ /* bunch of todos */ ] const todosReducer = produce((draft, action) => { switch (action.type) { case "toggle": const todo = draft.find(todo => todo.id === action.id) todo.done = !todo.done break case "add": draft.push({ id: action.id, title: "A new todo", done: false }) break default: break } }) ``` ================================================ FILE: website/docs/faq.md ================================================ --- id: faq title: Frequently Asked Questions sidebar_label: FAQ ---
## Q: How does Immer work? Read the (second part of the) [introduction blog](https://medium.com/@mweststrate/introducing-immer-immutability-the-easy-way-9d73d8f71cb3). ## Q: Does Immer use structural sharing? So that my selectors can be memoized and such? A: Yes ## Q: Does Immer support deep updates? A: Yes ## Q: I can't rely on Proxies being present on my target environments. Can I use Immer? A: Yes - [view details](./installation.mdx#immer-on-older-javascript-environments) ## Q: Can I typecheck my data structures when using Immer? A: Yes ## Q: Can I store `Date` objects, functions etc in my state tree when using Immer? A: Yes ## Q: Can I use Maps and Sets? A: Yes ## Q: Is it fast? A: Yes ## Q: Idea! Can Immer freeze the state for me? A: Yes ================================================ FILE: website/docs/freezing.mdx ================================================ --- id: freezing title: Auto freezing ---
egghead.io lesson 7: Immer automatically freezes data
Hosted on egghead.io
Immer automatically freezes any state trees that are modified using `produce`. This protects against accidental modifications of the state tree outside of a producer. In most cases this provides the most optimal behavior, but `setAutoFreeze(true / false)` can be used to explicitly turn this feature on or off. Immer will never freeze (the contents of) non-enumerable, non-own or symbolic properties, unless their content was drafted. _⚠️ Immer freezes everything recursively, for large data objects that won't be changed in the future this might be over-kill, in that case it can be more efficient to shallowly pre-freeze data using the `freeze` utility.⚠️_ _⚠️ If auto freezing is enabled, recipes are not entirely side-effect free: Any plain object or array that ends up in the produced result, will be frozen, even when these objects were not frozen before the start of the producer! ⚠️_ ================================================ FILE: website/docs/installation.mdx ================================================ --- id: installation title: Installation ---
Immer can be installed as a direct dependency, and will work in any ES5 environment: - Yarn: `yarn add immer` - NPM: `npm install immer` - CDN: Exposed global is `immer` - Unpkg: `` - JSDelivr: `` - ⚠️ When using a CDN, it is best to check the url in your browser and see what version it resolves to, so that your users aren't accidentally served a newer version in the future when updates are release. So use a url like: https://unpkg.com/immer@6.0.3/dist/immer.umd.production.min.js instead. Substitute `production.min` with `development` in the URL for a development build. ## Pick your Immer version _This section only applies to version 6 and later_ To make sure Immer is as small as possible, features that are not required by every project has been made opt-in, and have to be enabled explicitly. This ensures that when bundling your application for production, unused features don't take any space. The following features can be opt-in to: | Feature | Description | Method to call | | --- | --- | --- | | [Array Methods optimization](./array-methods.md) | Optimizes array method handling for improved performance with array-heavy operations | `enableArrayMethods()` | | [ES2015 Map and Set support](./complex-objects.md) | To enable Immer to operate on the native `Map` and `Set` collections, enable this feature | `enableMapSet()` | | [JSON Patch support](./patches.mdx) | Immer can keep track of all the changes you make to draft objects. This can be useful for communicating changes using JSON patches | `enablePatches()` | For example, if you want to use `produce` on a `Map`, you need to enable this feature once during the start of your application: ```typescript // In your application's entrypoint import {enableMapSet} from "immer" enableMapSet() // ...later import {produce} from "immer" const usersById_v1 = new Map([ ["michel", {name: "Michel Weststrate", country: "NL"}] ]) const usersById_v2 = produce(usersById_v1, draft => { draft.get("michel").country = "UK" }) expect(usersById_v1.get("michel").country).toBe("NL") expect(usersById_v2.get("michel").country).toBe("UK") ``` Vanilla Immer kicks in at ~3KB gzipped. Every plugin that is enabled adds ~1-2 KB to that. The breakdown is as follows: ``` Import size report for immer: ┌───────────────────────┬───────────┬────────────┬───────────┐ │ (index) │ just this │ cumulative │ increment │ ├───────────────────────┼───────────┼────────────┼───────────┤ │ import * from 'immer' │ 6908 │ 0 │ 0 │ │ produce │ 4183 │ 4183 │ 0 │ │ enableMapSet │ 4971 │ 4980 │ 797 │ │ enablePatches │ 5335 │ 6097 │ 1117 │ │ enableArrayMethods │ 4768 │ 6659 │ 562 │ └───────────────────────┴───────────┴────────────┴───────────┘ (this report was generated by npmjs.com/package/import-size) ``` ## Immer on older JavaScript environments? By default `produce` tries to use proxies for optimal performance. However, on older JavaScript engines `Proxy` is not available. For example, when running Microsoft Internet Explorer or React Native (if < v0.59 or when using the Hermes engine on React Native < 0.64) on Android. In such cases, Immer will fallback to an ES5 compatible implementation which works identically, but is a bit slower. - Since version 6, support for the fallback implementation has to be explicitly enabled by calling `enableES5()`. - Version 10 drops the fallback implementation fully, and cannot be used in browsers / engines that don't support Proxy. ================================================ FILE: website/docs/introduction.md ================================================ --- id: introduction title: Introduction to Immer sidebar_label: Introduction slug: / ---
# Immer Immer (German for: always) is a tiny package that allows you to work with immutable state in a more convenient way. > Immer is life-changing as a JS dev, and I'm not even exaggerating :) Like, it's right up there with Prettier in terms of "wow this package is amazing, how did I ever live without it?" --Mark Erikson, (the) Redux Maintainer, @replayio Winner of the "Breakthrough of the year" [React open source award](https://osawards.com/react/) and "Most impactful contribution" [JavaScript open source award](https://osawards.com/javascript/) in 2019. --- - Introduction blogpost: [Immer: Immutability the easy way](https://medium.com/@mweststrate/introducing-immer-immutability-the-easy-way-9d73d8f71cb3) - Short Egghead.io lesson covering the Immer essentials: [Simplify creating immutable data trees with Immer (7m)](https://egghead.io/lessons/redux-simplify-creating-immutable-data-trees-with-immer) - Free in-depth Egghead.io course: [Immutable JavaScript Data Structures with Immer (58m)](https://egghead.io/courses/immutable-javascript-data-structures-with-immer) --- ### Immer simplifies handling immutable data structures Immer can be used in any context in which immutable data structures need to be used. For example in combination with React state, React or Redux reducers, or configuration management. Immutable data structures allow for (efficient) change detection: if the reference to an object didn't change, the object itself did not change. In addition, it makes cloning relatively cheap: Unchanged parts of a data tree don't need to be copied and are shared in memory with older versions of the same state. Generally speaking, these benefits can be achieved by making sure you never change any property of an object, array or map, but by always creating an altered copy instead. In practice this can result in code that is quite cumbersome to write, and it is easy to accidentally violate those constraints. Immer will help you to follow the immutable data paradigm by addressing these pain points: 1. Immer will detect accidental mutations and throw an error. 2. Immer will remove the need for the typical boilerplate code that is needed when creating deep updates to immutable objects: Without Immer, object copies need to be made by hand at every level. Typically by using a lot of `...` spread operations. When using Immer, changes are made to a `draft` object, that records the changes and takes care of creating the necessary copies, without ever affecting the original object. 3. When using Immer, you don't need to learn dedicated APIs or data structures to benefit from the paradigm. With Immer you'll use plain JavaScript data structures, and use the well-known mutable JavaScript APIs, but safely. ### A quick example for comparison ```javascript const baseState = [ { title: "Learn TypeScript", done: true }, { title: "Try Immer", done: false } ] ``` Imagine we have the above base state, and we'll need to update the second todo, and add a third one. However, we don't want to mutate the original `baseState`, and we want to avoid deep cloning as well (to preserve the first todo). #### Without Immer Without Immer, we'll have to carefully shallow copy every level of the state structure that is affected by our change: ```javascript const nextState = baseState.slice() // shallow clone the array nextState[1] = { // replace element 1... ...nextState[1], // with a shallow clone of element 1 done: true // ...combined with the desired update } // since nextState was freshly cloned, using push is safe here, // but doing the same thing at any arbitrary time in the future would // violate the immutability principles and introduce a bug! nextState.push({title: "Tweet about it"}) ``` #### With Immer With Immer, this process is more straightforward. We can leverage the `produce` function, which takes as first argument the state we want to start from, and as second argument we pass a function, called the _recipe_, that is passed a `draft` to which we can apply straightforward mutations. Those mutations are recorded and used to produce the next state once the recipe is done. `produce` will take care of all the necessary copying, and protect against future accidental modifications as well by freezing the data. ```javascript import {produce} from "immer" const nextState = produce(baseState, draft => { draft[1].done = true draft.push({title: "Tweet about it"}) }) ``` Looking for Immer in combination with React? Feel free to skip ahead to the [React + Immer](example-setstate) page. ### How Immer works The basic idea is that with Immer you will apply all your changes to a temporary _draft_, which is a proxy of the _currentState_. Once all your mutations are completed, Immer will produce the _nextState_ based on the mutations to the draft state. This means that you can interact with your data by simply modifying it while keeping all the benefits of immutable data. ![immer-hd.png](/img/immer.png) Using Immer is like having a personal assistant. The assistant takes a letter (the current state) and gives you a copy (draft) to jot changes onto. Once you are done, the assistant will take your draft and produce the real immutable, final letter for you (the next state). Head to the [next section](./produce.mdx) to further dive into `produce`. ## Benefits - Follow the immutable data paradigm, while using normal JavaScript objects, arrays, Sets and Maps. No new APIs or "mutation patterns" to learn! - Strongly typed, no string based paths selectors etc. - Structural sharing out of the box - Object freezing out of the box - Deep updates are a breeze - Boilerplate reduction. Less noise, more concise code. - First class support for JSON patches - Small: 3KB gzipped ================================================ FILE: website/docs/map-set.md ================================================ --- id: map-set title: Map and Set ---
_⚠ Since version 6 support for `Map`s and `Set`s has to be enabled explicitly by calling [`enableMapSet()`](./installation.mdx#pick-your-immer-version) once when starting your application._ Plain objects, arrays, `Map`s and `Set`s are always drafted by Immer. An example of using Maps with immer: ```javascript test("Producers can update Maps", () => { const usersById_v1 = new Map() const usersById_v2 = produce(usersById_v1, draft => { // Modifying a map results in a new map draft.set("michel", {name: "Michel Weststrate", country: "NL"}) }) const usersById_v3 = produce(usersById_v2, draft => { // Making a change deep inside a map, results in a new map as well! draft.get("michel").country = "UK" }) // We got a new map each time! expect(usersById_v2).not.toBe(usersById_v1) expect(usersById_v3).not.toBe(usersById_v2) // With different content obviously expect(usersById_v1).toMatchInlineSnapshot(`Map {}`) expect(usersById_v2).toMatchInlineSnapshot(` Map { "michel" => Object { "country": "NL", "name": "Michel Weststrate", }, } `) expect(usersById_v3).toMatchInlineSnapshot(` Map { "michel" => Object { "country": "UK", "name": "Michel Weststrate", }, } `) // The old one was never modified expect(usersById_v1.size).toBe(0) // And trying to change a Map outside a producers is going to: NO! expect(() => usersById_v3.clear()).toThrowErrorMatchingInlineSnapshot( `"This object has been frozen and should not be mutated"` ) }) ``` Maps and Sets that are produced by Immer will be made artificially immutable. This means that they will throw an exception when trying mutative methods like `set`, `clear` etc. outside a producer. _Note: The **keys** of a map are never drafted! This is done to avoid confusing semantics and keep keys always referentially equal_ ================================================ FILE: website/docs/original.md ================================================ --- id: original title: Extracting the original state from a draft sidebar_label: Original ---
Immer exposes a named export `original` that will get the original object from the proxied instance inside `produce` (or return `undefined` for unproxied values). A good example of when this can be useful is when searching for nodes in a tree-like state using strict equality. ```js import {original, produce} from "immer" const baseState = {users: [{name: "Richie"}]} const nextState = produce(baseState, draftState => { original(draftState.users) // is === baseState.users }) ``` Just want to know if a value is a proxied instance? Use the `isDraft` function! Note that `original` cannot be invoked on objects that aren't drafts. ```js import {isDraft, produce} from "immer" const baseState = {users: [{name: "Bobby"}]} const nextState = produce(baseState, draft => { isDraft(draft) // => true isDraft(draft.users) // => true isDraft(draft.users[0]) // => true }) isDraft(nextState) // => false ``` ================================================ FILE: website/docs/other-lang.md ================================================ --- id: other-lang title: Porting to other languages --- Immer has been ported to other programming languages. |Language|Link| |---|---| |Java|[Jimmer](https://babyfish-ct.github.io/jimmer-doc/)| ================================================ FILE: website/docs/patches.mdx ================================================ --- id: patches title: Patches ---
egghead.io lesson 14: Capture patches using _produceWithPatches_
Hosted on egghead.io
egghead.io lesson 16: Apply Patches using _applyPatches_
Hosted on egghead.io
_⚠ Since version 6 support for Patches has to be enabled explicitly by calling [`enablePatches()`](./installation.mdx#pick-your-immer-version) once when starting your application._ During the run of a producer, Immer can record all the patches that would replay the changes made by the reducer. This is a very powerful tool if you want to fork your state temporarily and replay the changes to the original. Patches are useful in few scenarios: - To exchange incremental updates with other parties, for example over websockets - For debugging / traces, to see precisely how state is changed over time - As basis for undo/redo or as an approach to replay changes on a slightly different state tree To help with replaying patches, `applyPatches` comes in handy. Here is an example how patches could be used to record the incremental updates and (inverse) apply them: ```javascript import {produce, applyPatches} from "immer" // version 6 import {enablePatches} from "immer" enablePatches() let state = { name: "Micheal", age: 32 } // Let's assume the user is in a wizard, and we don't know whether // his changes should end up in the base state ultimately or not... let fork = state // all the changes the user made in the wizard let changes = [] // the inverse of all the changes made in the wizard let inverseChanges = [] fork = produce( fork, draft => { draft.age = 33 }, // The third argument to produce is a callback to which the patches will be fed (patches, inversePatches) => { changes.push(...patches) inverseChanges.push(...inversePatches) } ) // In the meantime, our original state is replaced, as, for example, // some changes were received from the server state = produce(state, draft => { draft.name = "Michel" }) // When the wizard finishes (successfully) we can replay the changes that were in the fork onto the *new* state! state = applyPatches(state, changes) // state now contains the changes from both code paths! expect(state).toEqual({ name: "Michel", // changed by the server age: 33 // changed by the wizard }) // Finally, even after finishing the wizard, the user might change his mind and undo his changes... state = applyPatches(state, inverseChanges) expect(state).toEqual({ name: "Michel", // Not reverted age: 32 // Reverted }) ``` The generated patches are similar (but not the same) to the [RFC-6902 JSON patch standard](https://datatracker.ietf.org/doc/html/rfc6902/#section-4.1), except that the `path` property is an array, rather than a string. This makes processing patches easier. If you want to normalize to the official specification, `patch.path = patch.path.join("/")` should do the trick. Anyway, this is what a bunch of patches and their inverse could look like: ```json [ { "op": "replace", "path": ["profile"], "value": {"name": "Veria", "age": 5} }, {"op": "remove", "path": ["tags", 3]} ] ``` ```json [ {"op": "replace", "path": ["profile"], "value": {"name": "Noa", "age": 6}}, {"op": "add", "path": ["tags", 3], "value": "kiddo"} ] ``` ⚠ Note: The set of patches generated by Immer should be correct, that is, applying them to an equal base object should result in the same end state. However Immer does not guarantee the generated set of patches will be optimal, that is, the minimum set of patches possible. It depends often on the use case what is considered 'optimal', and generating the optimal set of patches is potentially computationally very expensive. So in cases you might want to post process the generated patches, or compress them as explained below. ### `produceWithPatches`
egghead.io lesson 19: Using inverse patches to build undo functionality
Hosted on egghead.io
egghead.io lesson 20: Use patches to build redo functionality
Hosted on egghead.io
Instead of setting up a patch listener, an easier way to obtain the patches is to use `produceWithPatches`, which has the same signature as `produce`, except that it doesn't return just the next state, but a tuple consisting of `[nextState, patches, inversePatches]`. Like `produce`, `produceWithPatches` supports currying as well. ```javascript import {produceWithPatches} from "immer" const [nextState, patches, inversePatches] = produceWithPatches( { age: 33 }, draft => { draft.age++ } ) ``` Which produces: ```javascript [ { age: 34 }, [ { op: "replace", path: ["age"], value: 34 } ], [ { op: "replace", path: ["age"], value: 33 } ] ] ``` For a more in-depth study, see [Distributing patches and rebasing actions using Immer](https://medium.com/@mweststrate/distributing-state-changes-using-snapshots-patches-and-actions-part-2-2f50d8363988) Tip: Check this trick to [compress patches](https://medium.com/@david.b.edelstein/using-immer-to-compress-immer-patches-f382835b6c69) produced over time. ================================================ FILE: website/docs/performance.mdx ================================================ --- id: performance title: Immer performance ---
egghead.io lesson 5: Leveraging Immer's structural sharing in React
Hosted on egghead.io
egghead.io lesson 7: Immer will try to re-cycle data if there was no semantic change
Hosted on egghead.io
Here is a [simple benchmark](https://github.com/immerjs/immer/blob/main/__performance_tests__/todo.js) on the performance of Immer. This test takes 50,000 todo items and updates 5,000 of them. _Freeze_ indicates that the state tree has been frozen after producing it. This is a _development_ best practice, as it prevents developers from accidentally modifying the state tree. Something that isn't reflected in the numbers above, but in reality, Immer is sometimes significantly _faster_ than a hand written reducer. The reason for that is that Immer will detect "no-op" state changes, and return the original state if nothing actually changed, which can avoid a lot of re-renderings for example. Cases are known where simply applying immer solved critical performance issues. These tests were executed on Node 10.16.3. Use `yarn test:perf` to reproduce them locally. ![performance.png](/img/performance.png) Most important observation: - Immer with proxies is roughly speaking twice to three times slower as a handwritten reducer (the above test case is worst case, see `yarn test:perf` for more tests). This is in practice negligible. - Immer is roughly as fast as ImmutableJS. However, the _immutableJS + toJS_ makes clear the cost that often needs to be paid later; converting the immutableJS objects back to plain objects, to be able to pass them to components, over the network etc... (And there is also the upfront cost of converting data received from e.g. the server to immutable JS) - Generating patches doesn't significantly slow down immer - The ES5 fallback implementation is roughly twice as slow as the proxy implementation, in some cases worse. ## Performance tips ### Enable the Array Methods Plugin For applications with significant array iteration within producers, enable the [Array Methods Plugin](./array-methods.md): ```javascript import {enableArrayMethods} from "immer" enableArrayMethods() ``` This plugin optimizes array operations like `filter`, `find`, `some`, `every`, and `slice` by avoiding proxy creation for every element during iteration. Without the plugin, iterating a 1000-element array creates 1000+ proxies. With the plugin, callbacks receive base values, and proxies are only created for elements you actually mutate. ### Use loose iteration for better performance By default, Immer uses loose iteration which only processes enumerable string properties. This is faster than strict iteration which includes symbols and non-enumerable properties. For most use cases, the default is optimal: ```javascript import {setUseStrictIteration} from "immer" // Default: false (loose iteration for better performance) setUseStrictIteration(false) ``` Only enable strict iteration if you specifically need to track symbol or non-enumerable properties. ### Pre-freeze data When adding a large data set to the state tree in an Immer producer (for example data received from a JSON endpoint), it is worth to call `freeze(json)` on the root of the data that is being added first. To _shallowly_ freeze it. This will allow Immer to add the new data to the tree faster, as it will avoid the need to _recursively_ scan and freeze the new data. ### You can always opt-out Realize that immer is opt-in everywhere, so it is perfectly fine to manually write super performance critical reducers, and use immer for all the normal ones. Even from within a producer you opt-out from Immer for certain parts of your logic by using utilies `original` or `current` and perform some of your operations on plain JavaScript objects. ### For expensive search operations, read from the original state, not the draft Immer will convert anything you read in a draft recursively into a draft as well. If you have expensive side effect free operations on a draft that involves a lot of reading, for example finding an index using `find(Index)` in a very large array, you can speed this up by first doing the search, and only call the `produce` function once you know the index. Thereby preventing Immer to turn everything that was searched for in a draft. Or, alternatively, perform the search on the original value of a draft, by using `original(someDraft)`, which boils to the same thing. ### Pull produce as far up as possible Always try to pull produce 'up', for example `for (let x of y) produce(base, d => d.push(x))` is exponentially slower than `produce(base, d => { for (let x of y) d.push(x)})` ================================================ FILE: website/docs/pitfalls.md ================================================ --- id: pitfalls title: Pitfalls ---
### Performance tips For performance tips, see [Performance Tips](./performance.mdx#performance-tips). ### Don't reassign the recipe argument Never reassign the `draft` argument (example: `draft = myCoolNewState`). Instead, either modify the `draft` or return a new state. See [Returning data from producers](./return.mdx). ### Immer only supports unidirectional trees Immer assumes your state to be a unidirectional tree. That is, no object should appear twice in the tree, there should be no circular references. There should be exactly one path from the root to any node of the tree. ### Never explicitly return `undefined` from a producer It is possible to return values from producers, except, it is not possible to return `undefined` that way, as it is indistinguishable from not updating the draft at all! If you want to replace the draft with `undefined`, just return `nothing` from the producer. ### Don't mutate exotic objects Immer [does not support exotic objects](https://github.com/immerjs/immer/issues/504) such as window.location. ### Classes should be made draftable or not mutated You will need to enable your own classes to work properly with Immer. For docs on the topic, check out the section on [working with complex objects](./complex-objects.md). ### Only valid indices and length can be mutated on Arrays For arrays, only numeric properties and the `length` property can be mutated. Custom properties are not preserved on arrays. ### Data not originating from the state will never be drafted Note that data that comes from the closure, and not from the base state, will never be drafted, even when the data has become part of the new draft. ```javascript function onReceiveTodo(todo) { const nextTodos = produce(todos, draft => { draft.todos[todo.id] = todo // Note, because 'todo' is coming from external, and not from the 'draft', // it isn't draft so the following modification affects the original todo! draft.todos[todo.id].done = true // The reason for this, is that it means that the behavior of the 2 lines above // is equivalent to code, making this whole process more consistent todo.done = true draft.todos[todo.id] = todo }) } ``` ### Immer patches are not necessarily optimal The set of patches generated by Immer should be correct, that is, applying them to an equal base object should result in the same end state. However Immer does not guarantee the generated set of patches will be optimal, that is, the minimum set of patches possible. ### Always use the result of nested producers Nested `produce` calls are supported, but note that `produce` will _always_ produce a new state. So even when passing a draft to a nested produce, the changes made by the inner produce won't be visible in the draft of the outer produce; those changes will only be visible in the output that the inner `produce` returns. In other words, when using nested produce, you get a draft of a draft and the result of the inner produce should be merged back into the original draft (or returned). For example `produce(state, draft => { produce(draft.user, userDraft => { userDraft.name += "!" })})` won't work as the output of the inner produce isn't used. The correct way to use nested producers is: ```javascript produce(state, draft => { draft.user = produce(draft.user, userDraft => { userDraft.name += "!" }) }) ``` ### Drafts aren't referentially equal Draft objects in Immer are wrapped in `Proxy`, so you cannot use `==` or `===` to test equality between an original object and its equivalent draft (eg. when matching a specific element in an array). Instead, you can use the `original` helper: ```javascript const remove = produce((list, element) => { const index = list.indexOf(element) // this won't work! const index = original(list).indexOf(element) // do this instead if (index > -1) list.splice(index, 1) }) const values = [a, b, c] remove(values, a) ``` If possible, it's recommended to perform the comparison outside the `produce` function, or to use a unique identifier property like `.id` instead, to avoid needing to use `original`. ### Array Methods Plugin: Callbacks receive base values When using the [Array Methods Plugin](./array-methods.md) (`enableArrayMethods()`), callbacks for overridden methods like `filter`, `find`, `some`, `every`, and `slice` receive **base values** (not drafts). This is the core performance optimization - it avoids creating proxies for every element during iteration. ```javascript import {enableArrayMethods, produce} from "immer" enableArrayMethods() produce(state, draft => { draft.items.filter(item => { // `item` is a base value here, NOT a draft // Reading works fine: return item.value > 10 // But direct mutation here won't be tracked: // item.value = 999 // ❌ Won't affect the draft! }) // Instead, use the returned result (which contains drafts): const filtered = draft.items.filter(item => item.value > 10) filtered[0].value = 999 // ✅ This works - filtered[0] is a draft }) ``` This only applies to methods intercepted by the plugin. Methods like `map`, `forEach`, `reduce` are NOT overridden and work normally - their callbacks receive drafts. ================================================ FILE: website/docs/produce.mdx ================================================ --- id: produce title: Using produce ---
egghead.io lesson 3: Simplifying deep updates with _produce_
Hosted on egghead.io
The Immer package exposes a `produce` function that does all the work. `produce(baseState, recipe: (draftState) => void): nextState` `produce` takes a base state, and a _recipe_ that can be used to perform all the desired mutations on the `draft` that is passed in. The interesting thing about Immer is that the `baseState` will be untouched, but the `nextState` will reflect all changes made to `draftState`. Inside the recipe, all standard JavaScript APIs can be used on the `draft` object, including field assignments, `delete` operations, and mutating array, Map and Set operations like `push`, `pop`, `splice`, `set`, `sort`, `remove`, etc. Any of those mutations don't have to happen at the root, but it is allowed to modify anything anywhere deep inside the draft: `draft.todos[0].tags["urgent"].author.age = 56` Note that the recipe function itself normally doesn't return anything. However, it is possible to return in case you want to replace the `draft` object in its entirety with another object, for more details see [returning new data](./return.mdx). ## Example ```javascript import {produce} from "immer" const baseState = [ { title: "Learn TypeScript", done: true }, { title: "Try Immer", done: false } ] const nextState = produce(baseState, draftState => { draftState.push({title: "Tweet about it"}) draftState[1].done = true }) ``` ```javascript // the new item is only added to the next state, // base state is unmodified expect(baseState.length).toBe(2) expect(nextState.length).toBe(3) // same for the changed 'done' prop expect(baseState[1].done).toBe(false) expect(nextState[1].done).toBe(true) // unchanged data is structurally shared expect(nextState[0]).toBe(baseState[0]) // ...but changed data isn't. expect(nextState[1]).not.toBe(baseState[1]) ``` ### Terminology - `(base)state`, the immutable state passed to `produce` - `recipe`: the second argument of `produce`, that captures how the base state should be "mutated". - `draft`: the first argument of any `recipe`, which is a proxy to the original base state that can be safely mutated. - `producer`. A function that uses `produce` and is generally of the form `(baseState, ...arguments) => resultState` Note that it isn't strictly necessary to name the first argument of the recipe `draft`. You can name it anything you want, for example `users`. Using `draft` as a name is just a convention to signal: "mutation is OK here". ================================================ FILE: website/docs/resources.md ================================================ --- id: resources title: External resources ---
- Blog: [The Rise of Immer in React](https://www.netlify.com/blog/2018/09/12/the-rise-of-immer-in-react/) - Blog: by Workday Prism on why they picked Immer to manage immutable state [The Search for a Strongly-Typed, Immutable State](https://medium.com/workday-engineering/workday-prism-analytics-the-search-for-a-strongly-typed-immutable-state-a09f6768b2b5) - Blog: [Immutability in React and Redux: The Complete Guide](https://daveceddia.com/react-redux-immutability-guide/) - Video tutorial: [Using Immer with React.setState](https://codedaily.io/screencasts/86/Immutable-Data-with-Immer-and-React-setState) - [Talk](https://www.youtube.com/watch?v=-gJbS7YjcSo) + [slides](http://immer.surge.sh/) on Immer at React Finland 2018 by Michel Weststrate - [ForwardJS 2019: Immutability is Changing - From Immutable.js to Immer](https://www.youtube.com/watch?v=bFuRvcAEiHg&feature=youtu.be) by [shawn swyx wang](https://twitter.com/swyx/) - [Talk: Immer, Immutability and the Wonderful World of Proxies](https://www.youtube.com/watch?v=4Nb9Gwp2L24) + [slides](https://jsnation-proxies.surge.sh/), JSNation 2019, Michel Weststrate - Blog: [Distributing state changes using snapshots, patches and actions](https://medium.com/@mweststrate/distributing-state-changes-using-snapshots-patches-and-actions-part-1-2811a2fcd65f) - Blog: [Implementing Undo-Redo Functionality in Redux](https://techinscribed.com/implementing-undo-redo-functionality-in-redux-using-immer/), Sep 2019 - Blog: [Synchronized immutable state with time travel](https://dev.to/oleg008/synchronized-immutable-state-with-time-travel-2c6o), Apr 2022, by [Oleg Isonen](https://twitter.com/oleg008) ================================================ FILE: website/docs/return.mdx ================================================ --- id: return title: Returning new data from producers ---
egghead.io lesson 9: Returning completely new state
Hosted on egghead.io
It is not needed to return anything from a producer, as Immer will return the (finalized) version of the `draft` anyway. However, it is allowed to just `return draft`. It is also allowed to return arbitrarily other data from the producer function. But _only_ if you didn't modify the draft. This can be useful to produce an entirely new state. Some examples: ```javascript const userReducer = produce((draft, action) => { switch (action.type) { case "renameUser": // OK: we modify the current state draft.users[action.payload.id].name = action.payload.name return draft // same as just 'return' case "loadUsers": // OK: we return an entirely new state return action.payload case "adduser-1": // NOT OK: This doesn't do change the draft nor return a new state! // It doesn't modify the draft (it just redeclares it) // In fact, this just doesn't do anything at all draft = {users: [...draft.users, action.payload]} return case "adduser-2": // NOT OK: modifying draft *and* returning a new state draft.userCount += 1 return {users: [...draft.users, action.payload]} case "adduser-3": // OK: returning a new state. But, unnecessary complex and expensive return { userCount: draft.userCount + 1, users: [...draft.users, action.payload] } case "adduser-4": // OK: the immer way draft.userCount += 1 draft.users.push(action.payload) return } }) ``` _Note: It is not possible to return `undefined` this way, as it is indistinguishable from *not* updating the draft! Read on..._ ## Producing `undefined` using `nothing` So, in general, one can replace the current state by just `return`ing a new value from the producer, rather than modifying the draft. There is a subtle edge case however: if you try to write a producer that wants to replace the current state with `undefined`: ```javascript produce({}, draft => { // don't do anything }) ``` Versus: ```javascript produce({}, draft => { // Try to return undefined from the producer return undefined }) ``` The problem is that in JavaScript a function that doesn't return anything also returns `undefined`! So immer cannot differentiate between those different cases. So, by default, Immer will assume that any producer that returns `undefined` just tried to modify the draft. However, to make it clear to Immer that you intentionally want to produce the value `undefined`, you can return the built-in token `nothing`: ```javascript import {produce, nothing} from "immer" const state = { hello: "world" } produce(state, draft => {}) produce(state, draft => undefined) // Both return the original state: { hello: "world"} produce(state, draft => nothing) // Produces a new state, 'undefined' ``` N.B. Note that this problem is specific for the `undefined` value, any other value, including `null`, doesn't suffer from this issue. Tip: to be able to return `nothing` from a recipe when using TypeScript, the `state`'s type must accept `undefined` as value. ## Inline shortcuts using `void`
egghead.io lesson 10: Avoid accidental returns by using _void_
Hosted on egghead.io
Draft mutations in Immer usually warrant a code block, since a return denotes an overwrite. Sometimes that can stretch code a little more than you might be comfortable with. In such cases, you can use javascripts [`void`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void) operator, which evaluates expressions and returns `undefined`. ```javascript // Single mutation produce(draft => void (draft.user.age += 1)) // Multiple mutations produce(draft => void ((draft.user.age += 1), (draft.user.height = 186))) ``` Code style is highly personal, but for code bases that are to be understood by many, we recommend to stick to the classic `draft => { draft.user.age += 1}` to avoid cognitive overhead. ================================================ FILE: website/docs/support.md ================================================ --- id: support title: Supporting immer ---
Immer currently has 350.000 dependents on GitHub, and has almost 10.000.000 downloads per month. However, only the first 2 days of development has been sponsored (by Mendix), and all the development and maintenance after that has been a labor of love. If you are enjoying Immer, and you are grateful for the package, or want to ensure its longevity, consider sponsoring the open collective on https://opencollective.com/immer or make a one time donation using [PayPal](https://www.paypal.me/michelweststrate). ================================================ FILE: website/docs/typescript.mdx ================================================ --- id: typescript title: Using TypeScript or Flow sidebar_label: TypeScript / Flow ---
egghead.io lesson 12: Immer + TypeScript
Hosted on egghead.io
The Immer package ships with type definitions inside the package, which should be picked up by TypeScript and Flow out of the box and without further configuration. The TypeScript typings automatically remove `readonly` modifiers from your draft types and return a value that matches your original type. See this practical example: ```ts import {produce} from "immer" interface State { readonly x: number } // `x` cannot be modified here const state: State = { x: 0 } const newState = produce(state, draft => { // `x` can be modified here draft.x++ }) // `newState.x` cannot be modified here ``` This ensures that the only place you can modify your state is in your produce callbacks. It even works recursively and with `ReadonlyArray`. ## Best practices 1. Always define your states as `readonly` as much as possible. This best reflects the mental model and reality, since Immer will freeze all its returned values. 2. You can use the utility type `Immutable` to recursively make an entire type tree read-only, e.g.: `type ReadonlyState = Immutable`. 3. Immer won't automatically wrap all returned types in `Immutable` if the original type of the input state wasn't immutable. This is to make sure it doesn't break code bases that don't use immutable types. ## Tips for curried producers We try to inference as much as possible. So if a curried producer is created and directly passed to another function, we can infer the type from there. This works well with for example React: ```typescript import {Immutable, produce} from "immer" type Todo = Immutable<{ title: string done: boolean }> // later... const [todo, setTodo] = useState({ title: "test", done: true }) // later... setTodo( produce(draft => { // draft will be strongly typed and mutable! draft.done = !draft.done }) ) ``` When a curried producer isn't passed directly somewhere else, Immer can infer the state type from the draft argument. For example when doing the following: ```typescript // See below for a better solution! const toggler = produce((draft: Draft) => { draft.done = !draft.done }) // typeof toggler = (state: Immutable) => Writable ``` Note that we did wrap the `Todo` type of the `draft` argument with `Draft`, because `Todo` is a readonly type. For non-readonly types this isn't needed. For the returned curried function, `toggler`, We will _narrow_ the _input_ type to `Immutable`, so that even though `Todo` is a mutable type, we will still accept an immutable todo as input argument to `toggler`. In contrast, Immer will _widen_ the _output_ type of the curried function to `Writable`, to make sure it's output state is also assignable to variables that are not explicitly typed to be immutable. This type narrowing / widening behavior might be unwelcome, maybe even for the simple reason that it results in quite noisy types. So we recommend to specify the generic state type for curried producers instead, in cases where it cannot be inferred directly, like `toggler` above. By doing so the automatic output widening / input narrowing will be skipped. However, the `draft` argument itself will still be inferred to be a writable `Draft`: ```typescript const toggler = produce(draft => { draft.done = !draft.done }) // typeof toggler = (state: Todo) => Todo ``` However, in case the curried producer is defined with an initial state, Immer can infer the state type from the initial state, so in that case the generic doesn't need to be specified either: ```typescript const state0: Todo = { title: "test", done: false } // No type annotations needed, since we can infer from state0. const toggler = produce(draft => { draft.done = !draft.done }, state0) // typeof toggler = (state: Todo) => Todo ``` In case the toggler has no initial state, and it has curried arguments, and you set the state generic explicitly, then type of any additional arguments should be defined explicitly as a tuple type as well: ```typescript const toggler = produce((draft, newState) => { draft.done = newState }) // typeof toggler = (state: Todo, newState: boolean) => Todo ``` ## Cast utilities The types inside and outside a `produce` can be conceptually the same, but from a practical perspective different. For example, the `State` in the examples above should be considered immutable outside `produce`, but mutable inside `produce`. Sometimes this leads to practical conflicts. Take the following example: ```typescript type Todo = {readonly done: boolean} type State = { readonly finishedTodos: readonly Todo[] readonly unfinishedTodos: readonly Todo[] } function markAllFinished(state: State) { produce(state, draft => { draft.finishedTodos = state.unfinishedTodos }) } ``` This will generate the error: ``` The type 'readonly Todo[]' is 'readonly' and cannot be assigned to the mutable type '{ done: boolean; }[]' ``` The reason for this error is that we assign our read only, immutable array to our draft, which expects a mutable type, with methods like `.push` etc etc. As far as TS is concerned, those are not exposed from our original `State`. To hint TypeScript that we want to upcast the collection here to a mutable array for draft purposes, we can use the utility `castDraft`: `draft.finishedTodos = castDraft(state.unfinishedTodos)` will make the error disappear. There is also the utility `castImmutable`, in case you ever need to achieve the opposite. Note that these utilities are for all practical purposes no-ops, they will just return their original value. Tip: You can combine `castImmutable` with `produce` to type the return type of `produce` as something immutable, even when the original state was mutable: ```typescript // a mutable data structure const baseState = { todos: [{ done: false }] } const nextState = castImmutable(produce(baseState, _draft => {})) // inferred type of nextState is now: { readonly todos: ReadonlyArray<{ readonly done: boolean }> }) ``` ## Compatibility **Note:** Immer v5.3+ supports TypeScript v3.7+ only. **Note:** Immer v3.0+ supports TypeScript v3.4+ only. **Note:** Immer v1.9+ supports TypeScript v3.1+ only. **Note:** Flow support might be removed in future versions and we recommend TypeScript ================================================ FILE: website/docs/update-patterns.md ================================================ --- id: update-patterns title: Update patterns ---
Working with immutable data, before Immer, used to mean learning all the immutable update patterns. To help 'unlearning' those patterns here is an overview how you can leverage the built-in JavaScript APIs to update objects and collections: ### Object mutations ```javascript import {produce} from "immer" const todosObj = { id1: {done: false, body: "Take out the trash"}, id2: {done: false, body: "Check Email"} } // add const addedTodosObj = produce(todosObj, draft => { draft["id3"] = {done: false, body: "Buy bananas"} }) // delete single property const deletedTodosObj = produce(todosObj, draft => { delete draft["id1"] }) // update const updatedTodosObj = produce(todosObj, draft => { draft["id1"].done = true }) // replace & update in bulk const updatedTodosObj = produce(todosObj, draft => { Object.assign(draft, { id1: {done: true, body: "Take out the trash"}, id2: {done: true, body: "Check Email"}, id3: {done: true, body: "Feed my cat"} }) // reset/clear/empty const emptyTodo = produce(todosObj, () => { return {}; }) ``` Any time a nested draft field gets a new reference or value, produce() will finish applying the immutable update and return a new reference. If you tried to mutate, but the values remained the same, Immer will bail out and return the existing reference from produce() ### Array mutations ```javascript import {produce} from "immer" const todosArray = [ {id: "id1", done: false, body: "Take out the trash"}, {id: "id2", done: false, body: "Check Email"} ] // add const addedTodosArray = produce(todosArray, draft => { draft.push({id: "id3", done: false, body: "Buy bananas"}) }) // delete by index const deletedTodosArray = produce(todosArray, draft => { draft.splice(3 /*the index */, 1) }) // update by index const updatedTodosArray = produce(todosArray, draft => { draft[3].done = true }) // insert at index const updatedTodosArray = produce(todosArray, draft => { draft.splice(3, 0, {id: "id3", done: false, body: "Buy bananas"}) }) // remove last item const updatedTodosArray = produce(todosArray, draft => { draft.pop() }) // remove first item const updatedTodosArray = produce(todosArray, draft => { draft.shift() }) // add item at the beginning of the array const addedTodosArray = produce(todosArray, draft => { draft.unshift({id: "id3", done: false, body: "Buy bananas"}) }) // delete by id const deletedTodosArray = produce(todosArray, draft => { const index = draft.findIndex(todo => todo.id === "id1") if (index !== -1) draft.splice(index, 1) }) // update by id const updatedTodosArray = produce(todosArray, draft => { const index = draft.findIndex(todo => todo.id === "id1") if (index !== -1) draft[index].done = true }) // filtering items const updatedTodosArray = produce(todosArray, draft => { // creating a new state is simpler in this example // (note that we don't need produce in this case, // but as shown below, if the filter is not on the top // level produce is still pretty useful) return draft.filter(todo => todo.done) }) // reset/clear/empty const emptyTodo = produce(todosArray, () => { return []; }) ``` ### Nested data structures ```javascript import {produce} from "immer" // example complex data structure const store = { users: new Map([ [ "17", { name: "Michel", todos: [ { title: "Get coffee", done: false } ] } ] ]) } // updating something deeply in-an-object-in-an-array-in-a-map-in-an-object: const nextStore = produce(store, draft => { draft.users.get("17").todos[0].done = true }) // filtering out all unfinished todo's const nextStore = produce(store, draft => { const user = draft.users.get("17") // when filtering, creating a fresh collection is simpler than // removing irrelevant items user.todos = user.todos.filter(todo => !todo.done) }) ``` Note that many array operations can be used to insert multiple items at once by passing multiple arguments or using the spread operation: `todos.unshift(...items)`. Note that when working with arrays that contain objects that are typically identified by some id, we recommend to use `Map` or index based objects (as shown above) instead of performing frequent find operations, lookup tables perform much better in general. ================================================ FILE: website/docusaurus.config.js ================================================ // See https://v2.docusaurus.io/docs/configuration for more information. module.exports = { title: "Immer", tagline: "Create the next immutable state by mutating the current one.", url: "https://immerjs.github.io/", baseUrl: process.env.NETLIFY_PREVIEW ? "/" : "/immer/", projectName: "immer", organizationName: "immerjs", onBrokenLinks: "throw", onBrokenMarkdownLinks: "warn", favicon: "img/favicon.ico", i18n: { defaultLocale: "en", locales: ["en", "zh-CN"] }, themeConfig: { announcementBar: { id: "support_ukraine", content: 'Support Ukraine 🇺🇦 Help Provide Humanitarian Aid to Ukraine.', backgroundColor: "#20232a", textColor: "#fff", isCloseable: false }, navbar: { title: "Immer", style: "dark", logo: { src: "/img/immer-logo.svg", alt: "Immer Logo" }, items: [ { type: "doc", docId: "introduction", label: "Documentation", position: "right" }, { href: "https://github.com/immerjs/immer", label: "GitHub", position: "right" }, { type: "doc", docId: "support", label: "Support Immer", position: "right" }, { type: "localeDropdown", position: "left" } ] }, footer: { copyright: `Copyright © ${new Date().getFullYear()} Michel Weststrate` } }, scripts: [ "https://buttons.github.io/buttons.js", "https://media.ethicalads.io/media/client/ethicalads.min.js" ], themes: [ [ "@docusaurus/theme-classic", { customCss: require.resolve("./src/css/immer-infima.css") } ] ], plugins: [ [ "@docusaurus/plugin-content-docs", { sidebarPath: require.resolve("./sidebars.js"), editUrl: "https://github.com/immerjs/immer/edit/main/website/", routeBasePath: "/" } ], [ "@docusaurus/plugin-google-gtag", { trackingID: "G-X43066885W", anonymizeIP: true } ], [ "@docusaurus/plugin-google-analytics", { trackingID: "UA-65632006-3", anonymizeIP: true } ], [ "@docusaurus/plugin-client-redirects", { createRedirects: function(existingPath) { return ["/docs" + existingPath] } } ] ] } ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/api.md ================================================ --- id: api title: API 概览 ---
| 导出名称 | 描述 | 章节 | | --- | --- | --- | | `(default)` | Immer 核心 API,通常命名为 `produce`: `import {produce} from "immer"` | [Produce](./produce.mdx) | | `applyPatches` | 给定一个基本 state 或 draft,以及一组 patches ,应用 patches | [Patches](./patches.mdx) | | `castDraft` | 将任何不可变类型转换为其可变对应物。这只是一个转换,实际上并没有做任何事情。 | [TypeScript](./typescript.mdx) | | `castImmutable` | 将任何可变类型转换为其不可变对应物。这只是一个转换,实际上并没有做任何事情。 | [TypeScript](./typescript.mdx) | | `createDraft` | 给定一个基本 state,创建一个可变 draft,任何修改都将被记录下来 | [Async](./async.mdx) | | `current` | 给定一个 draft 对象(不必是对象的根结点),对 draft 的当前状态进行快照 | [Current](./current.md) | | `Draft` | 暴露的 TypeScript 类型以将不可变类型转换为可变类型 | [TypeScript](./typescript.mdx) | | `enableMapSet()` | 启用对 `Map` 和 `Set` 集合的支持。 | [Installation](./installation.mdx#pick-your-immer-version) | | `enablePatches()` | 启用对 JSON patches 的支持 | [Installation](./installation#pick-your-immer-version) | | `finishDraft` | 给定使用 `createDraft` 创建的 draft,冻结 draft 并生成并返回下一个不可变状态,该状态捕获所有更改 | [Async](./async.mdx) | | `freeze(obj, deep?)` | 冻结可 draft 对象。返回原始对象。默认情况下浅冻结,但如果第二个参数为真,它将递归冻结。 | | `Immer` | 可用于创建第二个“immer”实例(暴露此实例中列出的所有 API)的构造函数,它不与全局实例共享其设置 | | `immerable` | 可以添加到构造函数或原型的符号,表示 Immer 应该将类视为可以安全 draft 的东西 | [Classes](./complex-objects.md) | | `Immutable` | 暴露的 TypeScript 类型以将可变类型转换为不可变类型 | | | `isDraft` | 如果给定对象是 draft 对象,则返回 true | | | `isDraftable` | 如果 Immer 能够将此对象变成 draft,则返回 true。这适用于:数组、没有原型的对象、以 `Object` 为原型的对象、在其构造函数或原型上具有 `immerable` 符号的对象 | | | `nothing` | 可以从 recipe 返回的值,以指示应生成 `undefined` | [Return](./return.mdx) | | `original` | 给定一个 draft 对象(不必是对象的根结点),返回原始状态树中相同路径的原始对象(如果存在) | [Original](./original.md) | | `Patch` | 暴露的 TypeScript 类型,描述(反向)patches 对象的形状 | [Patches](./patches.mdx) | | `produce` | Immer 的核心 API,也暴露为 `default` 导出 | [Produce](./produce.mdx) | | `produceWithPatches` | 与 `produce` 相同,但它不仅返回生成的对象,还返回一个由 `[result, patch, inversePatches]` 组成的元组 | [Patches](./patches.mdx) | | `setAutoFreeze` | 启用/禁用递归的自动冻结。默认启用 | [Freezing](./freezing.mdx) | | `setUseStrictShallowCopy` | 可用于启用严格的浅拷贝。 如果启用,immer 会尽可能多地拷贝不可枚举属性 | [Classes](./complex-objects.md) | ## 导入 immer `produce` 作为默认导出,但也可以选择将其用作名称导入,因为这有利于一些较旧的项目设置。所以下面的导入都是正确的,这里推荐第一个: ```javascript import {produce} from "immer" import {produce} from "immer" const {produce} = require("immer") const produce = require("immer").produce const produce = require("immer").default import unleashTheMagic from "immer" import {produce as unleashTheMagic} from "immer" ``` ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/async.mdx ================================================ --- id: async title: createDraft / finishDraft sidebar_label: createDraft / finishDraft ---
egghead.io 第11课: 创建异步 producers(以及为什么不应该这样做)
Hosted on egghead.io
## `createDraft` and `finishDraft` `createDraft` 和 `finishDraft` 是两个底层函数,它们对于在 immer 之上构建抽象的库非常有用。它避免了为了使用 draft 始终创建函数。相反,人们可以创建一个 draft,对其进行修改,并在未来的某个时间完成该 draft,在这种情况下,将产生下一个不可变状态。例如,我们可以将上面的示例重写为: Beyond that, `createDraft` / `finishDraft` could be used to express async updates to drafts: ```javascript import {createDraft, finishDraft} from "immer" const user = { name: "michel", todos: [] } const draft = createDraft(user) draft.todos = await (await window.fetch("http://host/" + draft.name)).json() const loadedUser = finishDraft(draft) ``` 注意:`finishDraft` 以一个 `patchListener` 作为第二个参数,可以用来记录 patches,类似于 `produce` _警告:一般情况下,我们建议使用 `producer` 而不是 `createDraft / finishDraft` 组合,`produce` 在使用中不易出错,并且在代码中更清楚地区分了可变性和不变性的概念。_ ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/built-with.md ================================================ --- id: built-with title: 基于 Immer ---
- [react-copy-write](https://github.com/aweary/react-copy-write) _具有可变 API 的不可变状态_ - [redux-toolkit](https://github.com/reduxjs/redux-toolkit) _官方的,opinionated,自带全套工具的效率 Redux 开发_ - [immer based handleActions](https://gist.github.com/kitze/fb65f527803a93fb2803ce79a792fff8) _Redux 自由动作脚手架_ - [redux-box](https://github.com/anish000kumar/redux-box) _模块化且易于掌握的基于 redux 的状态管理,样板代码最少_ - [quick-redux](https://github.com/jeffreyyoung/quick-redux) _使 redux 开发更快更容易的工具_ - [bey](https://github.com/jamiebuilds/bey) _使用 Immer 实现 React 的简单不可变状态_ - [cool-store](https://github.com/Maxvien/cool-store) _CoolStore 是建立在 ImmerJS 和 RxJS 之上的不可变状态存储_ - [immer-wieder](https://github.com/drcmda/immer-wieder#readme) _结合 React 16 Context 和 immer 用于 Redux 语义的状态管理库_ - [robodux](https://github.com/neurosnap/robodux) _减少 redux 样板的灵活脚手架_ - [immer-reducer](https://github.com/epeli/immer-reducer) _用于 React Hooks 和 Redux 的 Typescript 类型安全和简洁的 reducer_ - [redux-ts-utils](https://github.com/knpwrs/redux-ts-utils) _使用 Redux 创建类型安全的应用程序所需的一切,强调简单性_ - [react-state-tree](https://github.com/suchipi/react-state-tree) _将您的状态持久化到类似 redux 的状态树,useState 的替代品_ - [redux-immer](https://github.com/salvoravida/redux-immer) _用于创建与 immer 状态一起使用的 Redux combineReducers 的等效函数。像 redux-immutable 但是 immer的_ - [ngrx-wieder](https://github.com/nilsmehlhorn/ngrx-wieder) _轻量级但可配置的解决方案,用于在 NgRx 和 Immer 之上的 Angular 应用程序中实现撤消重做_ - ... 还有 [很多](https://www.npmjs.com/browse/depended/immer) ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/complex-objects.md ================================================ --- id: complex-objects title: 类 ---
普通对象(没有原型的对象)、数组、`Map` 和 `Set` 总是可以用 Immer 更新。所有其他对象都必须使用 `immerable` 符号将自己标记为与 Immer 兼容。当这些对象之一在 `produce` 中进行更改时,它的原型将保留在副本之间 ```js import {immerable} from "immer" class Foo { [immerable] = true // 方式一 constructor() { this[immerable] = true // 方式二 } } Foo[immerable] = true // 方式三 ``` ### 例子 ```js import {immerable, produce} from "immer" class Clock { [immerable] = true constructor(hour, minute) { this.hour = hour this.minute = minute } get time() { return `${this.hour}:${this.minute}` } tick() { return produce(this, draft => { draft.minute++ }) } } const clock1 = new Clock(12, 10) const clock2 = clock1.tick() console.log(clock1.time) // 12:10 console.log(clock2.time) // 12:11 console.log(clock2 instanceof Clock) // true ``` ### 语义细节 关于类的 `draft` 对象语义如下: 1. 类的 `draft` 是一个新对象,但与原始对象具有相同的原型。 2. 创建 `draft` 时,Immer 会将所有拥有的的属性从源对象复制到 `draft`。这包括不可枚举和符号属性。 3. 源对象拥有的 getter 将在复制过程中被调用,就像 `Object.assign` 方法一样 4. 继承的 getter 和方法将保持原样并被 `draft` 继承 5. Immer 不会调用构造函数 6. 最终实例将使用与创建 `draft` 相同的机制构建。 7. 只有具有 setter 的 getter 才能在 `draft` 中写入,否则无法将值复制回来。 因为 Immer 会将对象拥有的 getter 解引用到普通属性中,所以可以使用在其字段上使用 getter/setter 获得的对象,就像MobX 和 Vue。 Immer 不支持外来/引擎原生对象,例如 DOM 节点或 Buffers,也不支持继承的 Map、Set 或数组,并且不能在它们上使用 immerable 符号。 因此,例如在使用 `Date` 对象时,您应该始终创建一个新的 `Date` 实例,而不是改变现有的 `Date` 对象。 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/current.md ================================================ --- id: current title: 从 draft 中提取当前 state sidebar_label: Current ---
Immer 暴露了一个命名导出的 `current`函数,可以创建 draft 对象当前状态的一个副本。 这对于调试非常有用(因为这些对象不会是代理对象,也不会被记录下来)。 此外,对 `current` 的引用可以安全地从 `produce` 函数中释放。换句话说,`current` 提供 draft 当前状态的快照。 `current` 工作生成的对象类似于 `produced` 本身创建的对象。 1. 未修改的对象将在结构上与原始对象共享。 2. 如果未对 draft 进行任何更改,通常它会保留 original(draft) === current(draft),但这并不能保证。 3. 未来对 draft 的更改不会反映在 `current` 生成的对象中(不可被 draft 对象的引用除外) 4. 与 `produce` 创建的对象不同,`current` 创建的对象不会被冻结。 谨慎使用 `current`,这可能是一项潜在的昂贵操作,尤其是在使用 ES5 时。 请注意,不能在不是 draft 的对象上调用 `current`。 ### 例子 以下示例显示了 `current`(和 `original` )的效果: ```js const base = { x: 0 } const next = produce(base, draft => { draft.x++ const orig = original(draft) const copy = current(draft) console.log(orig.x) console.log(copy.x) setTimeout(() => { // 将在 produce 完成后执行 console.log(orig.x) console.log(copy.x) }, 100) draft.x++ console.log(draft.x) }) console.log(next.x) // 将会打印 // 0 (orig.x) // 1 (copy.x) // 2 (draft.x) // 2 (next.x) // 0 (after timeout, orig.x) // 1 (after timeout, copy.x) ``` ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/curried-produce.mdx ================================================ --- id: curried-produce title: 柯里化 producers ---
egghead.io 第六课: 使用柯里化简化代码
Hosted on egghead.io
将函数作为第一个参数传递给 `produce` 会创建一个函数,该函数尚未将 `produce` 应用于特定 state,而是创建一个函数,该函数将应用于将来传递给它的任何 state。这通常称为柯里化。举个例子: ```javascript import {produce} from "immer" function toggleTodo(state, id) { return produce(state, draft => { const todo = draft.find(todo => todo.id === id) todo.done = !todo.done }) } const baseState = [ { id: "JavaScript", title: "Learn TypeScript", done: true }, { id: "Immer", title: "Try Immer", done: false } ] const nextState = toggleTodo(baseState, "Immer") ``` 上面的 `toggleTodo` 模式非常典型;传递一个现有的 state 来 `produce`,修改 `draft`,然后返回结果。由于 `state` 除了将其传递给 `produce` 之外没有其他任何用途,因此可以通过使用 `produce` 的柯里化形式来简化上面的示例,其中您只传递 `produce` recipe 函数,并且 `produce` 将返回一个应用 recipe 到基础状态的新函数。这允许我们缩短上述 `toggleTodo` 定义。 ```javascript import {produce} from "immer" // curried producer: const toggleTodo = produce((draft, id) => { const todo = draft.find(todo => todo.id === id) todo.done = !todo.done }) const baseState = [ /* as is */ ] const nextState = toggleTodo(baseState, "Immer") ``` 请注意,`id` 参数现在已成为 recipe 函数的一部分!这种拥有 curried producers 的模式与 React 中的 `useState` Hook 非常巧妙地结合在一起,我们将在下一页看到。 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/example-setstate.mdx ================================================ --- id: example-setstate title: React & Immer ---
egghead.io 第八课: 使用 Immer 和 useState,或者 useImmer。
Hosted on egghead.io
## useState + Immer `useState` hook 假定存储在其中的任何 state 都被视为不可变的。使用 Immer 可以大大简化 React 组件状态的深度更新。下面的例子展示了如何使用 `produce` 和 `useState` ,可以在 [CodeSandbox](https://codesandbox.io/s/immer-usestate-ujkgg?file=/src/index.js) 试试。 ```javascript import React, { useCallback, useState } from "react"; import {produce} from "immer"; const TodoList = () => { const [todos, setTodos] = useState([ { id: "React", title: "Learn React", done: true }, { id: "Immer", title: "Try Immer", done: false } ]); const handleToggle = useCallback((id) => { setTodos( produce((draft) => { const todo = draft.find((todo) => todo.id === id); todo.done = !todo.done; }) ); }, []); const handleAdd = useCallback(() => { setTodos( produce((draft) => { draft.push({ id: "todo_" + Math.random(), title: "A new todo", done: false }); }) ); }, []); return (
{*/ See CodeSandbox */}
) } ``` ## useImmer 由于所有 state 的更新都使用 `produce` 包装的更新模式,所以我们可以通过将更新模式包装在 [use-immer](https://www.npmjs.com/package/use-immer) 包中来简化上述操作 ```javascript import React, { useCallback } from "react"; import { useImmer } from "use-immer"; const TodoList = () => { const [todos, setTodos] = useImmer([ { id: "React", title: "Learn React", done: true }, { id: "Immer", title: "Try Immer", done: false } ]); const handleToggle = useCallback((id) => { setTodos((draft) => { const todo = draft.find((todo) => todo.id === id); todo.done = !todo.done; }); }, []); const handleAdd = useCallback(() => { setTodos((draft) => { draft.push({ id: "todo_" + Math.random(), title: "A new todo", done: false }); }); }, []); // etc ``` 完整的 demo 请参阅 [CodeSandbox](https://codesandbox.io/s/use-immer-bvd5v?file=/src/index.js) ## useReducer + Immer 与 `useState` 类似,`useReducer` 也与 Immer 巧妙结合,如 [CodeSandbox](https://codesandbox.io/s/immer-usereducer-bqpzn?file=/src/index.js:0-1018) 所示: ```javascript import React, {useCallback, useReducer} from "react" import {produce} from "immer" const TodoList = () => { const [todos, dispatch] = useReducer( produce((draft, action) => { switch (action.type) { case "toggle": const todo = draft.find(todo => todo.id === action.id) todo.done = !todo.done break case "add": draft.push({ id: action.id, title: "A new todo", done: false }) break default: break } }), [ /* initial todos */ ] ) const handleToggle = useCallback(id => { dispatch({ type: "toggle", id }) }, []) const handleAdd = useCallback(() => { dispatch({ type: "add", id: "todo_" + Math.random() }) }, []) // etc } ``` ## useImmerReducer 同上,可以通过 `use-immer` 包中的 `useImmerReducer` 简化 ([demo](https://codesandbox.io/s/useimmerreducer-sycpb?file=/src/index.js)) ```javascript import React, { useCallback } from "react"; import { useImmerReducer } from "use-immer"; const TodoList = () => { const [todos, dispatch] = useImmerReducer( (draft, action) => { switch (action.type) { case "toggle": const todo = draft.find((todo) => todo.id === action.id); todo.done = !todo.done; break; case "add": draft.push({ id: action.id, title: "A new todo", done: false }); break; default: break; } }, [ /* initial todos */ ] ); //etc ``` ## Redux + Immer Redux + Immer 在 [Redux Toolkit](https://redux-toolkit.js.org/usage/immer-reducers) 的文档中被广泛介绍。对于没有 Redux Toolkit 的 Redux,可以应用与上面应用于 `useReducer` 相同的技巧:使用 `produce` 包装 reducer 函数,您可以安全地修改 draft! 例子: ```javascript import {produce} from "immer" // 初始 state const INITIAL_STATE = [ /* 一系列 todos */ ] const todosReducer = produce((draft, action) => { switch (action.type) { case "toggle": const todo = draft.find(todo => todo.id === action.id) todo.done = !todo.done break case "add": draft.push({ id: action.id, title: "A new todo", done: false }) break default: break } }) ``` ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/faq.md ================================================ --- id: faq title: 常见问题 sidebar_label: FAQ ---
## Q: Immer 如何工作 阅读[介绍博客](https://medium.com/@mweststrate/introducing-immer-immutability-the-easy-way-9d73d8f71cb3)的(第二部分) ## Q: Immer 是否使用结构共享?这样我的选择器就可以被记住了吗? A: 是的 ## Q: Immer 是否支持深度更新? A: 是的 ## Q: 我的目标环境中没有代理。我可以使用 Immer 吗? A: 可以 - [查看细节](./installation.mdx#immer-on-older-javascript-environments) ## Q: 使用 Immer 时可以对我的数据结构进行类型检查吗? A: 可以 ## Q: 使用 Immer 时,我可以在状态树中存储 `Date` 对象、函数等吗? A: 可以 ## Q: 我可以使用 Map 和 Sets 吗? A: 可以 ## Q: 快吗? A: 快 ## Q: 灵感! Immer 可以为我冻结状态吗? A: 可以 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/freezing.mdx ================================================ --- id: freezing title: 自动冻结 ---
egghead.io 第7课: Immer 自动冻结数据
Hosted on egghead.io
Immer 自动冻结所有使用 `produce` 修改的任何 state。这可以防止在 producer 之外意外修改 state。在大多数情况下,这是最佳实践,但你可以通过 `setAutoFreeze(true / false)` 显式打开或关闭此功能。 Immer 永远不会冻结不可枚举、非自己或符号属性的(内容),除非它们的内容是可以被 `draft` 的。 _⚠️ Immer 以递归方式冻结所有内容,对于将来不会更改的大型数据对象,这可能会矫枉过正,在这种情况下,使用 `freeze` 函数 浅层冻结数据会更有效。⚠️_ _⚠️ 如果启用了自动冻结,recipe 函数并非完全没有副作用:任何最终出现在 produce 结果中的普通对象或数组都将被冻结,即使这些对象在 producer 开始之前没有被冻结!⚠️_ ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/installation.mdx ================================================ --- id: installation title: 安装 ---
Immer 可以作为直接依赖项安装,并且可以在任何 ES5 环境中工作: - Yarn: `yarn add immer` - NPM: `npm install immer` - CDN: 暴露的全局变量是 `immer` - Unpkg: `` - JSDelivr: `` - ⚠️ 使用 CDN 时,最好检查浏览器中的 url 并查看它解析为哪个版本,这样当更新发布时,您的用户不会意外地获得更新的版本。因此,请改用如下网址:https://unpkg.com/immer@6.0.3/dist/immer.umd.production.min.js 。在 URL 中将 production.min 替换为 development 以进行开发构建。 ## 选择您的 Immer 版本 _本节仅适用于版本 6 及更高版本_ 为确保 Immer 尽可能小,并非每个项目都需要的功能已选择加入,并且必须明确启用。这可确保在将您的应用程序捆绑用于生产时,未使用的功能不会占用任何空间。 可以选择加入以下功能: | 功能 | 描述 | 调用方法 | | --- | --- | --- | | ES 5 支持 | 如果您的应用程序需要能够在较旧的 JavaScript 环境(例如 Internet Explorer 或 React Native)上运行,请启用此功能。 | `enableES5()` | | [ES2015 Map and Set 支持](./complex-objects.md) | 要使 Immer 能够对原生 Map 和 Set 集合进行操作,请启用此功能 | `enableMapSet()` | | [JSON 补丁 支持](./patches.mdx) | Immer 可以跟踪您对 draft 对象所做的所有更改。这对于使用 JSON 补丁时传达更改很有用 | `enablePatches()` | 例如,如果您想在 `Map` 上使用 `produce` ,则需要在应用程序启动期间启用此功能一次: ```typescript // 在你的应用程序入口文件 import {enableMapSet} from "immer" enableMapSet() // ...然后 import {produce} from "immer" const usersById_v1 = new Map([ ["michel", {name: "Michel Weststrate", country: "NL"}] ]) const usersById_v2 = produce(usersById_v1, draft => { draft.get("michel").country = "UK" }) expect(usersById_v1.get("michel").country).toBe("NL") expect(usersById_v2.get("michel").country).toBe("UK") ``` Immer 以大约 3KB 的 gzip 压缩开始。每个启用的插件都会增加 < 1 KB。细分如下 ``` Import size report for immer: ┌───────────────────────┬───────────┬────────────┬───────────┐ │ (index) │ just this │ cumulative │ increment │ ├───────────────────────┼───────────┼────────────┼───────────┤ │ import * from 'immer' │ 5033 │ 0 │ 0 │ │ produce │ 3324 │ 3324 │ 0 │ │ enableMapSet │ 4030 │ 4039 │ 715 │ │ enablePatches │ 4112 │ 4826 │ 787 │ └───────────────────────┴───────────┴────────────┴───────────┘ (this report was generated by npmjs.com/package/import-size) ``` ## Immer 使用在旧的 JavaScript 环境? 默认情况下,`produce` 尝试使用代理以获得最佳性能。但是,在较旧的 JavaScript 引擎上,代理不可用。例如,在 Android 上运行 Microsoft Internet Explorer 或 React Native(如果 React Native < v0.59 或在 React Native < v0.64 上使用 Hermes 引擎)时。在这种情况下,Immer 将回退到与 ES5 兼容的实现,其工作方式相同,但速度稍慢 - 从版本 6 开始,必须通过调用 `enableES5()` 显式启用对回退实现的支持 - Version 10 drops the fallback implementation fully, and cannot be used in browsers / engines that don't support Proxy. ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/introduction.md ================================================ --- id: introduction title: Immer 入门 sidebar_label: 入门 slug: / ---
# Immer 2019 年 “年度突破”[React 开源奖](https://osawards.com/react/)和“最有影响的贡献”[JavaScript 开源奖](https://osawards.com/javascript/)的获得者 - 介绍博客: [Immer: Immutability the easy way](https://medium.com/@mweststrate/introducing-immer-immutability-the-easy-way-9d73d8f71cb3) - Egghead.io 简短课程,涵盖 Immer 的基本知识: [Simplify creating immutable data trees with Immer (7 分钟)](https://egghead.io/lessons/redux-simplify-creating-immutable-data-trees-with-immer) - Egghead.io 免费深入课程: [Immutable JavaScript Data Structures with Immer (58 分钟)](https://egghead.io/courses/immutable-javascript-data-structures-with-immer) --- Immer(德语为:always)是一个小型包,可让您以更方便的方式使用不可变状态。 ### Immer 简化了不可变数据结构的处理 Immer 可以在需要使用不可变数据结构的任何上下文中使用。例如与 React state、React 或 Redux reducers 或者 configuration management 结合使用。不可变的数据结构允许(高效)的变化检测:如果对对象的引用没有改变,那么对象本身也没有改变。此外,它使克隆对象相对便宜:数据树的未更改部分不需要复制,并且在内存中与相同状态的旧版本共享 一般来说,这些好处可以通过确保您永远不会更改对象、数组或映射的任何属性来实现,而是始终创建一个更改后的副本。在实践中,这可能会导致代码编写起来非常麻烦,并且很容易意外违反这些约束。 Immer 将通过解决以下痛点来帮助您遵循不可变数据范式: 1. Immer 将检测到意外 mutations 并抛出错误。 2. Immer 将不再需要创建对不可变对象进行深度更新时所需的典型样板代码:如果没有 Immer,则需要在每个级别手动制作对象副本。通常通过使用大量 `...` 展开操作。使用 Immer 时,会对 `draft` 对象进行更改,该对象会记录更改并负责创建必要的副本,而不会影响原始对象。 3. 使用 Immer 时,您无需学习专用 API 或数据结构即可从范例中受益。使用 Immer,您将使用纯 JavaScript 数据结构,并使用众所周知的安全地可变 JavaScript API。 ### 一个简单的比较示例 ```javascript const baseState = [ { title: "Learn TypeScript", done: true }, { title: "Try Immer", done: false } ] ``` 假设我们有上述基本状态,我们需要更新第二个 todo,并添加第三个。但是,我们不想改变原始的 baseState,我们也想避免深度克隆(以保留第一个 todo) #### 不使用 Immer 如果没有 Immer,我们将不得不小心地浅拷贝每层受我们更改影响的 state 结构 ```javascript const nextState = baseState.slice() // 浅拷贝数组 nextState[1] = { // 替换第一层元素 ...nextState[1], // 浅拷贝第一层元素 done: true // 期望的更新 } // 因为 nextState 是新拷贝的, 所以使用 push 方法是安全的, // 但是在未来的任意时间做相同的事情会违反不变性原则并且导致 bug! nextState.push({title: "Tweet about it"}) ``` #### 使用 Immer 使用 Immer,这个过程更加简单。我们可以利用 `produce` 函数,它将我们要更改的 state 作为第一个参数,对于第二个参数,我们传递一个名为 recipe 的函数,该函数传递一个 `draft` 参数,我们可以对其应用直接的 `mutations`。一旦 `recipe` 执行完成,这些 `mutations` 被记录并用于产生下一个状态。 `produce` 将负责所有必要的复制,并通过冻结数据来防止未来的意外修改。 ```javascript import {produce} from "immer" const nextState = produce(baseState, draft => { draft[1].done = true draft.push({title: "Tweet about it"}) }) ``` 正在寻找结合 React 的 Immer?跳到 [React + Immer](example-setstate) 页面 ### Immer 如何工作 基本思想是,使用 Immer,您会将所有更改应用到临时 _draft_,它是 _currentState_ 的代理。一旦你完成了所有的 _mutations_,Immer 将根据对 _draft state_ 的 _mutations_ 生成 nextState。这意味着您可以通过简单地修改数据来与数据交互,同时保留不可变数据的所有好处。 ![immer-hd.png](/img/immer.png) 使用 Immer 就像拥有一个私人助理。助手拿一封信(当前状态)并给您一份副本(草稿)以记录更改。完成后,助手将接受您的草稿并为您生成真正不变的最终字母(下一个状态)。 前往 [下一章节](./produce.mdx) 以进一步深入了解 `produce` ## 好处 - 遵循不可变数据范式,同时使用普通的 JavaScript 对象、数组、Sets 和 Maps。无需学习新的 API 或 "mutations patterns"! - 强类型,无基于字符串的路径选择器等 - 开箱即用的结构共享 - 开箱即用的对象冻结 - 深度更新轻而易举 - 样板代码减少。更少的噪音,更简洁的代码 - 对 JSON 补丁的一流支持 - 小:3KB gzip ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/map-set.md ================================================ --- id: map-set title: Map 和 Set ---
_⚠ 从版本6开始,对 `Map` 和 `Set` 的支持必须在启动应用程序时通过显式调用 [`enableMapSet()`](./installation.mdx#pick-your-immer-version)来开启_ 普通对象、数组、`Map` 和 `Set` 总是可以用 Immer 更新。一个使用 `Map` 和 Immer 的示例: ```javascript test("Producers can update Maps", () => { const usersById_v1 = new Map() const usersById_v2 = produce(usersById_v1, draft => { // 修改 map 会生成一个新的 map draft.set("michel", {name: "Michel Weststrate", country: "NL"}) }) const usersById_v3 = produce(usersById_v2, draft => { // 在 map 深处进行修改,同样会生成一个新的 map! draft.get("michel").country = "UK" }) // 我们每次都会得到一个新的 map expect(usersById_v2).not.toBe(usersById_v1) expect(usersById_v3).not.toBe(usersById_v2) // 显然它们的内容不同 expect(usersById_v1).toMatchInlineSnapshot(`Map {}`) expect(usersById_v2).toMatchInlineSnapshot(` Map { "michel" => Object { "country": "NL", "name": "Michel Weststrate", }, } `) expect(usersById_v3).toMatchInlineSnapshot(` Map { "michel" => Object { "country": "UK", "name": "Michel Weststrate", }, } `) // 旧的从来不会被更改 expect(usersById_v1.size).toBe(0) // 试图在 produce 之外修改 map 对象是不行的! expect(() => usersById_v3.clear()).toThrowErrorMatchingInlineSnapshot( `"This object has been frozen and should not be mutated"` ) }) ``` Immer 生成的 Map 和 Set 将被人为地设置为不可变。这意味着在 `produce` 之外尝试 `set`、`clear`等可变方法时,它们将抛出异常。 注意:map 的**键**永远不会被更改!这样做是为了避免混淆语义并保持键始终引用相等 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/original.md ================================================ --- id: original title: 从 draft 中提取原始 state sidebar_label: Original ---
Immer中暴露了一个命名对象 `original`,将从 `produce` 内部的代理实例获取原始对象(对于未代理值返回 `undefined`。 一个好的例子是:当在一个树状 state 中使用严格相等搜索结点的时候它很有用。 ```js import {original, produce} from "immer" const baseState = {users: [{name: "Richie"}]} const nextState = produce(baseState, draftState => { original(draftState.users) // is === baseState.users }) ``` 只是想知道一个值是否是代理实例?使用 `isDraft` 函数!请注意,不能在不是 draft 的对象上调用 `original`。 ```js import {isDraft, produce} from "immer" const baseState = {users: [{name: "Bobby"}]} const nextState = produce(baseState, draft => { isDraft(draft) // => true isDraft(draft.users) // => true isDraft(draft.users[0]) // => true }) isDraft(nextState) // => false ``` ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/other-lang.md ================================================ --- id: other-lang title: 移植到其它语言 --- Immer 已经被移植到其它编程语言。 |编程语言|链接| |---|---| |Java|[Jimmer](https://babyfish-ct.github.io/jimmer-doc/)| ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/patches.mdx ================================================ --- id: patches title: Patches ---
egghead.io 第14课: 使用 produceWithPatches 捕获 Patches
Hosted on egghead.io
egghead.io 第16课: 使用 applyPatches 应用 Patches
Hosted on egghead.io
_⚠ 在版本 6 之后,必须在启动应用程序调用一次 [`enablePatches()`](./installation.mdx#pick-your-immer-version) 来启用对 Patches 的支持。_ 在 producer 运行期间,Immer 可以记录所有的补丁来回溯 reducer 造成的更改 。这是一个非常强大的工具,如果您想暂时 fork 您的状态并回溯对原始状态的更改。 Patches 在下面场景很有用: - 与其他方交换增量更新,例如通过 - 对于调试/跟踪,准确查看状态如何随时间变化 - 作为撤消/重做的基础或作为在稍微不同的状态树上回溯更改的方法。 为了帮助回溯补丁,`applyPatches` 派上用场了。这是一个如何使用 Patches 来记录增量更新并(反向)应用它们的示例: ```javascript import {produce, applyPatches} from "immer" // 版本 6 import {enablePatches} from "immer" enablePatches() let state = { name: "Micheal", age: 32 } // 假设用户在向导中 // 他的更改 应该以最终是否为基本状态结束... let fork = state // 用户在向导中所作的所有更改 let changes = [] // 与向导中所做的所有更改相反 let inverseChanges = [] fork = produce( fork, draft => { draft.age = 33 }, // 产生的第三个参数是一个回调,patches 将从这里产生 (patches, inversePatches) => { changes.push(...patches) inverseChanges.push(...inversePatches) } ) // 同时,我们的原始状态被替换,例如 // 从服务器收到了一些更改 state = produce(state, draft => { draft.name = "Michel" }) // 当向导完成(成功)后,我们可以将 fork 中的更改重播到新的状态! state = applyPatches(state, changes) // state 现在包含来自两个代码路径的更改! expect(state).toEqual({ name: "Michel", // 服务器更改 age: 33 // 向导更改 }) // 最后,即使在完成向导之后,用户也可能会改变主意并撤消他的更改...... state = applyPatches(state, inverseChanges) expect(state).toEqual({ name: "Michel", // 没有还原 age: 32 // 还原了 }) ``` 生成的 patches 与 [RFC-6902 JSON patch standard](https://datatracker.ietf.org/doc/html/rfc6902/#section-4.1) 类似(但并不相同),除了 path 属性是一个数组,而不是一个字符串。这使得处理 patches 更加容易。如果你想规范化到官方格式,`patch.path = patch.path.join("/")`应该可以解决这个问题。无论如何,下面就是一堆 patches 和它们回溯的样子。 ```json [ { "op": "replace", "path": ["profile"], "value": {"name": "Veria", "age": 5} }, {"op": "remove", "path": ["tags", 3]} ] ``` ```json [ {"op": "replace", "path": ["profile"], "value": {"name": "Noa", "age": 6}}, {"op": "add", "path": ["tags", 3], "value": "kiddo"} ] ``` ⚠ 注意: Immer 生成的补丁集应该是正确的,也就是说,将它们应用于相同的基础对象应该会导致相同的最终状态。然而,Immer 不保证生成的补丁集是最优的,即可能的最小补丁集。它通常取决于被认为是“最佳”的用例,并且生成最佳补丁集在计算上可能非常昂贵。因此,在某些情况下,您可能想要对生成的补丁进行后处理,或者按照下面的说明压缩它们。 ### `produceWithPatches`
egghead.io 第19课: 使用回溯 patches 构建撤销功能
Hosted on egghead.io
egghead.io 第20课: 使用 patches 构建重做功能
Hosted on egghead.io
除了设置 patch 监听器之外,获取 patches 的更简单方法是使用 `produceWithPatches`,它与 `produce` 具有相同的签名,不过它不止返回 next state,而是一个包含 `[nextState, patches, inversePatches]` 的元组,和 `produce` 一样,`produceWithPatches` 也支持柯里化。 ```javascript import {produceWithPatches} from "immer" const [nextState, patches, inversePatches] = produceWithPatches( { age: 33 }, draft => { draft.age++ } ) ``` 将返回: ```javascript ;[ { age: 34 }, [ { op: "replace", path: ["age"], value: 34 } ], [ { op: "replace", path: ["age"], value: 33 } ] ] ``` 有关更深入的研究,请参阅使用 [Distributing patches and rebasing actions using Immer](https://medium.com/@mweststrate/distributing-state-changes-using-snapshots-patches-and-actions-part-2-2f50d8363988) 提示:使用此技巧可以 [compress patches](https://medium.com/@david.b.edelstein/using-immer-to-compress-immer-patches-f382835b6c69) ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/performance.mdx ================================================ --- id: performance title: Immer 性能 ---
egghead.io 第5课: 在 React 中利用 Immer 的结构共享
Hosted on egghead.io
egghead.io 第7课: 如果没有语义变化,Immer 会使用原先的数据
Hosted on egghead.io
这是一个关于 Immer 性能的 [简单 benchmark](https://github.com/immerjs/immer/blob/main/__performance_tests__/todo.js) 。该测试需要 50,000 个待办事项并更新其中的 5,000 个。 _Freeze_ 表示状态树在生成后已被冻结。这是一种开发最佳实践,因为它可以防止开发人员意外修改状态树。 上面的数字没有反映一些东西,但实际上,Immer 有时比手写的 reducer _快_ 得多。这样做的原因是,Immer 会检测“无操作”状态变化,如果实际上没有任何变化,则返回原始状态,这可以避免很多重新渲染。众所周知,只需应用 immer 即可解决关键性能问题。 这些测试在 Node 10.16.3 上执行。使用 `yarn test:perf` 在本地重现它们。 ![performance.png](/img/performance.png) 最重要的结论: - Immer with proxies 大约比手写 reducer 慢 2 到 3 倍(上面的测试用例是最坏的情况,请参阅 `yarn test:perf` 了解更多测试情况)。这在实践中可以忽略不计。 - Immer 的速度大致与 ImmutableJS 一样快。但是,_immutableJS + toJS_ 明确了后期往往需要付出的代价;将 immutableJS 对象转换回普通对象,以便将它们传递给组件或者进行序列化操作在网络中传输......(还有将从服务器接收到的数据转换为不可变 JS 的前期成本) - 生成 patches 不会显著减慢 immer - ES5 后备实现的速度大约比代理实现慢两倍,在某些情况下更糟。 ## 性能提示 ### 预冻结数据 当向 Immer producer 中的状态树添加大型数据集时(例如从 JSON 端点接收的数据),可以在首先添加的数据的根上调用 `freeze(json)` ,来*浅冻结*它。这将允许 Immer 更快地将新数据添加到树中,因为它将避免*递归*扫描和冻结新数据的需要。 ### 您可以随时选择退出 immer 在任何地方都是可选的,因此手动编写性能非常苛刻的 reducers ,并将 immer 用于所有普通的的 reducers 是非常好的。即使在 producer 内部,您也可以通过使用 `original` 或 `current` 函数来选择退出 Immer 的某些部分逻辑,并对纯 JavaScript 对象执行一些操作。 ### 对于昂贵的搜索操作,从原始 state 读取,而不是 draft Immer 会将您在 draft 中读取的任何内容也递归地转换为 draft。如果您对涉及大量读取操作的 draft 进行昂贵的无副作用操作,例如在非常大的数组中使用 `find(Index)` 查找索引,您可以通过首先进行搜索,并且只在知道索引后调用 `produce` 来加快速度。这样可以阻止 Immer 将在 draft 中搜索到的所有内容都进行转换。或者,使用 `original(someDraft)` 对 draft 的原始值执行搜索,这归结为同样的事情。 ### 将 produce 拉到尽可能远的地方 始终尝试将 produce “向上”拉动,例如 `for (let x of y) produce(base, d => d.push(x))` 比 `produce(base, d => { for (let x of y) ) d.push(x)})` 慢得多 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/pitfalls.md ================================================ --- id: pitfalls title: 陷阱 ---
### 性能提示 对于性能提示,阅读 [性能提示](./performance.mdx#performance-tips). ### 不要重新分配 recipe 参数 永远不要重新分配 `draft` 参数(例如:`draft = myCoolNewState`)。相反,要么修改 draft,要么返回新状态。请参阅[从 producers 返回数据](./return.mdx)。 ### Immer 只支持单向树 Immer 假设您的状态是单向树。也就是说,任何对象都不应该在树中出现两次,也不应该有循环引用。从根到树的任何节点应该只有一条路径。 ### 永远不要从 producer 那里显式返回 `undefined` 可以从 producers 返回值,但不能以这种方式返回 `undefined`,因为它与根本不更新 draft 没有区别!如果你想用 `undefined` 替换 draft,只需从 producer 那里返回 `nothing`。 ### 不要修改特殊对象 Immer [不支持特殊对象](https://github.com/immerjs/immer/issues/504) 比如 window.location. ### 类应该是可 draft 的或不可变的 您将需要使自己的类能与 Immer 一起正常工作。有关该主题的文档,请查看有关使用[复杂对象](./complex-objects.md)的部分。 ### 只有有效的索引和长度可以在数组上改变 对于数组,只能改变数值属性和 `length` 属性。自定义属性不会保留在数组上。 ### 只有来自 state 的数据会被 draft 请注意,来自闭包而不是来自基本 state 的数据将永远不会被 draft,即使数据已成为新 darft 的一部分。 ```javascript function onReceiveTodo(todo) { const nextTodos = produce(todos, draft => { draft.todos[todo.id] = todo // 注意,因为 todo 来自外部,而不是 draft,所以他不会被 draft, // 所以下面的修改会影响原来的 todo! draft.todos[todo.id].done = true // 上面的代码相当于 todo.done = true draft.todos[todo.id] = todo }) } ``` ### Immer patches 不一定是最优的 Immer 生成的 patches 应该是正确的,也就是说,将它们应用于相同的基础对象应该会导致相同的最终状态。然而,Immer 不保证生成的 patches 是最优的,即可能的最小 patches ### 始终使用嵌套 producers 的结果 支持嵌套调用 `produce` ,但请注意 `produce` 将_始终_产生新状态,因此即使将 draft 传递给嵌套 produce,内部 produce 所做的更改也不会在传递给它的 draft 中可见,只会反映在产生的输出中。换句话说,当使用嵌套 produce 时,您会得到 draft 的 draft,并且内部 produce 的结果应该合并回原始 draft(或返回)。例如,如果内部 produce 的输出没有被使用的话, `produce(state, draft => {produce(draft.user, userDraft => { userDraft.name += "!" })})` 将不会生效。使用嵌套 producers 的正确方法是: ```javascript produce(state, draft => { draft.user = produce(draft.user, userDraft => { userDraft.name += "!" }) }) ``` ### Drafts 在引用上不相等 Immer 中的 draft 对象包装在 `Proxy` 中,因此您不能使用 `==` 或 `===` 来测试原始对象与其 draft 之间的相等性(例如,当匹配数组中的特定元素时)。相反,您可以使用 `original` 助手: ```javascript const remove = produce((list, element) => { const index = list.indexOf(element) // 不会工作! const index = original(list).indexOf(element) // 用这个! if (index > -1) list.splice(index, 1) }) const values = [a, b, c] remove(values, a) ``` 如果可以的话,建议在 `produce` 函数之外执行比较,或者使用 `.id` 之类的唯一标识符属性,以避免需要使用 `original`。 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/produce.mdx ================================================ --- id: produce title: 使用 produce ---
egghead.io 第 3 课:使用 produce 简化深度更新
Hosted on egghead.io
Immer 包暴露了一个完成所有工作的默认函数。 `produce(currentState, recipe: (draftState) => void): nextState` `produce` 需要一个 `baseState`,以及一个可用于对传入的 `draft` 进行所有所需更改的 `recipe`。关于 Immer 的有趣之处在于 baseState 将保持不变,但 nextState 将反映对 DraftState 所做的所有更改. 在 `recipe` 中,所有标准的 JavaScript API 都可以在 `draft` 对象上使用,包括属性字段分配、删除操作和修改数组、Map 和 Set 操作,如 push、pop、splice、set、sort、remove 等。 这些 `mutations` 中的任何一个都不必发生在初始对象上,但它可以修改 `draft` 深处的任何内容:`draft.todos[0].tags["urgent"].author.age = 56` 请注意,`recipe` 函数通常不会返回任何内容。但是,如果您想用另一个对象完全替换 `draft`,则可以返回,有关更多详细信息,请参阅返回[新数据](return)。 ## 例子 ```javascript import {produce} from "immer" const baseState = [ { title: "Learn TypeScript", done: true }, { title: "Try Immer", done: false } ] const nextState = produce(baseState, draftState => { draftState.push({title: "Tweet about it"}) draftState[1].done = true }) ``` ```javascript // 新的 item 仅仅被添加到了 next state // base state 没有被修改 expect(baseState.length).toBe(2) expect(nextState.length).toBe(3) // 同上 expect(baseState[1].done).toBe(false) expect(nextState[1].done).toBe(true) // 未修改的数据结构共享 expect(nextState[0]).toBe(baseState[0]) // 改变的数据不是 expect(nextState[1]).not.toBe(baseState[1]) ``` ### 术语 - `(base)state`, 传递给 `produce` 的不可变状态 - `recipe`: `produce` 的第二个参数,它捕获了 base state 应该如何 `mutated`。 - `draft`: 任何 `recipe` 的第一个参数,它是可以安全 `mutate` 的原始状态的代理。 - `producer`. 一个使用 `produce` 的函数,通常形式为 `(baseState, ...arguments) => resultState` 请注意,命名 `recipe` 的第一个参数 `draft` 并不是绝对必要的。您可以将其命名为任何您想要的名称,例如 `user`。使用 `draft` 作为名称只是一个约定,以表明:“这里的 `mutation` 是可以的”。 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/resources.md ================================================ --- id: resources title: 外部资源 ---
- 博客: [Immer 在 React 中的兴起](https://www.netlify.com/blog/2018/09/12/the-rise-of-immer-in-react/) - 博客: 由 Workday Prism 解释他们为什么选择 Immer 来管理不可变状态 [寻找强类型、不可变的状态](https://medium.com/workday-engineering/workday-prism-analytics-the-search-for-a-strongly-typed-immutable-state-a09f6768b2b5) - 博客: [React 和 Redux 中的不可变性:完整指南](https://daveceddia.com/react-redux-immutability-guide/) - 视频教程: [将 Immer 与 React.setState 一起使用](https://codedaily.io/screencasts/86/Immutable-Data-with-Immer-and-React-setState) - Michel Weststrate 在 React Finland 2018 上的 Immer [演讲](https://www.youtube.com/watch?v=-gJbS7YjcSo) + [幻灯片](http://immer.surge.sh/) - [ForwardJS 2019:不可变性正在改变——从 Immutable.js 到 Immer](https://www.youtube.com/watch?v=bFuRvcAEiHg&feature=youtu.be) by [shawn swyx wang](https://twitter.com/swyx/) - [演讲:Immer、不可变性和代理的奇妙世界](https://www.youtube.com/watch?v=4Nb9Gwp2L24) + [幻灯片](https://jsnation-proxies.surge.sh/), JSNation 2019, Michel Weststrate - 博客: [使用快照、patches 和操作分发状态更改](https://medium.com/@mweststrate/distributing-state-changes-using-snapshots-patches-and-actions-part-1-2811a2fcd65f) - 博客: [在 Redux 中实现 Undo-Redo 功能](https://techinscribed.com/implementing-undo-redo-functionality-in-redux-using-immer/), 2019年9月 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/return.mdx ================================================ --- id: return title: 从 producers 返回新数据 ---
egghead.io 第9课: 返回全新 state
Hosted on egghead.io
不需要从 producer 那里返回任何东西,因为 Immer 无论如何都会返回 `draft` 的(最终)版本。但是,也允许仅仅 `return draft`。 也允许从 producer 函数中任意返回其他数据。但*前提*是你没有修改 `draft`。这对于产生一个全新的 state 很有用。一些例子: ```javascript const userReducer = produce((draft, action) => { switch (action.type) { case "renameUser": //可以: 我们修改了当前的 state draft.users[action.payload.id].name = action.payload.name return draft // 与仅仅 'return' 相同 case "loadUsers": // 可以: 我们返回了一个全新的 state return action.payload case "adduser-1": // 不行: 这不会改变 draft ,也不会返回新的状态 // 它不会修改 draft(它只是重新声明它) // 事实上,这根本没有做任何事情 draft = {users: [...draft.users, action.payload]} return case "adduser-2": // 不行: 修改 draft 的同时返回了一个新的状态 draft.userCount += 1 return {users: [...draft.users, action.payload]} case "adduser-3": // 可以: 返回一个新的状态。但是,不必要的复杂和昂贵 return { userCount: draft.userCount + 1, users: [...draft.users, action.payload] } case "adduser-4": // 可以: immer 的方式 draft.userCount += 1 draft.users.push(action.payload) return } }) ``` _注意:无法以这种方式返回 `undefined` ,因为它与不更新 draft 没有区别!继续阅读......_ ## 使用 `nothing` 产生 `undefined` 因此,一般来说,可以通过从 producer 返回一个新值来替换当前 state,而不是修改 draft。然而,有一个微妙的边缘情况:如果您尝试编写一个想要用 undefined 替换当前状态的 producer: ```javascript produce({}, draft => { // 什么也不干 }) ``` 或者: ```javascript produce({}, draft => { // 尝试从 producer 中返回 undefined return undefined }) ``` 问题在于,在 JavaScript 中,一个不返回任何内容的函数也会返回 `undefined`!所以 immer 无法区分这些不同的情况。因此,默认情况下,Immer 会假设任何返回 `undefined` 的 producer 只是试图修改 draft。 但是,为了让 Immer 清楚您有意生成 `undefined` 值,您可以返回内置标记 `nothing`: ```javascript import {produce, nothing} from "immer" const state = { hello: "world" } produce(state, draft => {}) produce(state, draft => undefined) // 都会返回最初的状态: { hello: "world"} produce(state, draft => nothing) // 产生一个新的状态, 'undefined' ``` 注:请注意,此问题特定于 `undefined` 值,任何其他值(包括 `null`)都不会受到此问题的影响 提示:为了能够在使用 TypeScript 时从 recipe 中返回 `nothing`,`state` 的类型必须接受 undefined 值。 ## 使用 `void` 的内联快捷方式
egghead.io 第10课: 使用 _void_ 避免意外的返回
Hosted on egghead.io
Immer 中的 draft 修改通常需要一段代码块,因为返回表示覆盖。有时候你可能觉得这么多的样板代码很糟心。 在这种情况下,您可以使用 javascripts [`void`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void) 运算符,它计算表达式并返回 `undefined`。 ```javascript // 单次修改 produce(draft => void (draft.user.age += 1)) // 多次修改 produce(draft => void ((draft.user.age += 1), (draft.user.height = 186))) ``` 代码风格是高度个人化的,但对于要被许多人理解的代码库,我们建议坚持经典的 `draft => { draft.user.age += 1}` 以避免认知开销。 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/support.md ================================================ --- id: support title: 赞助 immer ---
Immer 目前在 GitHub 上有 350000 个项目依赖于它,每月的下载量接近 10000000 次。然而,只有一开始两天的开发得到了赞助(由 Mendix),之后的所有开发和维护都是用爱发电。 如果您喜欢 Immer,并且对这个包心存感激,或者想确保它的使用寿命,请考虑在 https://opencollective.com/immer 上赞助或使用 [PayPal](https://www.paypal.me/michelweststrate) 进行一次性捐赠。 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/typescript.mdx ================================================ --- id: typescript title: Using TypeScript or Flow sidebar_label: TypeScript / Flow ---
egghead.io 第12课: Immer + TypeScript
Hosted on egghead.io
Immer 包附带了类型定义,TypeScript 和 Flow 开箱即可获取这些定义,无需进一步配置 TypeScript 类型会自动从 draft 类型中删除 `readonly` 修饰符,并返回与原始类型匹配的值。看这个实际的例子: ```ts import {produce} from "immer" interface State { readonly x: number } // `x` 不能被修改 const state: State = { x: 0 } const newState = produce(state, draft => { // `x` 可以被修改 draft.x++ }) // `newState.x` 不能在这里被修改 ``` 这确保了您可以修改状态的唯一位置是在您的 produce 回调中。它甚至可以递归地和 `ReadonlyArray` 一起工作。 ## 最佳实践 1. 始终尽可能将您的 state 定义为只读。这最好地反映了心智模型和现实,因为 Immer 将冻结其所有返回值。 2. 您可以使用实用类型 `Immutable` 递归地使整个类型树成为只读的,例如:`type ReadonlyState = Immutable` 3. 如果输入状态的原始类型不是不可变的,则 Immer 不会自动将所有返回的类型包装在 `Immutable` 中。这是为了确保它不会破坏不使用不可变类型的代码库。 ## 柯里化 producers 的提示 我们尝试尽可能多地推断。因此,如果创建了一个柯里化 producer 并直接传递给另一个函数,我们可以从那里推断出类型。这适用于例如 React: ```typescript import {Immutable, produce} from "immer" type Todo = Immutable<{ title: string done: boolean }> // 然后... const [todo, setTodo] = useState({ title: "test", done: true }) // 然后... setTodo( produce(draft => { // draft 将是强类型和可变的! draft.done = !draft.done }) ) ``` 当柯里化 producers 没有直接传递到其他地方时,Immer 可以从 draft 参数推断状态类型。例如在执行以下操作时: ```typescript // 请参阅下文以获得更好的解决方案 const toggler = produce((draft: Draft) => { draft.done = !draft.done }) // typeof toggler = (state: Immutable) => Writable ``` 请注意,我们确实用 `Draft` 包装了 `draft` 参数的 `Todo` 类型,因为 `Todo` 是只读类型。对于非只读类型,这不是必需的 对于返回的柯里化函数 `toggler`,我们将输入类型缩小为 `Immutable`,这样即使 `Todo` 是可变类型,我们仍将接受不可变的 todo 作为切换器的输入参数。 与之相反,Immer 会将柯里化函数的输出类型*扩展*为 `Writable`,以确保它的输出状态也可分配给未明确键入为不可变的变量。 这种类型的缩小/扩大行为可能不受欢迎,甚至可能因为它会导致类型非常多的噪音。因此,我们建议为柯里化 produces 指定 state 泛型 ,以防它无法直接推断,例如上面的 `toggler`。通过这样做,将跳过自动输出扩大/输入缩小。然而,`draft` 参数本身仍将被推断为可写 `Draft`: ```typescript const toggler = produce(draft => { draft.done = !draft.done }) // typeof toggler = (state: Todo) => Todo ``` 但是,如果柯里化 producer 定义了初始状态,Immer 可以从初始状态推断状态类型,因此在这种情况下也不需要指定泛型: ```typescript const state0: Todo = { title: "test", done: false } // 不需要类型注释,因为我们可以从 state0 推断。 const toggler = produce(draft => { draft.done = !draft.done }, state0) // typeof toggler = (state: Todo) => Todo ``` 如果 toggler 没有初始状态,并且它有柯里化参数,并且您显式设置 state 泛型,则任何附加参数的类型也应显式定义为元组类型: ```typescript const toggler = produce((draft, newState) => { draft.done = newState }) // typeof toggler = (state: Todo, newState: boolean) => Todo ``` ## 类型转换 `produce` 内部和外部的类型在概念上可以相同,但从实际角度来看是不同的。例如,上面示例中的 `State` 应被视为在 `produce` 外部不可变,但在 `produce` 内部是可变的。 有时这会导致实际冲突。举个例子: ```typescript type Todo = {readonly done: boolean} type State = { readonly finishedTodos: readonly Todo[] readonly unfinishedTodos: readonly Todo[] } function markAllFinished(state: State) { produce(state, draft => { draft.finishedTodos = state.unfinishedTodos }) } ``` 这将产生错误: ``` The type 'readonly Todo[]' is 'readonly' and cannot be assigned to the mutable type '{ done: boolean; }[]' ``` 这个错误的原因是我们将只读的、不可变的数组分配给我们的 draft,draft 需要一个可变的类型,并带有 .push 等方法。就 TS 而言,这些并没有从我们的原始 `State` 中暴露出来。为了提示 TypeScript 我们希望将此处的集合向上转换为可变数组以用于 draft,我们可以使用函数 `castDraft`: `draft.finishedTodos = castDraft(state.unfinishedTodos)` 将使错误消失。 还有函数 `castImmutable`,以防您需要实现相反的效果。请注意,这些函数出于所有实际目的都是无操作的,它们只会返回其原始值。 提示:您可以将 `castImmutable` 与 `produce` 结合起来,将 `produce` 的返回类型定义为不可变的内容,即使原始 state 是可变的 ```typescript // 一个可变数据结构 const baseState = { todos: [{ done: false }] } const nextState = castImmutable(produce(baseState, _draft => {})) // nextState 的推断类型现在是: { readonly todos: ReadonlyArray<{ readonly done: boolean }> }) ``` ## 兼容性 **注意:** Immer v5.3+ 仅支持 TypeScript v3.7+ **注意:** Immer v3.0+ 仅支持 TypeScript v3.4+ **注意:** Immer v1.9+ 仅支持 TypeScript v3.1+ **注意:** 在未来的版本中可能会删除 flow 支持,我们建议使用 TypeScript ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current/update-patterns.md ================================================ --- id: update-patterns title: 更新模式 ---
在 Immer 之前,使用不可变数据意味着学习所有不可变的更新模式。 为了帮助“忘记”这些模式,这里概述了如何利用内置 JavaScript API 来更新对象和集合 ### 更新对象 ```javascript import {produce} from "immer" const todosObj = { id1: {done: false, body: "Take out the trash"}, id2: {done: false, body: "Check Email"} } // 添加 const addedTodosObj = produce(todosObj, draft => { draft["id3"] = {done: false, body: "Buy bananas"} }) // 删除 const deletedTodosObj = produce(todosObj, draft => { delete draft["id1"] }) // 更新 const updatedTodosObj = produce(todosObj, draft => { draft["id1"].done = true }) ``` ### 更新数组 ```javascript import {produce} from "immer" const todosArray = [ {id: "id1", done: false, body: "Take out the trash"}, {id: "id2", done: false, body: "Check Email"} ] // 添加 const addedTodosArray = produce(todosArray, draft => { draft.push({id: "id3", done: false, body: "Buy bananas"}) }) // 索引删除 const deletedTodosArray = produce(todosArray, draft => { draft.splice(3 /*索引 */, 1) }) // 索引更新 const updatedTodosArray = produce(todosArray, draft => { draft[3].done = true }) // 索引插入 const updatedTodosArray = produce(todosArray, draft => { draft.splice(3, 0, {id: "id3", done: false, body: "Buy bananas"}) }) // 删除最后一个元素 const updatedTodosArray = produce(todosArray, draft => { draft.pop() }) // 删除第一个元素 const updatedTodosArray = produce(todosArray, draft => { draft.shift() }) // 数组开头添加元素 const addedTodosArray = produce(todosArray, draft => { draft.unshift({id: "id3", done: false, body: "Buy bananas"}) }) // 根据 id 删除 const deletedTodosArray = produce(todosArray, draft => { const index = draft.findIndex(todo => todo.id === "id1") if (index !== -1) draft.splice(index, 1) }) // 根据 id 更新 const updatedTodosArray = produce(todosArray, draft => { const index = draft.findIndex(todo => todo.id === "id1") if (index !== -1) draft[index].done = true }) // 过滤 const updatedTodosArray = produce(todosArray, draft => { // 过滤器实际上会返回一个不可变的状态,但是如果过滤器不是处于对象的顶层,这个依然很有用 return draft.filter(todo => todo.done) }) ``` ### 嵌套数据结构 ```javascript import {produce} from "immer" // 复杂数据结构例子 const store = { users: new Map([ [ "17", { name: "Michel", todos: [ { title: "Get coffee", done: false } ] } ] ]) } // 深度更新 const nextStore = produce(store, draft => { draft.users.get("17").todos[0].done = true }) // 过滤 const nextStore = produce(store, draft => { const user = draft.users.get("17") user.todos = user.todos.filter(todo => todo.done) }) ``` 请注意,许多数组操作可用于通过传递多个参数或使用展开操作来一次插入多个元素:`todos.unshift(...items)`。 请注意,当处理包含通常由某个 id 标识的对象的数组时,我们建议使用基于 `Map` 或索引的对象(如上所示)而不是执行频繁的查找操作,查找表通常执行效率更高。 ================================================ FILE: website/i18n/zh-CN/docusaurus-plugin-content-docs/current.json ================================================ { "version.label": { "message": "Next", "description": "The label for version current" }, "sidebar.Immer.category.Basics": { "message": "基础", "description": "The label for category Basics in sidebar Immer" }, "sidebar.Immer.category.Advanced Features": { "message": "高级", "description": "The label for category Advanced Features in sidebar Immer" }, "sidebar.Immer.category.Resources": { "message": "资源", "description": "The label for category Resources in sidebar Immer" } } ================================================ FILE: website/i18n/zh-CN/docusaurus-theme-classic/footer.json ================================================ { "copyright": { "message": "Copyright © 2022 Michel Weststrate", "description": "The footer copyright" } } ================================================ FILE: website/i18n/zh-CN/docusaurus-theme-classic/navbar.json ================================================ { "title": { "message": "Immer", "description": "The title in the navbar" }, "item.label.Documentation": { "message": "文档", "description": "Navbar item with label Documentation" }, "item.label.GitHub": { "message": "GitHub", "description": "Navbar item with label GitHub" }, "item.label.Support Immer": { "message": "赞助 Immer", "description": "Navbar item with label Support Immer" } } ================================================ FILE: website/package.json ================================================ { "name": "immer-website", "license": "MIT", "private": true, "scripts": { "examples": "docusaurus-examples", "start": "docusaurus start", "build": "docusaurus build", "publish-gh-pages": "docusaurus publish", "write-translations": "docusaurus write-translations" }, "dependencies": { "@docusaurus/core": "^2.4.0", "@docusaurus/plugin-client-redirects": "^2.4.0", "@docusaurus/plugin-content-docs": "^2.4.0", "@docusaurus/plugin-google-analytics": "^2.4.0", "@docusaurus/plugin-google-gtag": "^2.4.0", "@docusaurus/plugin-sitemap": "^2.4.0", "@docusaurus/theme-classic": "^2.4.0", "react": "^16.8.4", "react-dom": "^16.8.4" } } ================================================ FILE: website/sidebars.js ================================================ module.exports = { Immer: { Basics: [ "introduction", "installation", "produce", "curried-produce", "example-setstate", "update-patterns" ], "Advanced Features": [ "api", "map-set", "array-methods", "complex-objects", "current", "original", "patches", "freezing", "return", "async", "typescript" ], Resources: [ "performance", "resources", "faq", "pitfalls", "built-with", "support", "other-lang" ] } } ================================================ FILE: website/src/css/immer-infima.css ================================================ /* :root { --ifm-color-primary: #000; } */ a { color: #c200c2; } a:hover { text-decoration: underline; } .navbar--dark { --ifm-navbar-background-color: black; --ifm-menu-color: white; --ifm-menu-color-background-hover: rgba(255, 255, 255, 0.1); } .navbar--fixed-top { color: white; font-weight: bold; } .navbar--fixed-top a { color: white; } :root { --ifm-link-color: #c200c2; } details { margin-bottom: 20px; background: #e2e2e2; } details[open] { border-bottom: 2px solid #c200c2; } details iframe { padding: 0 20px; } details a { display: block; text-align: right; font-size: 0.8em; color: #666; } .egghead-summary { color: white; background: #c200c2; padding: 5px; margin: 0px; border-radius: 2px; cursor: pointer; } .egghead-link { font-style: italic; padding: 5px; margin: 5px; } iframe { border: none; } .dropdown__link { color: black !important; } /* Announcement banner */ :root { --docusaurus-announcement-bar-height: auto !important; } div[class^="announcementBarContent"] { line-height: 40px; font-size: 20px; font-weight: bold; padding: 8px 30px; } div[class^="announcementBarContent"] a { text-decoration: underline; display: inline-block; color: var(--ifm-color-primary-lightest) !important; } div[class^="announcementBarContent"] a:hover { color: var(--brand) !important; } @media only screen and (max-width: 768px) { .announcement { font-size: 18px; } } @media only screen and (max-width: 500px) { .announcement { font-size: 15px; line-height: 22px; padding: 6px 30px; } } ================================================ FILE: website/static/.nojekyll ================================================

Please provide either a CodeSandbox demo or a minimal repository on GitHub.