├── Procfile
├── src
├── marko.json
├── layouts
│ └── default
│ │ ├── browser.json
│ │ ├── style.less
│ │ └── index.marko
├── components
│ ├── app-overlay
│ │ ├── marko-tag.json
│ │ ├── index.marko
│ │ ├── style.less
│ │ └── component.js
│ ├── app
│ │ ├── style.less
│ │ ├── component.js
│ │ └── index.marko
│ ├── app-notification
│ │ ├── index.marko
│ │ ├── component.js
│ │ └── style.less
│ ├── app-tabs
│ │ ├── marko-tag.json
│ │ ├── style.less
│ │ └── index.marko
│ ├── app-markdown
│ │ ├── marko-tag.json
│ │ └── code-generator.js
│ ├── app-sections
│ │ ├── marko-tag.json
│ │ ├── style.less
│ │ └── index.marko
│ ├── app-checkbox
│ │ ├── marko-tag.json
│ │ ├── images
│ │ │ ├── unchecked.svg
│ │ │ └── checked.svg
│ │ ├── style.less
│ │ └── index.marko
│ ├── app-state-select
│ │ ├── CA.png
│ │ ├── CO.png
│ │ └── index.marko
│ ├── app-progress-bar
│ │ ├── marko-tag.json
│ │ ├── index.marko
│ │ ├── style.less
│ │ └── component.js
│ ├── app-map
│ │ ├── marko-tag.json
│ │ ├── browser.json
│ │ └── index.marko
│ ├── app-fetch-data
│ │ ├── style.less
│ │ ├── index.marko
│ │ └── loading.svg
│ ├── app-notifications
│ │ ├── index.marko
│ │ └── component.js
│ ├── app-button
│ │ ├── marko-tag.json
│ │ ├── style.less
│ │ └── index.marko
│ └── app-number-spinner
│ │ ├── index.marko
│ │ └── style.css
├── services
│ ├── package.json
│ ├── users-browser.js
│ ├── routes.js
│ ├── users.js
│ └── mock-users-data.json
├── global-style
│ ├── browser.json
│ ├── variables.less
│ └── style.less
└── pages
│ └── home
│ ├── browser.json
│ ├── index.js
│ └── template.marko
├── .browser-refresh-ignore
├── README.md
├── .gitignore
├── .jshintrc
├── package.json
└── server.js
/Procfile:
--------------------------------------------------------------------------------
1 | web: node server.js
--------------------------------------------------------------------------------
/src/marko.json:
--------------------------------------------------------------------------------
1 | {
2 | "tags-dir": "./components"
3 | }
--------------------------------------------------------------------------------
/.browser-refresh-ignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | /static
3 | *.marko.js
4 | .*
--------------------------------------------------------------------------------
/src/layouts/default/browser.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | "./style.less"
4 | ]
5 | }
--------------------------------------------------------------------------------
/src/components/app-overlay/marko-tag.json:
--------------------------------------------------------------------------------
1 | {
2 | "@width": "integer",
3 | "@visible": "boolean"
4 | }
--------------------------------------------------------------------------------
/src/components/app/style.less:
--------------------------------------------------------------------------------
1 | .render-target {
2 | padding-top: 1em;
3 | padding-bottom: 1em;
4 | }
--------------------------------------------------------------------------------
/src/components/app-notification/index.marko:
--------------------------------------------------------------------------------
1 |
2 | $!{data.message}
3 |
--------------------------------------------------------------------------------
/src/components/app-tabs/marko-tag.json:
--------------------------------------------------------------------------------
1 | {
2 | "@tabs []": {
3 | "@label": "string"
4 | }
5 | }
--------------------------------------------------------------------------------
/src/services/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "browser": {
3 | "./users.js": "./users-browser.js"
4 | }
5 | }
--------------------------------------------------------------------------------
/src/components/app-markdown/marko-tag.json:
--------------------------------------------------------------------------------
1 | {
2 | "body": "static-text",
3 | "preserve-whitespace": true
4 | }
--------------------------------------------------------------------------------
/src/components/app-sections/marko-tag.json:
--------------------------------------------------------------------------------
1 | {
2 | "@sections []": {
3 | "@title": "string"
4 | }
5 | }
--------------------------------------------------------------------------------
/src/layouts/default/style.less:
--------------------------------------------------------------------------------
1 | .container {
2 | margin-left: auto;
3 | margin-right: auto;
4 | width: 800px;
5 | }
--------------------------------------------------------------------------------
/src/global-style/browser.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | "less-import: variables.less",
4 | "style.less"
5 | ]
6 | }
--------------------------------------------------------------------------------
/src/components/app-checkbox/marko-tag.json:
--------------------------------------------------------------------------------
1 | {
2 | "@label": "string",
3 | "@data": "expression",
4 | "@checked": "boolean",
5 | "@class": "string"
6 | }
--------------------------------------------------------------------------------
/src/components/app-state-select/CA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marko-js-samples/ui-components-playground-lasso-express/HEAD/src/components/app-state-select/CA.png
--------------------------------------------------------------------------------
/src/components/app-state-select/CO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marko-js-samples/ui-components-playground-lasso-express/HEAD/src/components/app-state-select/CO.png
--------------------------------------------------------------------------------
/src/components/app-progress-bar/marko-tag.json:
--------------------------------------------------------------------------------
1 | {
2 | "@steps []": {
3 | "@name": "string",
4 | "@label": "string",
5 | "@active": "boolean"
6 | }
7 | }
--------------------------------------------------------------------------------
/src/components/app-map/marko-tag.json:
--------------------------------------------------------------------------------
1 | {
2 | "@height": "string",
3 | "@width": "string",
4 | "@static": "boolean",
5 | "@class": "string",
6 | "@lat": "number",
7 | "@lng": "number"
8 | }
9 |
--------------------------------------------------------------------------------
/src/pages/home/browser.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | "~/src/layouts/default/browser.json",
4 | "~/src/global-style/browser.json",
5 | "require: ~/src/components/app"
6 | ]
7 | }
--------------------------------------------------------------------------------
/src/pages/home/index.js:
--------------------------------------------------------------------------------
1 | var template = require('./template.marko');
2 |
3 | module.exports = function(req, res) {
4 | res.setHeader('Content-Type', 'text/html; charset=utf-8');
5 | res.marko(template, {});
6 | };
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Marko UI Components Playground
2 | ==================================
3 |
4 | ```bash
5 | git clone https://github.com/marko-js-samples/ui-components-playground.git
6 | cd ui-components-playground
7 | npm install
8 | node server.js
9 | ```
10 |
--------------------------------------------------------------------------------
/src/pages/home/template.marko:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <@title>
5 | Marko UI Components Playground
6 | @title>
7 | <@body>
8 |
9 | @body>
10 |
--------------------------------------------------------------------------------
/src/services/users-browser.js:
--------------------------------------------------------------------------------
1 | require('whatwg-fetch');
2 |
3 | exports.getUsers = function(options) {
4 | return fetch('/services/users?pageIndex=' + (options.pageIndex || 0))
5 | .then(function(response) {
6 | return response.json();
7 | });
8 | };
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.seed
2 | *.log
3 | *.csv
4 | *.dat
5 | *.out
6 | *.pid
7 | *.gz
8 | *.marko.js
9 | *.sublime-workspace
10 | *.sublime-project
11 | *.original
12 |
13 | /lib-cov
14 | /pids
15 | /logs
16 | /results
17 | /static
18 | /build
19 | /.cache
20 | /node_modules
21 |
22 | npm-debug.log
23 | .DS_Store
--------------------------------------------------------------------------------
/src/components/app-fetch-data/style.less:
--------------------------------------------------------------------------------
1 | .app-fetch-data .loading {
2 | background-image: url('./loading.svg');
3 | width: 64px;
4 | height: 64px;
5 | display: inline-block;
6 | vertical-align: middle;
7 | }
8 |
9 | .app-fetch-data .table-container {
10 | max-height: 400px;
11 | overflow: auto;
12 | }
--------------------------------------------------------------------------------
/src/components/app-map/browser.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | {
4 | "type": "js",
5 | "url": "https://maps.googleapis.com/maps/api/js"
6 | },
7 | {
8 | "type": "css",
9 | "url": "https://fonts.googleapis.com/css?family=Open+Sans:300,400,700"
10 | }
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/app-notifications/index.marko:
--------------------------------------------------------------------------------
1 | style.less {
2 | .app-notifications {
3 | position: fixed;
4 | top: 0px;
5 | width: 500px;
6 | left: 50%;
7 | margin-left: -250px;
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/src/components/app-sections/style.less:
--------------------------------------------------------------------------------
1 | .app-sections {
2 |
3 | }
4 | .tableOfContents {
5 | position: fixed;
6 | right: 15px;
7 | top: 15px;
8 | background-color: #f7f7f9;
9 | box-shadow: 4px 4px 4px rgba(0,0,0,0.2);
10 | padding: 1em;
11 | }
12 |
13 | .app-sections .section {
14 | margin-top: 40px;
15 | }
16 |
17 | .app-sections .section > h2 {
18 | border-bottom: 1px solid #c0c0c0;
19 | margin-bottom: 0.5em;
20 | }
--------------------------------------------------------------------------------
/src/global-style/variables.less:
--------------------------------------------------------------------------------
1 | @medium-color: #2980b9;
2 | @light-color: lighten(@medium-color, 35%);
3 | @dark-color: darken(@medium-color, 25%);
4 |
5 | @link-color: @medium-color;
6 |
7 | @font-color: #333;
8 | @font-family: "HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,sans-serif;
9 |
10 | @button-bg: @medium-color;
11 | @button-fg: #fff;
12 |
13 | @button-secondary-bg: #999999;
14 | @button-secondary-fg: #fff;
15 |
16 |
--------------------------------------------------------------------------------
/src/components/app-button/marko-tag.json:
--------------------------------------------------------------------------------
1 | {
2 | "@label": "string",
3 | "@href": "string",
4 | "@variant": {
5 | "type": "string",
6 | "enum": [
7 | "primary",
8 | "secondary"
9 | ]
10 | },
11 | "@size": {
12 | "type": "string",
13 | "enum": [
14 | "small",
15 | "normal",
16 | "large"
17 | ]
18 | },
19 | "@class": {
20 | "type": "string",
21 | "description": "Additional CSS class names"
22 | },
23 | "@*": "string"
24 | }
--------------------------------------------------------------------------------
/src/components/app-markdown/code-generator.js:
--------------------------------------------------------------------------------
1 | var marked = require('marked');
2 |
3 | function removeIndentation(str) {
4 | var indentMatches = /\s*\n(\s+)/.exec(str);
5 | if (indentMatches) {
6 | var indent = indentMatches[1];
7 | str = str.replace(new RegExp('^' + indent, 'mg'), '');
8 | }
9 | return str;
10 | }
11 |
12 | module.exports = function(el, codegen) {
13 | var bodyText = removeIndentation(el.bodyText);
14 | var builder = codegen.builder;
15 | var html = marked(bodyText);
16 | return builder.html(builder.literal(html));
17 | };
--------------------------------------------------------------------------------
/src/components/app-notification/component.js:
--------------------------------------------------------------------------------
1 | require('./style.less');
2 |
3 | module.exports = {
4 | onInput: function(input) {
5 | this.state = {
6 | timeout: input.timeout,
7 | message: input.message
8 | };
9 | },
10 |
11 | onMount: function() {
12 | var el = this.el;
13 | setTimeout(function() {
14 | el.style.opacity = 1;
15 | el.style.maxHeight = '60px';
16 | }, 10);
17 | },
18 |
19 | fadeOut: function(callback) {
20 | var el = this.el;
21 | el.style.opacity = 0;
22 | setTimeout(callback, 300);
23 | }
24 | };
--------------------------------------------------------------------------------
/src/components/app-checkbox/images/unchecked.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
--------------------------------------------------------------------------------
/src/components/app-checkbox/style.less:
--------------------------------------------------------------------------------
1 | .app-button.app-checkbox {
2 | background-color: @button-secondary-bg;
3 | color: @button-secondary-fg;
4 | }
5 |
6 | .app-button.app-checkbox.checked {
7 | background-color: @button-bg;
8 | color: @button-fg;
9 | }
10 |
11 | .app-checkbox-icon {
12 | background-image: url(./images/unchecked.svg);
13 | background-size: contain;
14 | width: 18px;
15 | height: 18px;
16 | display: inline-block;
17 | background-repeat: no-repeat;
18 | opacity: 0.2;
19 | margin-right: 4px;
20 | }
21 |
22 | .app-checkbox.checked .app-checkbox-icon {
23 | background-image: url(./images/checked.svg);
24 | opacity: 1.0;
25 | }
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node" : true,
3 | "esnext" : true,
4 | "browser" : true,
5 | "boss" : false,
6 | "curly": false,
7 | "debug": false,
8 | "devel": false,
9 | "eqeqeq": true,
10 | "evil": true,
11 | "forin": false,
12 | "immed": true,
13 | "laxbreak": false,
14 | "newcap": true,
15 | "noarg": true,
16 | "noempty": false,
17 | "nonew": true,
18 | "nomen": false,
19 | "onevar": false,
20 | "plusplus": false,
21 | "regexp": false,
22 | "undef": true,
23 | "sub": true,
24 | "white": false,
25 | "eqeqeq": false,
26 | "latedef": true,
27 | "unused": "vars",
28 | "strict": false,
29 | "eqnull": true
30 | }
--------------------------------------------------------------------------------
/src/components/app-notification/style.less:
--------------------------------------------------------------------------------
1 | @notification-bg: #2ecc71;
2 | @notification-border-color: darken(@notification-bg, 20%);
3 |
4 | .app-notification {
5 | opacity: 0;
6 | transition-property: max-height, opacity;
7 | transition-duration: .3s;
8 | transition-timing-function: ease-out;
9 | max-height: 0px;
10 | margin-top: 8px;
11 | background-color: @notification-bg;
12 | color: white;
13 | width: 100%;
14 | border: 2px solid @notification-border-color;
15 | padding-left: 1em;
16 | padding-right: 1em;
17 | line-height: 40px;
18 | vertical-align: middle;
19 | border-radius: 4px;
20 | box-shadow: 3px 3px 3px rgba(51, 65, 80, 0.35);
21 | }
--------------------------------------------------------------------------------
/src/services/routes.js:
--------------------------------------------------------------------------------
1 | var usersService = require('./users');
2 |
3 | module.exports = function(app) {
4 | app.get('/services/users', function(req, res) {
5 | var pageIndex = req.query.pageIndex;
6 | if (typeof pageIndex === 'string') {
7 | pageIndex = parseInt(pageIndex, 10);
8 | } else {
9 | pageIndex = 0;
10 | }
11 |
12 | usersService.getUsers({ pageIndex: pageIndex })
13 | .then(function(data) {
14 | res.json(data);
15 | })
16 | .catch(function(err) {
17 | console.log(err);
18 | res.status(500).send('Unable to load users');
19 | });
20 | });
21 | };
--------------------------------------------------------------------------------
/src/services/users.js:
--------------------------------------------------------------------------------
1 | var mockUsersData = require('./mock-users-data.json');
2 |
3 | const pageSize = 10;
4 |
5 | exports.getUsers = function(options) {
6 | var pageIndex = options.pageIndex || 0;
7 | var start = pageIndex * pageSize;
8 |
9 | var users = [];
10 |
11 | for (var i=start; i {
22 | setTimeout(function() {
23 | resolve(results);
24 | }, 1000);
25 | });
26 | };
--------------------------------------------------------------------------------
/src/components/app-overlay/index.marko:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/app-checkbox/images/checked.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
--------------------------------------------------------------------------------
/src/components/app-sections/index.marko:
--------------------------------------------------------------------------------
1 | import './style.less'
2 |
3 | static function getAnchorName(section) {
4 | if (!section.anchorName) {
5 | section.anchorName = section.title.replace(/[^a-zA-Z]+/g, '-');
6 | }
7 |
8 | return section.anchorName;
9 | }
10 |
11 |
12 |
19 |
20 |
21 |
${section.title}
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/components/app-button/style.less:
--------------------------------------------------------------------------------
1 | .app-button {
2 | display: inline-block;
3 | border-radius: 8px;
4 | padding: 12px;
5 | background-color: @button-bg;
6 | color: @button-fg;
7 |
8 | transition-property: background-color;
9 | transition-duration: .3s;
10 | transition-timing-function: ease-out;
11 | }
12 |
13 | .app-button:hover {
14 | background-color: lighten(@button-bg, 10%);
15 | }
16 |
17 |
18 | /* Variants */
19 | .app-button-secondary {
20 | background-color: @button-secondary-bg;
21 | color: @button-secondary-fg;
22 | }
23 |
24 | .app-button-secondary:hover {
25 | background-color: lighten(@button-secondary-bg, 10%);
26 | }
27 |
28 | /* Sizes */
29 | .app-button-small {
30 | font-size: 0.9em;
31 | padding-top: 6px;
32 | padding-bottom: 6px;
33 | }
34 |
35 | .app-button-large {
36 | font-size: 1.2em;
37 | font-weight: 100;
38 | }
--------------------------------------------------------------------------------
/src/components/app-progress-bar/index.marko:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/layouts/default/index.marko:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/components/app-map/index.marko:
--------------------------------------------------------------------------------
1 | class {
2 | onMount() {
3 | var el = this.el;
4 | var google = window.google;
5 |
6 | var lat = this.input.lat;
7 | var lng = this.input.lng;
8 |
9 | // If there is no internet connection then
10 | // the Google Maps API will fail to load and
11 | // window.google will be undefined
12 | if (google && google.maps && google.maps.Map) {
13 | var Map = google.maps.Map;
14 | var LatLng = google.maps.LatLng;
15 |
16 | this._map = new Map(el, {
17 | zoom: 8,
18 | center: new LatLng(
19 | lat,
20 | lng)
21 | });
22 | } else {
23 | this.innerHTML = 'Failed to load Google Maps API. Is your internet connection working?';
24 | }
25 | }
26 | }
27 |
28 | $ var height=input.height
29 | $ var width=input.width
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/components/app-button/index.marko:
--------------------------------------------------------------------------------
1 | class {
2 | onInput(input) {
3 | return {
4 | size: input.size || 'normal',
5 | variant: input.variant || 'primary',
6 | body: input.label || input.renderBody,
7 | className: input['class']
8 | };
9 | }
10 |
11 | handleClick(event) {
12 | // Every Widget instance is also an EventEmitter instance.
13 | // We will emit a custom "click" event when a DOM click event
14 | // is triggered
15 | this.emit('click', {
16 | event: event // Pass along the DOM event in case it is helpful to others
17 | });
18 | }
19 | }
20 |
21 | $ var variantClassName = (input.variant !== 'primary' && 'app-button-' + input.variant);
22 | $ var sizeClassName = (input.size !== 'normal' && 'app-button-' + input.size);
23 |
24 |
--------------------------------------------------------------------------------
/src/components/app-number-spinner/index.marko:
--------------------------------------------------------------------------------
1 | import './style.css'
2 |
3 | static function getClassNameForValue(value) {
4 | if (value < 0) {
5 | return 'negative';
6 | } else if (value > 0) {
7 | return 'positive';
8 | }
9 | }
10 |
11 | class {
12 | onInput(input) {
13 | var value = input.value || 0;
14 |
15 | this.state = {
16 | value: value
17 | };
18 | }
19 |
20 | handleIncrementClick(delta) {
21 | this.state.value += delta;
22 | }
23 |
24 | handleInputKeyUp(event, el) {
25 | var newValue = el.value;
26 | if (/^-?[0-9]+$/.test(newValue)) {
27 | this.state.value = parseInt(newValue, 10);
28 | }
29 | }
30 | }
31 |
32 | $ var value=state.value;
33 |
34 |
35 |
36 |
39 |
40 |
42 |
43 |
46 |
47 |
--------------------------------------------------------------------------------
/src/components/app-tabs/style.less:
--------------------------------------------------------------------------------
1 | .app-tabs .tab {
2 |
3 | }
4 |
5 | .app-tabs ul.tab-nav {
6 | padding-left: 0;
7 | list-style: none;
8 | }
9 |
10 | .app-tabs ul.tab-nav > li {
11 | float: left;
12 | }
13 |
14 | .app-tabs ul.tab-nav > li > a {
15 | margin-right: 2px;
16 | line-height: 1.42857143;
17 | border: 1px solid @button-secondary-bg;
18 | margin-left: 10px;
19 | border-radius: 4px 4px 0 0;
20 | padding-left: 1em;
21 | padding-right: 1em;
22 | padding-bottom: 0.5em;
23 | padding-top: 0.5em;
24 | display: inline-block;
25 | margin-bottom: -1px;
26 | background-color: @button-secondary-bg;
27 | color: @button-secondary-fg;
28 | }
29 |
30 | .app-tabs ul.tab-nav > li:first-child > a {
31 | margin-left: 0px;
32 | }
33 |
34 | .app-tabs .tab.active > a {
35 | background-color: transparent;
36 | border-bottom: 1px solid white;
37 | color: inherit;
38 | }
39 |
40 | .app-tabs .tab-panes {
41 | clear: both;
42 |
43 | }
44 |
45 | .app-tabs .tab-pane {
46 | display: none;
47 | border: 1px solid @button-secondary-bg;
48 | padding: 1em;
49 | }
50 |
51 | .app-tabs .tab-pane.active {
52 | display: block;
53 | }
--------------------------------------------------------------------------------
/src/components/app-number-spinner/style.css:
--------------------------------------------------------------------------------
1 | .number-spinner button {
2 | background: #4285f4;
3 | color: #ffffff;
4 | border: 1px solid #1266f1;
5 | display: inline-block;
6 | padding: 12px 32px;
7 | height: 26px;
8 | line-height: 26px;
9 | vertical-align: middle;
10 | text-align: center;
11 | font-family: Helvetica, sans-serif;
12 | font-weight: 600;
13 | font-size: 16px;
14 | outline: 0;
15 | transition: none;
16 | margin: 0;
17 | padding: 0;
18 | padding-left: 13px;
19 | padding-right: 13px;
20 | cursor: pointer;
21 | }
22 |
23 | .number-spinner input {
24 | background: #fff;
25 | border: 1px solid #1266f1;
26 | display: inline-block;
27 | height: 26px;
28 | line-height: 26px;
29 | vertical-align: middle;
30 | text-align: center;
31 | font-family: Helvetica, sans-serif;
32 | font-weight: 600;
33 | font-size: 16px;
34 | outline: 0;
35 | transition: none;
36 | margin: 0;
37 | padding: 0;
38 | padding-left: 13px;
39 | padding-right: 13px;
40 | }
41 |
42 | .number-spinner.positive input {
43 | background: rgb(86, 239, 165);
44 | }
45 |
46 | .number-spinner.negative input {
47 | background: rgb(235, 182, 176);
48 | }
--------------------------------------------------------------------------------
/src/components/app-progress-bar/style.less:
--------------------------------------------------------------------------------
1 | .app-progress-bar .progress-step {
2 | display: inline-block;
3 | height: 2em;
4 | }
5 |
6 | .app-progress-bar a.progress-step {
7 | display: inline-block;
8 | background-color: @button-secondary-bg;
9 | color: @button-secondary-fg;
10 | padding-left: 28px;
11 | padding-right: 8px;
12 | height: 2em;
13 | font-size: 1em;
14 | line-height: 2em;
15 | vertical-align: middle;
16 | }
17 |
18 | .app-progress-bar div.progress-step:first-child a.progress-step {
19 | padding-left: 8px;
20 | }
21 |
22 | .app-progress-bar .progress-step.active a.progress-step {
23 | background-color: @button-bg;
24 | color: @button-fg;
25 | }
26 |
27 | div.progress-step-end {
28 | display: inline-block;
29 | width: 20px;
30 | height: 2em;
31 | position: relative;
32 | font-size: 1em;
33 | line-height: 2em;
34 | vertical-align: middle;
35 | margin-right: -20px;
36 | }
37 |
38 | svg.progress-step-end {
39 | display: inline-block;
40 | width: 100%;
41 | height: 100%;
42 | }
43 |
44 |
45 | polygon.progress-step-end {
46 | fill: @button-secondary-bg;
47 | }
48 |
49 | .app-progress-bar .progress-step.active polygon.progress-step-end {
50 | fill: @button-bg;
51 | }
--------------------------------------------------------------------------------
/src/components/app-tabs/index.marko:
--------------------------------------------------------------------------------
1 | class {
2 | onInput(input) {
3 | var activeIndex = 0;
4 |
5 | var tabs = input.tabs;
6 |
7 | if (tabs) {
8 | tabs.forEach(function(tab, i) {
9 | if (tab.active) {
10 | activeIndex = i;
11 | }
12 | });
13 | }
14 |
15 | this.state = {
16 | activeIndex: activeIndex
17 | };
18 | }
19 |
20 | setActiveIndex(newActiveIndex) {
21 | this.state.activeIndex = newActiveIndex;
22 | }
23 |
24 | handleTabClick(tabIndex, event) {
25 | this.setActiveIndex(tabIndex);
26 | event.preventDefault();
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ui-components-playground",
3 | "version": "1.0.0",
4 | "description": "Sample app that demonstrates the power of building UI components using Marko and Marko Widgets",
5 | "main": "server.js",
6 | "scripts": {
7 | "start": "node server.js",
8 | "browser-refresh": "browser-refresh server.js"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/marko-js-samples/ui-components-playground.git"
13 | },
14 | "author": "Patrick Steele-idem ",
15 | "license": "ISC",
16 | "bugs": {
17 | "url": "https://github.com/marko-js-samples/ui-components-playground/issues"
18 | },
19 | "homepage": "https://github.com/marko-js-samples/ui-components-playground",
20 | "dependencies": {
21 | "browser-refresh": "^1.7.1",
22 | "browser-refresh-taglib": "^1.1.0",
23 | "compression": "^1.6.2",
24 | "express": "^4.14.0",
25 | "jquery": "^2.2.4",
26 | "lasso": "^2.10.0",
27 | "lasso-less": "^2.4.0",
28 | "lasso-marko": "^2.2.1",
29 | "marked": "^0.3.6",
30 | "marko": "^4.0.0-rc.24",
31 | "minprops": "^1.0.0",
32 | "purecss": "^0.6.2",
33 | "raptor-pubsub": "^1.0.5",
34 | "raptor-util": "^1.1.1",
35 | "require-self-ref": "^2.0.1",
36 | "serve-static": "^1.11.1",
37 | "whatwg-fetch": "^2.0.1"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/app-checkbox/index.marko:
--------------------------------------------------------------------------------
1 | class {
2 |
3 | onInput(input) {
4 | this.state = {
5 | checked: input.checked === true,
6 | };
7 | }
8 |
9 | isChecked() {
10 | return this.state.checked === true;
11 | }
12 |
13 | setChecked(newChecked) {
14 | this.state.checked = newChecked
15 | }
16 |
17 | toggle() {
18 | this.state.checked = !this.state.checked;
19 | }
20 |
21 | getData() {
22 | return this.input.data;
23 | }
24 |
25 | handleClick() {
26 | var newChecked = !this.state.checked;
27 |
28 | var defaultPrevented = false;
29 |
30 | this.emit('toggle', {
31 | checked: newChecked,
32 | data: this.getData(),
33 | preventDefault: function() {
34 | defaultPrevented = true;
35 | }
36 | });
37 |
38 | if (!defaultPrevented) {
39 | this.state.checked = newChecked;
40 | }
41 | }
42 | }
43 |
44 |
45 | $ var classNames=[
46 | 'app-checkbox',
47 | input['class'],
48 | state.checked && 'checked'
49 | ];
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/components/app-progress-bar/component.js:
--------------------------------------------------------------------------------
1 | require('./style.less');
2 |
3 | module.exports = {
4 | onInput: function(input) {
5 | var steps = input.steps || [];
6 | var activeIndex = 0;
7 |
8 |
9 | steps.forEach(function(step) {
10 | if (step.active) {
11 | activeIndex = steps.length;
12 | }
13 | });
14 |
15 | this.state = {
16 | steps: steps,
17 | activeIndex: activeIndex
18 | };
19 | },
20 |
21 | setCurrentStepIndex: function(index) {
22 | if (this.state.activeIndex === index) {
23 | return;
24 | }
25 |
26 | var defaultPrevented = false;
27 |
28 | this.emit('beforeChange', {
29 | step: this.state.steps[this.state.activeIndex],
30 | preventDefault: function() {
31 | defaultPrevented = true;
32 | }
33 | });
34 |
35 | if (defaultPrevented) {
36 | return;
37 | }
38 |
39 | var newStep = this.state.steps[index];
40 |
41 | this.state.activeIndex = index;
42 |
43 | this.emit('change', {
44 | name: newStep.name,
45 | index: index
46 | });
47 | },
48 |
49 | handleStepClick: function(stepIndex, event) {
50 | event.preventDefault();
51 | this.setCurrentStepIndex(stepIndex);
52 | }
53 | };
--------------------------------------------------------------------------------
/src/components/app-state-select/index.marko:
--------------------------------------------------------------------------------
1 | static {
2 | var states = [
3 | {
4 | name: 'Colorado',
5 | value: 'CO'
6 | },
7 | {
8 | name: 'California',
9 | value: 'CA'
10 | }
11 | ];
12 | }
13 |
14 | class {
15 | onInput() {
16 | this.state = {
17 | stateIndex: null
18 | }
19 | }
20 |
21 | handleSelectChange(event, selectEl) {
22 | if (selectEl.selectedIndex === 0) {
23 | this.state.stateIndex = null;
24 | } else {
25 | this.state.stateIndex = selectEl.selectedIndex - 1;
26 | }
27 | }
28 | }
29 |
30 | style.css {
31 | .state-icon {
32 | width: 75px;
33 | height: 50px;
34 | }
35 |
36 | .state-icon.CA {
37 | background-image: url('./CA.png')
38 | }
39 |
40 | .state-icon.CO {
41 | background-image: url('./CO.png')
42 | }
43 | }
44 |
45 |
46 |
Choose a state
47 |
55 |
56 |
57 | You selected:
58 |
59 |
60 |
--------------------------------------------------------------------------------
/src/components/app-notifications/component.js:
--------------------------------------------------------------------------------
1 | var raptorPubsub = require('raptor-pubsub');
2 |
3 | var nextId = 0;
4 |
5 | module.exports = {
6 | onInput: function() {
7 | this.state = {
8 | notifications: []
9 | };
10 | },
11 |
12 | onMount: function() {
13 | var self = this;
14 |
15 | this.subscribeTo(raptorPubsub)
16 | .on('notification', function(eventArgs) {
17 | var message = eventArgs.message;
18 | self.addNotification(message);
19 | });
20 | },
21 |
22 | addNotification: function(message) {
23 | var notifications = this.state.notifications;
24 | var notificationId = 'notification' + (nextId++);
25 | notifications = [
26 | {
27 | message: message,
28 | id: notificationId
29 | }
30 | ].concat(notifications);
31 |
32 | this.setState('notifications', notifications);
33 |
34 | setTimeout(function() {
35 | this.removeNotification(notificationId);
36 | }.bind(this), 3000);
37 | },
38 |
39 | removeNotification: function(notificationId) {
40 | var notificationWidget = this.getComponent(notificationId);
41 | notificationWidget.fadeOut(function() {
42 | var notifications = this.state.notifications.filter(function(notification) {
43 | return notification.id !== notificationId;
44 | });
45 | this.setState('notifications', notifications);
46 | }.bind(this));
47 | }
48 | };
--------------------------------------------------------------------------------
/src/components/app-overlay/style.less:
--------------------------------------------------------------------------------
1 | .app-overlay > .app-overlay-mask {
2 | position: fixed;
3 | top: 0px;
4 | left: 0px;
5 | right: 0px;
6 | bottom: 0px;
7 | visibility: hidden;
8 | background-color: #000;
9 | opacity: 0;
10 | transition-property: opacity, visibility;
11 | transition-duration: .3s;
12 | transition-timing-function: ease-out;
13 | }
14 |
15 | .app-overlay.visible > .app-overlay-mask {
16 | visibility: visible;
17 | opacity: 0.8;
18 | z-index: 999;
19 | }
20 |
21 | .app-overlay > .app-overlay-container {
22 | position: fixed;
23 | top: -50%;
24 | transform: translateX(-50%) translateY(-50%);
25 | left: 50%;
26 | background-color: white;
27 | opacity: 0;
28 | transition-property: opacity, top;
29 | transition-duration: .2s;
30 | transition-timing-function: ease-out;
31 | border-radius: 5px;
32 | overflow: auto;
33 | z-index: 1000;
34 | }
35 |
36 | .app-overlay.visible > .app-overlay-container {
37 | top: 50%;
38 | opacity: 1;
39 | }
40 |
41 | .app-overlay-body {
42 | padding: 1em;
43 | }
44 |
45 | .app-overlay-footer {
46 | width: 100%;
47 | bottom: 0px;
48 | left: 0px;
49 | text-align: right;
50 | padding: 1em;
51 | padding-top: 2em;
52 | }
53 |
54 |
55 | .app-overlay > .app-overlay-container .app-overlay > .app-overlay-container {
56 | height: 100%;
57 | }
58 |
59 | .app-overlay > .app-overlay-container .app-overlay > .app-overlay-container .app-overlay-footer {
60 | position: absolute;
61 | height: 48px;
62 | left: 0px;
63 | bottom: 0px;
64 | width: 100%;
65 | padding-top: 0px;
66 | }
--------------------------------------------------------------------------------
/src/components/app-overlay/component.js:
--------------------------------------------------------------------------------
1 | require('./style.less');
2 |
3 | module.exports = {
4 | onInput: function(input) {
5 | this.state = {
6 | width: input.width || '80%',
7 | visible: input.visible === true ? true : false,
8 | body: input.renderBody
9 | };
10 | },
11 |
12 | onMount: function() {
13 | this.fixPageScrolling();
14 | },
15 |
16 | onUpdate: function() {
17 | this.fixPageScrolling();
18 | },
19 |
20 | fixPageScrolling: function() {
21 | if (this.state.visible === true) {
22 | document.body.style.overflow = 'hidden';
23 | } else {
24 | document.body.style.overflow = '';
25 | }
26 | },
27 |
28 | hide: function() {
29 | this.setVisibility(false);
30 | },
31 | show: function() {
32 | this.setVisibility(true);
33 | },
34 |
35 | setVisibility: function(visible) {
36 | if (this.state.visible === visible) {
37 | // Visibility did not change... nothing to do
38 | return;
39 | }
40 |
41 | if (visible) {
42 | this.emit('show');
43 | } else {
44 | this.emit('hide');
45 | }
46 |
47 | this.setState('visible', visible);
48 | },
49 |
50 | handleMaskClick: function() {
51 | this.hide();
52 | },
53 | handleCancelButtonClick: function() {
54 | this.emit('cancel', {});
55 | this.hide();
56 | },
57 | handleDoneButtonClick: function() {
58 | var preventDefault = false;
59 |
60 | this.emit('ok', {
61 | preventDefault: function() {
62 | preventDefault = true;
63 | }
64 | });
65 |
66 | if (!preventDefault) {
67 | this.hide();
68 | }
69 | }
70 | };
--------------------------------------------------------------------------------
/src/global-style/style.less:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: @font-family;
3 | color: @font-color;
4 | padding: 0;
5 | margin: 0;
6 | }
7 |
8 | * {
9 | -moz-box-sizing: border-box;
10 | -webkit-box-sizing: border-box;
11 | box-sizing: border-box;
12 | }
13 |
14 | button::-moz-focus-inner,
15 | input::-moz-focus-inner {
16 | border: 0;
17 | padding: 0;
18 | }
19 |
20 | ul,
21 | ol {
22 | margin-top: 0;
23 | margin-bottom: 0;
24 | padding-top: 0;
25 | padding-bottom: 0;
26 | }
27 |
28 | form,
29 | img {
30 | margin: 0;
31 | padding: 0;
32 | }
33 |
34 | img {
35 | border-width: 0;
36 | }
37 |
38 | textarea,
39 | input {
40 | font-size: 14px;
41 | font-family: @font-family;
42 | }
43 |
44 | select {
45 | margin: 0;
46 | }
47 |
48 | table {
49 | border-collapse: separate;
50 | border-spacing: 0;
51 | }
52 |
53 | td {
54 | padding: 0;
55 | margin: 0;
56 | border-width: 0;
57 | }
58 |
59 | pre {
60 | margin: 0;
61 | padding: 0;
62 | }
63 |
64 | h1, h2, h3 {
65 | margin-top: 0;
66 | padding-top: 0.5em;
67 | margin-bottom: 0.2em;
68 | }
69 |
70 | h1 {
71 | font-size: 1.5em;
72 | color: @dark-color;
73 |
74 | a {
75 | color: @dark-color;
76 | }
77 | }
78 |
79 | h2 {
80 | font-size: 1.25em;
81 | }
82 |
83 | h3 {
84 | font-size: 1.0em;
85 | }
86 |
87 | label {
88 | display: block;
89 | font-size: 0.9em;
90 | }
91 |
92 | button, input, select, textarea {
93 | font-size: 100%;
94 | margin: 0;
95 | }
96 |
97 | button {
98 | padding: 0;
99 | cursor: pointer;
100 | line-height: normal;
101 | border: 0;
102 | }
103 |
104 | a {
105 | color: @link-color;
106 | text-decoration: none;
107 | }
108 |
109 | input[type=text] {
110 | border: 1px solid #c0c0c0;
111 | }
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | require('require-self-ref');
2 |
3 | require('marko/express');
4 | require('marko/node-require');
5 | require('lasso/node-require-no-op').enable('.less', '.css');
6 |
7 | var express = require('express');
8 | var compression = require('compression'); // Provides gzip compression for the HTTP response
9 | var serveStatic = require('serve-static');
10 |
11 | var isProduction = process.env.NODE_ENV === 'production';
12 |
13 | // Configure the RaptorJS Optimizer to control how JS/CSS/etc. is
14 | // delivered to the browser
15 | require('lasso').configure({
16 | plugins: [
17 | 'lasso-less', // Allow Less files to be rendered to CSS
18 | 'lasso-marko' // Allow Marko templates to be compiled and transported to the browser
19 | ],
20 | outputDir: __dirname + '/static', // Place all generated JS/CSS/etc. files into the "static" dir
21 | bundlingEnabled: isProduction, // Only enable bundling in production
22 | minify: isProduction, // Only minify JS and CSS code in production
23 | fingerprintsEnabled: isProduction, // Only add fingerprints to URLs in production
24 | });
25 |
26 | var app = express();
27 |
28 | var port = process.env.PORT || 8080;
29 |
30 | // Enable gzip compression for all HTTP responses
31 | app.use(compression());
32 |
33 | // Allow all of the generated files under "static" to be served up by Express
34 | app.use('/static', serveStatic(__dirname + '/static'));
35 |
36 | require('./src/services/routes')(app);
37 |
38 | // Map the "/" route to the home page
39 | app.get('/', require('./src/pages/home'));
40 |
41 | app.listen(port, function(err) {
42 | if (err) {
43 | throw err;
44 | }
45 | console.log('Listening on port %d', port);
46 |
47 | // The browser-refresh module uses this event to know that the
48 | // process is ready to serve traffic after the restart
49 | if (process.send) {
50 | process.send('online');
51 | }
52 | });
--------------------------------------------------------------------------------
/src/components/app-fetch-data/index.marko:
--------------------------------------------------------------------------------
1 | import { getUsers } from '~/src/services/users';
2 | import 'purecss/build/tables.css';
3 |
4 | class {
5 | onInput(input) {
6 | var users = [];
7 | var pageIndex = -1;
8 |
9 | var usersData = input.usersData;
10 | if (usersData) {
11 | users = usersData.users;
12 | pageIndex = usersData.pageIndex;
13 | }
14 |
15 | this.state = {
16 | loading: false,
17 | users: users,
18 | pageIndex: pageIndex
19 | };
20 | }
21 |
22 | onMount() {
23 | this.fetchPromise = Promise.resolve();
24 |
25 | if (this.state.users.length === 0) {
26 | this.loadMore();
27 | }
28 | }
29 |
30 | loadMore() {
31 | this.state.loading = true;
32 |
33 | var state = this.state;
34 |
35 | this.fetchPromise = this.fetchPromise
36 | .then(function() {
37 | return getUsers({
38 | pageIndex: ++state.pageIndex
39 | });
40 | })
41 | .then(function(usersData) {
42 | state.users = state.users.concat(usersData.users);
43 | state.loading = false;
44 | })
45 | .catch(function(e) {
46 | state.loading = false;
47 | console.log('Fetch failed:', e);
48 | });
49 | }
50 |
51 | handleLoadMoreClick() {
52 | this.loadMore();
53 | }
54 |
55 | onUpdate() {
56 | if (this.state.pageIndex > 0) {
57 | var tableContainer = this.getEl('tableContainer');
58 | tableContainer.scrollTop = tableContainer.scrollHeight;
59 | }
60 | }
61 | }
62 |
63 |
64 |
65 |
66 |
67 |
68 | | ID |
69 | Avatar |
70 | Name |
71 | Email |
72 |
73 |
74 |
75 |
76 | | ${user.id} |
77 |  |
78 | ${user.firstName} ${user.lastName} |
79 | ${user.email} |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/src/components/app-fetch-data/loading.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/app/component.js:
--------------------------------------------------------------------------------
1 | require('./style.less');
2 |
3 | var raptorPubsub = require('raptor-pubsub');
4 | var button = require('~/src/components/app-button');
5 | var checkbox = require('~/src/components/app-checkbox');
6 | var progressBar = require('~/src/components/app-progress-bar');
7 | var extend = require('raptor-util/extend');
8 |
9 | var buttonSizes = ['small', 'normal', 'large'];
10 | var buttonVariants = ['primary', 'secondary'];
11 |
12 | var currentButtonSize = 0;
13 | var currentButtonVariant = 0;
14 |
15 | module.exports = {
16 | onInput: function(input) {
17 | var now = (new Date()).toString();
18 |
19 | this.state = {
20 | buttonSize: input.buttonSize || 'small',
21 | buttonVariant: input.buttonVariant || 'primary',
22 | overlayVisible: false,
23 | checked: input.checked || {
24 | foo: false,
25 | bar: true,
26 | baz: false
27 | },
28 | dynamicTabs: [
29 | {
30 | timestamp: now
31 | },
32 | {
33 | timestamp: now
34 | }
35 | ]
36 | };
37 | },
38 |
39 | handleCheckboxToggle: function(event, sourceWidget) {
40 | // event.preventDefault();
41 |
42 | var name = event.data.name;
43 |
44 | // We treat complex objects stored in the state as immutable
45 | // since only a shallow compare is done to see if the state
46 | // has changed. Instead of modifying the "checked" object,
47 | // we create a new object with the updated state of what is
48 | // checked.
49 | var newChecked = extend({}, this.state.checked);
50 | newChecked[name] = event.checked;
51 | this.setState('checked', newChecked);
52 | },
53 |
54 | /**
55 | * This demonstrates how to provide a custom state transition handler to avoid
56 | * a full rerender.
57 | */
58 | update_overlayVisible: function(overlayVisible) {
59 | this.getComponent('overlay').setVisibility(overlayVisible);
60 | },
61 |
62 | handleShowOverlayButtonClick: function() {
63 | // this.setState('overlayVisible', true);
64 | this.getComponent('overlay').show();
65 | },
66 |
67 | handleOverlayHide: function() {
68 | // Synchronize the updated state of the o
69 | this.setState('overlayVisible', false);
70 | },
71 |
72 | handleOverlayShow: function() {
73 | this.setState('overlayVisible', true);
74 | },
75 |
76 | handleShowNotificationButtonClick: function() {
77 | raptorPubsub.emit('notification', {
78 | message: 'This is a notification'
79 | });
80 | },
81 |
82 | handleOverlayOk: function() {
83 | raptorPubsub.emit('notification', {
84 | message: 'You clicked the "Done" button!'
85 | });
86 | },
87 |
88 | handleOverlayCancel: function() {
89 | raptorPubsub.emit('notification', {
90 | message: 'You clicked the "Cancel" button!'
91 | });
92 | },
93 |
94 | handleRenderButtonClick: function() {
95 | button.renderSync({
96 | label: 'Hello World'
97 | })
98 | .appendTo(this.getEl('renderTarget'));
99 | },
100 |
101 | handleRenderCheckboxButtonClick: function() {
102 | checkbox.renderSync({
103 | label: 'Hello World',
104 | checked: true
105 | })
106 | .appendTo(this.getEl('renderTarget'));
107 | },
108 |
109 | handleRenderProgressBarButtonClick: function() {
110 | progressBar.renderSync({
111 | steps: [
112 | {
113 | label: 'Step 1'
114 | },
115 | {
116 | label: 'Step 2'
117 | },
118 | {
119 | label: 'Step 3',
120 | active: true
121 | },
122 | {
123 | label: 'Step 4'
124 | }
125 | ]
126 | })
127 | .appendTo(this.getEl('renderTarget'));
128 | },
129 |
130 | handleChangeButtonSizeClick: function() {
131 | var nextButtonSize = buttonSizes[++currentButtonSize % buttonSizes.length];
132 | this.state.buttonSize = nextButtonSize;
133 | },
134 |
135 | handleChangeButtonVariantClick: function() {
136 | var nextButtonVariant = buttonVariants[++currentButtonVariant % buttonVariants.length];
137 | this.state.buttonVariant = nextButtonVariant;
138 | },
139 |
140 | handleToggleCheckboxButtonClick: function(event) {
141 | var checkbox = this.getComponent('toggleCheckbox');
142 | checkbox.toggle();
143 | },
144 |
145 | handleAddTabButtonClick: function() {
146 | this.state.dynamicTabs = this.state.dynamicTabs.concat({
147 | timestamp: '' + new Date()
148 | });
149 | }
150 | };
--------------------------------------------------------------------------------
/src/components/app/index.marko:
--------------------------------------------------------------------------------
1 |
2 |
3 | <@section title="Buttons">
4 |
5 |
6 | | Primary: |
7 |
8 |
9 |
10 |
11 | |
12 |
13 |
14 | | Secondary: |
15 |
16 |
17 |
18 |
19 | |
20 |
21 |
22 |
23 |
32 | @section>
33 |
34 |
35 | <@section title="Checkboxes">
36 |
37 |
42 |
46 |
51 |
52 |
53 |
57 |
58 |
59 | Checked:
60 |
61 |
62 | -
63 | ${key}
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
73 |
74 | @section>
75 |
76 | <@section title="Overlays">
77 |
80 |
81 |
84 |
85 |
86 |
87 |
94 | Overlay Demo
95 | This is an overlay!
96 |
97 | @section>
98 |
99 | <@section title="Tabs">
100 |
101 | Static tabs
102 |
103 |
104 | <@tab label="Home">
105 | Content for Home
106 | @tab>
107 | <@tab label="Profile">
108 | Content for Profile
109 | @tab>
110 | <@tab label="Messages">
111 | Content for Messages
112 | @tab>
113 |
114 |
115 | Dynamic tabs
116 |
117 |
118 |
119 | <@tab label=('Tab ' + tabIndex)>
120 | Content for tab ${tabIndex}: ${tab.timestamp}
121 | @tab>
122 |
123 |
124 |
125 |
126 |
127 | @section>
128 |
129 | <@section title="Miscellaneous">
130 |
131 | <@step name="contact-info">
132 | Contact Info
133 | @step>
134 | <@step name="interests">
135 | Interests
136 | @step>
137 | <@step name="family">
138 | Family
139 | @step>
140 |
141 |
142 |
143 |
144 |
145 | @section>
146 |
147 | <@section title="Client-side Rendering">
148 |
149 |
151 |
152 |
154 |
155 |
157 |
158 |
159 | @section>
160 |
161 | <@section title="Fetch data">
162 |
163 |
164 | @section>
165 |
166 | <@section title="Maps">
167 |
168 |
174 | @section>
175 | <@section title="Markdown">
176 |
177 | ---
178 |
179 | > This section demonstrates Markdown in Marko
180 |
181 | ## Marko Features
182 |
183 | - High performance
184 | - Small
185 | - Intuitive
186 |
187 | # H1
188 | ## H2
189 | ### H3
190 | #### H4
191 | ##### H5
192 | ###### H6
193 |
194 | [markojs.com](http://markojs.com/)
195 |
196 | _emphasis_
197 | __strong__
198 |
199 | ---
200 |
201 | @section>
202 |
203 |
--------------------------------------------------------------------------------
/src/services/mock-users-data.json:
--------------------------------------------------------------------------------
1 | [{"id":1,"firstName":"Evelyn","lastName":"Patterson","email":"epatterson0@ehow.com","avatar":"https://robohash.org/quinihilomnis.bmp?size=50x50&set=set1"},
2 | {"id":2,"firstName":"Matthew","lastName":"Moore","email":"mmoore1@squidoo.com","avatar":"https://robohash.org/eaquemolestiasdistinctio.png?size=50x50&set=set1"},
3 | {"id":3,"firstName":"Ryan","lastName":"Mendoza","email":"rmendoza2@bloglines.com","avatar":"https://robohash.org/corruptiipsumlabore.png?size=50x50&set=set1"},
4 | {"id":4,"firstName":"Matthew","lastName":"Rice","email":"mrice3@cafepress.com","avatar":"https://robohash.org/voluptatererumpariatur.bmp?size=50x50&set=set1"},
5 | {"id":5,"firstName":"Ryan","lastName":"Bradley","email":"rbradley4@yahoo.com","avatar":"https://robohash.org/inconsequaturtempora.bmp?size=50x50&set=set1"},
6 | {"id":6,"firstName":"James","lastName":"Simmons","email":"jsimmons5@nbcnews.com","avatar":"https://robohash.org/iustoadest.jpg?size=50x50&set=set1"},
7 | {"id":7,"firstName":"Heather","lastName":"Wagner","email":"hwagner6@state.tx.us","avatar":"https://robohash.org/sitlaborumdolorem.png?size=50x50&set=set1"},
8 | {"id":8,"firstName":"Norma","lastName":"Payne","email":"npayne7@kickstarter.com","avatar":"https://robohash.org/undeetducimus.bmp?size=50x50&set=set1"},
9 | {"id":9,"firstName":"Jeremy","lastName":"Wilson","email":"jwilson8@amazonaws.com","avatar":"https://robohash.org/quisutlaboriosam.png?size=50x50&set=set1"},
10 | {"id":10,"firstName":"Sean","lastName":"Palmer","email":"spalmer9@eepurl.com","avatar":"https://robohash.org/quibusdamnullacorporis.jpg?size=50x50&set=set1"},
11 | {"id":11,"firstName":"Tina","lastName":"Wilson","email":"twilsona@businesswire.com","avatar":"https://robohash.org/ipsumdebitisfugiat.png?size=50x50&set=set1"},
12 | {"id":12,"firstName":"Andrew","lastName":"Carter","email":"acarterb@admin.ch","avatar":"https://robohash.org/consequaturidipsa.jpg?size=50x50&set=set1"},
13 | {"id":13,"firstName":"Mildred","lastName":"Palmer","email":"mpalmerc@e-recht24.de","avatar":"https://robohash.org/nequereiciendisomnis.png?size=50x50&set=set1"},
14 | {"id":14,"firstName":"Theresa","lastName":"Bowman","email":"tbowmand@cocolog-nifty.com","avatar":"https://robohash.org/quosexpeditaest.bmp?size=50x50&set=set1"},
15 | {"id":15,"firstName":"Denise","lastName":"Dixon","email":"ddixone@bigcartel.com","avatar":"https://robohash.org/utrepudiandaesequi.png?size=50x50&set=set1"},
16 | {"id":16,"firstName":"Nancy","lastName":"Gardner","email":"ngardnerf@godaddy.com","avatar":"https://robohash.org/molestiaeoditvoluptatibus.png?size=50x50&set=set1"},
17 | {"id":17,"firstName":"Susan","lastName":"Taylor","email":"staylorg@php.net","avatar":"https://robohash.org/reiciendisetrepellendus.bmp?size=50x50&set=set1"},
18 | {"id":18,"firstName":"Christopher","lastName":"Olson","email":"colsonh@shop-pro.jp","avatar":"https://robohash.org/estautfugit.bmp?size=50x50&set=set1"},
19 | {"id":19,"firstName":"Kathleen","lastName":"Hall","email":"khalli@psu.edu","avatar":"https://robohash.org/illoutcorrupti.jpg?size=50x50&set=set1"},
20 | {"id":20,"firstName":"Catherine","lastName":"Dixon","email":"cdixonj@4shared.com","avatar":"https://robohash.org/estatquepraesentium.png?size=50x50&set=set1"},
21 | {"id":21,"firstName":"Jason","lastName":"Jones","email":"jjonesk@scribd.com","avatar":"https://robohash.org/sapienteinventoreesse.jpg?size=50x50&set=set1"},
22 | {"id":22,"firstName":"Michelle","lastName":"Barnes","email":"mbarnesl@ycombinator.com","avatar":"https://robohash.org/excepturietnobis.jpg?size=50x50&set=set1"},
23 | {"id":23,"firstName":"Roy","lastName":"Hunt","email":"rhuntm@mit.edu","avatar":"https://robohash.org/voluptaspossimustenetur.bmp?size=50x50&set=set1"},
24 | {"id":24,"firstName":"Samuel","lastName":"Olson","email":"solsonn@blog.com","avatar":"https://robohash.org/utlaboreprovident.png?size=50x50&set=set1"},
25 | {"id":25,"firstName":"Pamela","lastName":"Garcia","email":"pgarciao@nydailynews.com","avatar":"https://robohash.org/cumplaceatamet.bmp?size=50x50&set=set1"},
26 | {"id":26,"firstName":"Janet","lastName":"Lawrence","email":"jlawrencep@google.pl","avatar":"https://robohash.org/autnatusmolestiae.bmp?size=50x50&set=set1"},
27 | {"id":27,"firstName":"Charles","lastName":"Myers","email":"cmyersq@ask.com","avatar":"https://robohash.org/quasiplaceatomnis.jpg?size=50x50&set=set1"},
28 | {"id":28,"firstName":"Kathleen","lastName":"Moore","email":"kmoorer@deviantart.com","avatar":"https://robohash.org/impeditrerumvel.bmp?size=50x50&set=set1"},
29 | {"id":29,"firstName":"Jerry","lastName":"Price","email":"jprices@google.com","avatar":"https://robohash.org/nostrumetdolores.png?size=50x50&set=set1"},
30 | {"id":30,"firstName":"Tammy","lastName":"Kelly","email":"tkellyt@unicef.org","avatar":"https://robohash.org/quibusdamsedquos.png?size=50x50&set=set1"},
31 | {"id":31,"firstName":"Katherine","lastName":"Ford","email":"kfordu@tmall.com","avatar":"https://robohash.org/explicaboautdolorem.png?size=50x50&set=set1"},
32 | {"id":32,"firstName":"Eric","lastName":"Kelley","email":"ekelleyv@amazon.co.uk","avatar":"https://robohash.org/inciduntquiaaut.bmp?size=50x50&set=set1"},
33 | {"id":33,"firstName":"Paula","lastName":"Fernandez","email":"pfernandezw@clickbank.net","avatar":"https://robohash.org/accusamusestdoloribus.jpg?size=50x50&set=set1"},
34 | {"id":34,"firstName":"Christopher","lastName":"Robertson","email":"crobertsonx@reference.com","avatar":"https://robohash.org/quamquisconsequatur.bmp?size=50x50&set=set1"},
35 | {"id":35,"firstName":"Janet","lastName":"Alexander","email":"jalexandery@bing.com","avatar":"https://robohash.org/etmolestiaeoccaecati.bmp?size=50x50&set=set1"},
36 | {"id":36,"firstName":"Melissa","lastName":"Harrison","email":"mharrisonz@nih.gov","avatar":"https://robohash.org/ipsumsitveritatis.png?size=50x50&set=set1"},
37 | {"id":37,"firstName":"Lori","lastName":"Sanders","email":"lsanders10@friendfeed.com","avatar":"https://robohash.org/deseruntcupiditateet.png?size=50x50&set=set1"},
38 | {"id":38,"firstName":"Janice","lastName":"Bradley","email":"jbradley11@jimdo.com","avatar":"https://robohash.org/voluptatumutiste.bmp?size=50x50&set=set1"},
39 | {"id":39,"firstName":"Sharon","lastName":"Hernandez","email":"shernandez12@stanford.edu","avatar":"https://robohash.org/quiacumenim.png?size=50x50&set=set1"},
40 | {"id":40,"firstName":"Frank","lastName":"Dunn","email":"fdunn13@hp.com","avatar":"https://robohash.org/quosedsit.png?size=50x50&set=set1"},
41 | {"id":41,"firstName":"Dorothy","lastName":"Reid","email":"dreid14@ucoz.com","avatar":"https://robohash.org/minusquosnon.bmp?size=50x50&set=set1"},
42 | {"id":42,"firstName":"Norma","lastName":"Rodriguez","email":"nrodriguez15@vkontakte.ru","avatar":"https://robohash.org/autmaximeeum.jpg?size=50x50&set=set1"},
43 | {"id":43,"firstName":"Anna","lastName":"Ryan","email":"aryan16@quantcast.com","avatar":"https://robohash.org/dolorautquisquam.jpg?size=50x50&set=set1"},
44 | {"id":44,"firstName":"Eric","lastName":"Foster","email":"efoster17@spotify.com","avatar":"https://robohash.org/doloresveroad.bmp?size=50x50&set=set1"},
45 | {"id":45,"firstName":"Rebecca","lastName":"Ray","email":"rray18@tiny.cc","avatar":"https://robohash.org/nihilipsamin.png?size=50x50&set=set1"},
46 | {"id":46,"firstName":"Marilyn","lastName":"Burke","email":"mburke19@accuweather.com","avatar":"https://robohash.org/aututdelectus.bmp?size=50x50&set=set1"},
47 | {"id":47,"firstName":"Randy","lastName":"Daniels","email":"rdaniels1a@ox.ac.uk","avatar":"https://robohash.org/voluptaseumipsa.png?size=50x50&set=set1"},
48 | {"id":48,"firstName":"Jeremy","lastName":"Arnold","email":"jarnold1b@uiuc.edu","avatar":"https://robohash.org/rerumeaquelabore.png?size=50x50&set=set1"},
49 | {"id":49,"firstName":"Lisa","lastName":"Riley","email":"lriley1c@cpanel.net","avatar":"https://robohash.org/eiusautaliquid.jpg?size=50x50&set=set1"},
50 | {"id":50,"firstName":"Kevin","lastName":"Franklin","email":"kfranklin1d@google.ru","avatar":"https://robohash.org/omnissuscipitquis.png?size=50x50&set=set1"},
51 | {"id":51,"firstName":"Craig","lastName":"Mason","email":"cmason1e@geocities.com","avatar":"https://robohash.org/doloremdignissimoscum.jpg?size=50x50&set=set1"},
52 | {"id":52,"firstName":"Juan","lastName":"Hart","email":"jhart1f@apache.org","avatar":"https://robohash.org/omniscorporisimpedit.bmp?size=50x50&set=set1"},
53 | {"id":53,"firstName":"Helen","lastName":"Allen","email":"hallen1g@cnn.com","avatar":"https://robohash.org/corruptidistinctioquaerat.bmp?size=50x50&set=set1"},
54 | {"id":54,"firstName":"Chris","lastName":"Boyd","email":"cboyd1h@vistaprint.com","avatar":"https://robohash.org/totamquaeratassumenda.png?size=50x50&set=set1"},
55 | {"id":55,"firstName":"Barbara","lastName":"Bradley","email":"bbradley1i@google.co.uk","avatar":"https://robohash.org/explicaboquiadignissimos.png?size=50x50&set=set1"},
56 | {"id":56,"firstName":"Linda","lastName":"Boyd","email":"lboyd1j@miitbeian.gov.cn","avatar":"https://robohash.org/sednumquameos.bmp?size=50x50&set=set1"},
57 | {"id":57,"firstName":"Laura","lastName":"Green","email":"lgreen1k@si.edu","avatar":"https://robohash.org/voluptasquoharum.jpg?size=50x50&set=set1"},
58 | {"id":58,"firstName":"Doris","lastName":"Thomas","email":"dthomas1l@github.com","avatar":"https://robohash.org/quisitvoluptas.bmp?size=50x50&set=set1"},
59 | {"id":59,"firstName":"Willie","lastName":"Romero","email":"wromero1m@ycombinator.com","avatar":"https://robohash.org/distinctioexsed.png?size=50x50&set=set1"},
60 | {"id":60,"firstName":"Virginia","lastName":"Cole","email":"vcole1n@imgur.com","avatar":"https://robohash.org/idcommodiiure.png?size=50x50&set=set1"},
61 | {"id":61,"firstName":"Larry","lastName":"Rogers","email":"lrogers1o@mediafire.com","avatar":"https://robohash.org/consecteturveleos.jpg?size=50x50&set=set1"},
62 | {"id":62,"firstName":"Stephen","lastName":"Brooks","email":"sbrooks1p@narod.ru","avatar":"https://robohash.org/etsuntunde.jpg?size=50x50&set=set1"},
63 | {"id":63,"firstName":"Joseph","lastName":"Lee","email":"jlee1q@deviantart.com","avatar":"https://robohash.org/exnamqui.png?size=50x50&set=set1"},
64 | {"id":64,"firstName":"Roger","lastName":"Long","email":"rlong1r@businessweek.com","avatar":"https://robohash.org/velnonnesciunt.bmp?size=50x50&set=set1"},
65 | {"id":65,"firstName":"Virginia","lastName":"Harper","email":"vharper1s@stanford.edu","avatar":"https://robohash.org/delenitidoloresdolores.jpg?size=50x50&set=set1"},
66 | {"id":66,"firstName":"Fred","lastName":"Robertson","email":"frobertson1t@tripod.com","avatar":"https://robohash.org/quononcumque.bmp?size=50x50&set=set1"},
67 | {"id":67,"firstName":"Ernest","lastName":"Price","email":"eprice1u@devhub.com","avatar":"https://robohash.org/consequunturestesse.bmp?size=50x50&set=set1"},
68 | {"id":68,"firstName":"Linda","lastName":"Murray","email":"lmurray1v@google.it","avatar":"https://robohash.org/ipsameligendiquia.bmp?size=50x50&set=set1"},
69 | {"id":69,"firstName":"Peter","lastName":"Dean","email":"pdean1w@webnode.com","avatar":"https://robohash.org/auttotamporro.jpg?size=50x50&set=set1"},
70 | {"id":70,"firstName":"Steven","lastName":"Baker","email":"sbaker1x@abc.net.au","avatar":"https://robohash.org/enimharumlaborum.jpg?size=50x50&set=set1"},
71 | {"id":71,"firstName":"Linda","lastName":"Smith","email":"lsmith1y@google.it","avatar":"https://robohash.org/sitautsit.jpg?size=50x50&set=set1"},
72 | {"id":72,"firstName":"Lillian","lastName":"Diaz","email":"ldiaz1z@exblog.jp","avatar":"https://robohash.org/autperspiciatisrepellat.jpg?size=50x50&set=set1"},
73 | {"id":73,"firstName":"Alan","lastName":"Smith","email":"asmith20@cpanel.net","avatar":"https://robohash.org/minusquiaest.png?size=50x50&set=set1"},
74 | {"id":74,"firstName":"Clarence","lastName":"Hill","email":"chill21@prweb.com","avatar":"https://robohash.org/ametetnostrum.bmp?size=50x50&set=set1"},
75 | {"id":75,"firstName":"Paula","lastName":"White","email":"pwhite22@cocolog-nifty.com","avatar":"https://robohash.org/assumendaomnisearum.png?size=50x50&set=set1"},
76 | {"id":76,"firstName":"Kathryn","lastName":"Wright","email":"kwright23@msu.edu","avatar":"https://robohash.org/temporesaepeenim.bmp?size=50x50&set=set1"},
77 | {"id":77,"firstName":"Roger","lastName":"Hill","email":"rhill24@tripod.com","avatar":"https://robohash.org/erroretquia.bmp?size=50x50&set=set1"},
78 | {"id":78,"firstName":"Todd","lastName":"Moreno","email":"tmoreno25@mit.edu","avatar":"https://robohash.org/quodinciduntmodi.jpg?size=50x50&set=set1"},
79 | {"id":79,"firstName":"George","lastName":"Brown","email":"gbrown26@myspace.com","avatar":"https://robohash.org/mollitiaminusexercitationem.jpg?size=50x50&set=set1"},
80 | {"id":80,"firstName":"Harry","lastName":"Dean","email":"hdean27@de.vu","avatar":"https://robohash.org/veldolordolorum.jpg?size=50x50&set=set1"},
81 | {"id":81,"firstName":"Norma","lastName":"Perez","email":"nperez28@ebay.com","avatar":"https://robohash.org/totamesseexplicabo.png?size=50x50&set=set1"},
82 | {"id":82,"firstName":"Cheryl","lastName":"Gilbert","email":"cgilbert29@ucsd.edu","avatar":"https://robohash.org/fugiatabfacere.bmp?size=50x50&set=set1"},
83 | {"id":83,"firstName":"Willie","lastName":"Myers","email":"wmyers2a@ow.ly","avatar":"https://robohash.org/earumnoniste.bmp?size=50x50&set=set1"},
84 | {"id":84,"firstName":"Fred","lastName":"Turner","email":"fturner2b@nasa.gov","avatar":"https://robohash.org/quisquamautemillo.bmp?size=50x50&set=set1"},
85 | {"id":85,"firstName":"Harold","lastName":"Garza","email":"hgarza2c@simplemachines.org","avatar":"https://robohash.org/voluptassuntdebitis.bmp?size=50x50&set=set1"},
86 | {"id":86,"firstName":"Judith","lastName":"Edwards","email":"jedwards2d@about.com","avatar":"https://robohash.org/inciduntinnesciunt.bmp?size=50x50&set=set1"},
87 | {"id":87,"firstName":"James","lastName":"Hall","email":"jhall2e@infoseek.co.jp","avatar":"https://robohash.org/placeatquianemo.bmp?size=50x50&set=set1"},
88 | {"id":88,"firstName":"Earl","lastName":"Phillips","email":"ephillips2f@technorati.com","avatar":"https://robohash.org/quodestcommodi.jpg?size=50x50&set=set1"},
89 | {"id":89,"firstName":"Bruce","lastName":"Garza","email":"bgarza2g@php.net","avatar":"https://robohash.org/sapienteeosautem.bmp?size=50x50&set=set1"},
90 | {"id":90,"firstName":"Joyce","lastName":"Simmons","email":"jsimmons2h@devhub.com","avatar":"https://robohash.org/voluptatemvelitofficiis.png?size=50x50&set=set1"},
91 | {"id":91,"firstName":"Pamela","lastName":"Carr","email":"pcarr2i@scientificamerican.com","avatar":"https://robohash.org/quiiustoadipisci.bmp?size=50x50&set=set1"},
92 | {"id":92,"firstName":"Debra","lastName":"Cox","email":"dcox2j@ucoz.com","avatar":"https://robohash.org/atquequoet.png?size=50x50&set=set1"},
93 | {"id":93,"firstName":"Cynthia","lastName":"Murray","email":"cmurray2k@trellian.com","avatar":"https://robohash.org/voluptassuscipitipsa.bmp?size=50x50&set=set1"},
94 | {"id":94,"firstName":"Margaret","lastName":"Bennett","email":"mbennett2l@jugem.jp","avatar":"https://robohash.org/magniettempore.png?size=50x50&set=set1"},
95 | {"id":95,"firstName":"Dennis","lastName":"Gonzalez","email":"dgonzalez2m@prlog.org","avatar":"https://robohash.org/laboriosamconsequaturinventore.bmp?size=50x50&set=set1"},
96 | {"id":96,"firstName":"Janice","lastName":"Adams","email":"jadams2n@vk.com","avatar":"https://robohash.org/facilismolestiaedeserunt.png?size=50x50&set=set1"},
97 | {"id":97,"firstName":"Billy","lastName":"Miller","email":"bmiller2o@pen.io","avatar":"https://robohash.org/ullamreiciendiset.png?size=50x50&set=set1"},
98 | {"id":98,"firstName":"Sara","lastName":"Stevens","email":"sstevens2p@vimeo.com","avatar":"https://robohash.org/utquasiquia.bmp?size=50x50&set=set1"},
99 | {"id":99,"firstName":"Julia","lastName":"Gonzales","email":"jgonzales2q@chicagotribune.com","avatar":"https://robohash.org/ipsalaudantiumexercitationem.bmp?size=50x50&set=set1"},
100 | {"id":100,"firstName":"Theresa","lastName":"Carter","email":"tcarter2r@google.fr","avatar":"https://robohash.org/quiconsequaturvoluptas.jpg?size=50x50&set=set1"},
101 | {"id":101,"firstName":"Robin","lastName":"Henderson","email":"rhenderson2s@wufoo.com","avatar":"https://robohash.org/suntdoloresquaerat.jpg?size=50x50&set=set1"},
102 | {"id":102,"firstName":"Helen","lastName":"Evans","email":"hevans2t@hc360.com","avatar":"https://robohash.org/cupiditatesolutavelit.jpg?size=50x50&set=set1"},
103 | {"id":103,"firstName":"Paula","lastName":"Dunn","email":"pdunn2u@mapquest.com","avatar":"https://robohash.org/similiquesequinatus.bmp?size=50x50&set=set1"},
104 | {"id":104,"firstName":"Lawrence","lastName":"Burke","email":"lburke2v@cloudflare.com","avatar":"https://robohash.org/veniaminventoresit.bmp?size=50x50&set=set1"},
105 | {"id":105,"firstName":"Sharon","lastName":"Carr","email":"scarr2w@google.com.hk","avatar":"https://robohash.org/etaliquamaut.jpg?size=50x50&set=set1"},
106 | {"id":106,"firstName":"Stephanie","lastName":"Brooks","email":"sbrooks2x@shareasale.com","avatar":"https://robohash.org/quiacorporisquia.bmp?size=50x50&set=set1"},
107 | {"id":107,"firstName":"Catherine","lastName":"Stone","email":"cstone2y@jigsy.com","avatar":"https://robohash.org/nonvoluptateaperiam.jpg?size=50x50&set=set1"},
108 | {"id":108,"firstName":"Russell","lastName":"Taylor","email":"rtaylor2z@lycos.com","avatar":"https://robohash.org/aliquamomnisomnis.bmp?size=50x50&set=set1"},
109 | {"id":109,"firstName":"Keith","lastName":"Perez","email":"kperez30@digg.com","avatar":"https://robohash.org/etlaborumnisi.jpg?size=50x50&set=set1"},
110 | {"id":110,"firstName":"Judith","lastName":"Hart","email":"jhart31@globo.com","avatar":"https://robohash.org/fugiatvitaequam.png?size=50x50&set=set1"},
111 | {"id":111,"firstName":"Harold","lastName":"George","email":"hgeorge32@xrea.com","avatar":"https://robohash.org/providentquianimi.jpg?size=50x50&set=set1"},
112 | {"id":112,"firstName":"Martin","lastName":"Knight","email":"mknight33@dagondesign.com","avatar":"https://robohash.org/voluptateprovidentquos.bmp?size=50x50&set=set1"},
113 | {"id":113,"firstName":"James","lastName":"Martinez","email":"jmartinez34@shop-pro.jp","avatar":"https://robohash.org/saeperepellendusbeatae.jpg?size=50x50&set=set1"},
114 | {"id":114,"firstName":"Evelyn","lastName":"Riley","email":"eriley35@hud.gov","avatar":"https://robohash.org/oditquaeratet.png?size=50x50&set=set1"},
115 | {"id":115,"firstName":"William","lastName":"White","email":"wwhite36@independent.co.uk","avatar":"https://robohash.org/etlaboriosamea.bmp?size=50x50&set=set1"},
116 | {"id":116,"firstName":"Anne","lastName":"Brooks","email":"abrooks37@rediff.com","avatar":"https://robohash.org/esseofficiaest.bmp?size=50x50&set=set1"},
117 | {"id":117,"firstName":"Kathy","lastName":"Roberts","email":"kroberts38@alibaba.com","avatar":"https://robohash.org/saepeexpeditamolestiae.jpg?size=50x50&set=set1"},
118 | {"id":118,"firstName":"Robin","lastName":"Garrett","email":"rgarrett39@europa.eu","avatar":"https://robohash.org/sapienteetofficiis.png?size=50x50&set=set1"},
119 | {"id":119,"firstName":"Lois","lastName":"Bell","email":"lbell3a@ucoz.ru","avatar":"https://robohash.org/solutaquisdolore.png?size=50x50&set=set1"},
120 | {"id":120,"firstName":"Robin","lastName":"Willis","email":"rwillis3b@arstechnica.com","avatar":"https://robohash.org/abvoluptasaut.jpg?size=50x50&set=set1"},
121 | {"id":121,"firstName":"Juan","lastName":"Smith","email":"jsmith3c@cbsnews.com","avatar":"https://robohash.org/veletet.bmp?size=50x50&set=set1"},
122 | {"id":122,"firstName":"Mark","lastName":"Greene","email":"mgreene3d@intel.com","avatar":"https://robohash.org/nihilmodiaut.jpg?size=50x50&set=set1"},
123 | {"id":123,"firstName":"Janet","lastName":"Welch","email":"jwelch3e@alibaba.com","avatar":"https://robohash.org/undequamdolores.jpg?size=50x50&set=set1"},
124 | {"id":124,"firstName":"Jean","lastName":"Ford","email":"jford3f@mashable.com","avatar":"https://robohash.org/ideta.bmp?size=50x50&set=set1"},
125 | {"id":125,"firstName":"Jessica","lastName":"Fisher","email":"jfisher3g@flickr.com","avatar":"https://robohash.org/etdelectusnecessitatibus.png?size=50x50&set=set1"},
126 | {"id":126,"firstName":"Elizabeth","lastName":"Daniels","email":"edaniels3h@pcworld.com","avatar":"https://robohash.org/exdoloremrerum.png?size=50x50&set=set1"},
127 | {"id":127,"firstName":"Terry","lastName":"Cook","email":"tcook3i@tiny.cc","avatar":"https://robohash.org/ullamistemagni.bmp?size=50x50&set=set1"},
128 | {"id":128,"firstName":"Frances","lastName":"Hart","email":"fhart3j@jugem.jp","avatar":"https://robohash.org/voluptasquodrepellendus.png?size=50x50&set=set1"},
129 | {"id":129,"firstName":"Jesse","lastName":"Johnson","email":"jjohnson3k@fotki.com","avatar":"https://robohash.org/oditoptioculpa.bmp?size=50x50&set=set1"},
130 | {"id":130,"firstName":"Michael","lastName":"Stevens","email":"mstevens3l@sfgate.com","avatar":"https://robohash.org/veroadiste.bmp?size=50x50&set=set1"},
131 | {"id":131,"firstName":"Angela","lastName":"Bowman","email":"abowman3m@indiegogo.com","avatar":"https://robohash.org/etinaut.bmp?size=50x50&set=set1"},
132 | {"id":132,"firstName":"Gerald","lastName":"Ward","email":"gward3n@plala.or.jp","avatar":"https://robohash.org/etvoluptatibusnostrum.jpg?size=50x50&set=set1"},
133 | {"id":133,"firstName":"Jack","lastName":"Russell","email":"jrussell3o@bloglovin.com","avatar":"https://robohash.org/autvitaeillum.jpg?size=50x50&set=set1"},
134 | {"id":134,"firstName":"Pamela","lastName":"Stevens","email":"pstevens3p@si.edu","avatar":"https://robohash.org/veroutdebitis.bmp?size=50x50&set=set1"},
135 | {"id":135,"firstName":"Craig","lastName":"Holmes","email":"cholmes3q@earthlink.net","avatar":"https://robohash.org/quisednecessitatibus.bmp?size=50x50&set=set1"},
136 | {"id":136,"firstName":"Victor","lastName":"Hill","email":"vhill3r@yellowbook.com","avatar":"https://robohash.org/accusantiumquiomnis.jpg?size=50x50&set=set1"},
137 | {"id":137,"firstName":"Jose","lastName":"Sullivan","email":"jsullivan3s@dropbox.com","avatar":"https://robohash.org/blanditiisducimusvoluptas.jpg?size=50x50&set=set1"},
138 | {"id":138,"firstName":"Susan","lastName":"Coleman","email":"scoleman3t@liveinternet.ru","avatar":"https://robohash.org/mollitiavoluptasvoluptate.png?size=50x50&set=set1"},
139 | {"id":139,"firstName":"Gloria","lastName":"Foster","email":"gfoster3u@wordpress.org","avatar":"https://robohash.org/quammodiquisquam.png?size=50x50&set=set1"},
140 | {"id":140,"firstName":"Anne","lastName":"Welch","email":"awelch3v@hostgator.com","avatar":"https://robohash.org/quisequivoluptas.png?size=50x50&set=set1"},
141 | {"id":141,"firstName":"Louise","lastName":"Peterson","email":"lpeterson3w@house.gov","avatar":"https://robohash.org/delenitisedharum.png?size=50x50&set=set1"},
142 | {"id":142,"firstName":"Nancy","lastName":"Coleman","email":"ncoleman3x@nytimes.com","avatar":"https://robohash.org/eligendivoluptasrepellat.png?size=50x50&set=set1"},
143 | {"id":143,"firstName":"Howard","lastName":"Torres","email":"htorres3y@i2i.jp","avatar":"https://robohash.org/accusantiummaximererum.jpg?size=50x50&set=set1"},
144 | {"id":144,"firstName":"Linda","lastName":"Patterson","email":"lpatterson3z@uol.com.br","avatar":"https://robohash.org/consequaturveritatistempore.bmp?size=50x50&set=set1"},
145 | {"id":145,"firstName":"Julie","lastName":"Gilbert","email":"jgilbert40@ask.com","avatar":"https://robohash.org/quiaquiminus.bmp?size=50x50&set=set1"},
146 | {"id":146,"firstName":"Harold","lastName":"Alvarez","email":"halvarez41@baidu.com","avatar":"https://robohash.org/quisconsequaturquis.bmp?size=50x50&set=set1"},
147 | {"id":147,"firstName":"Walter","lastName":"Little","email":"wlittle42@i2i.jp","avatar":"https://robohash.org/dolorumutnumquam.png?size=50x50&set=set1"},
148 | {"id":148,"firstName":"Mildred","lastName":"Matthews","email":"mmatthews43@example.com","avatar":"https://robohash.org/undequasrepellat.png?size=50x50&set=set1"},
149 | {"id":149,"firstName":"Pamela","lastName":"Wheeler","email":"pwheeler44@microsoft.com","avatar":"https://robohash.org/itaqueestnisi.bmp?size=50x50&set=set1"},
150 | {"id":150,"firstName":"Adam","lastName":"Gilbert","email":"agilbert45@shop-pro.jp","avatar":"https://robohash.org/utettotam.png?size=50x50&set=set1"},
151 | {"id":151,"firstName":"Raymond","lastName":"Roberts","email":"rroberts46@shareasale.com","avatar":"https://robohash.org/autexblanditiis.bmp?size=50x50&set=set1"},
152 | {"id":152,"firstName":"Lori","lastName":"Morales","email":"lmorales47@biblegateway.com","avatar":"https://robohash.org/doloresatet.jpg?size=50x50&set=set1"},
153 | {"id":153,"firstName":"Louise","lastName":"Hall","email":"lhall48@fotki.com","avatar":"https://robohash.org/auteumodit.jpg?size=50x50&set=set1"},
154 | {"id":154,"firstName":"Joyce","lastName":"Fuller","email":"jfuller49@prnewswire.com","avatar":"https://robohash.org/faceretemporaeum.png?size=50x50&set=set1"},
155 | {"id":155,"firstName":"Martin","lastName":"Torres","email":"mtorres4a@geocities.com","avatar":"https://robohash.org/quoblanditiisautem.bmp?size=50x50&set=set1"},
156 | {"id":156,"firstName":"Marie","lastName":"Duncan","email":"mduncan4b@ox.ac.uk","avatar":"https://robohash.org/quisquamsuntarchitecto.jpg?size=50x50&set=set1"},
157 | {"id":157,"firstName":"Joseph","lastName":"Hill","email":"jhill4c@comsenz.com","avatar":"https://robohash.org/repellendussuntin.png?size=50x50&set=set1"},
158 | {"id":158,"firstName":"Clarence","lastName":"Chavez","email":"cchavez4d@bbb.org","avatar":"https://robohash.org/veniammodivitae.png?size=50x50&set=set1"},
159 | {"id":159,"firstName":"Linda","lastName":"Wheeler","email":"lwheeler4e@themeforest.net","avatar":"https://robohash.org/nobissimiliquenulla.png?size=50x50&set=set1"},
160 | {"id":160,"firstName":"Fred","lastName":"Cole","email":"fcole4f@hud.gov","avatar":"https://robohash.org/quiaquiblanditiis.jpg?size=50x50&set=set1"},
161 | {"id":161,"firstName":"Joan","lastName":"Henderson","email":"jhenderson4g@pcworld.com","avatar":"https://robohash.org/corporispraesentiumdolores.png?size=50x50&set=set1"},
162 | {"id":162,"firstName":"Kathy","lastName":"Gordon","email":"kgordon4h@state.gov","avatar":"https://robohash.org/nihiloditqui.jpg?size=50x50&set=set1"},
163 | {"id":163,"firstName":"Frank","lastName":"Crawford","email":"fcrawford4i@dion.ne.jp","avatar":"https://robohash.org/veloptioplaceat.jpg?size=50x50&set=set1"},
164 | {"id":164,"firstName":"Kevin","lastName":"Freeman","email":"kfreeman4j@marketwatch.com","avatar":"https://robohash.org/quaseaquetemporibus.bmp?size=50x50&set=set1"},
165 | {"id":165,"firstName":"Betty","lastName":"Fields","email":"bfields4k@nationalgeographic.com","avatar":"https://robohash.org/undeaperiamblanditiis.png?size=50x50&set=set1"},
166 | {"id":166,"firstName":"Johnny","lastName":"Alvarez","email":"jalvarez4l@yale.edu","avatar":"https://robohash.org/estutnesciunt.jpg?size=50x50&set=set1"},
167 | {"id":167,"firstName":"Timothy","lastName":"Roberts","email":"troberts4m@bandcamp.com","avatar":"https://robohash.org/necessitatibusnondolores.jpg?size=50x50&set=set1"},
168 | {"id":168,"firstName":"Martin","lastName":"Hughes","email":"mhughes4n@huffingtonpost.com","avatar":"https://robohash.org/sintexpeditaquos.png?size=50x50&set=set1"},
169 | {"id":169,"firstName":"Julia","lastName":"Gibson","email":"jgibson4o@e-recht24.de","avatar":"https://robohash.org/quasettempore.jpg?size=50x50&set=set1"},
170 | {"id":170,"firstName":"Jessica","lastName":"Harris","email":"jharris4p@bigcartel.com","avatar":"https://robohash.org/quisimiliquearchitecto.bmp?size=50x50&set=set1"},
171 | {"id":171,"firstName":"Samuel","lastName":"George","email":"sgeorge4q@cmu.edu","avatar":"https://robohash.org/utipsavoluptatem.bmp?size=50x50&set=set1"},
172 | {"id":172,"firstName":"Todd","lastName":"Elliott","email":"telliott4r@ow.ly","avatar":"https://robohash.org/placeatnisia.bmp?size=50x50&set=set1"},
173 | {"id":173,"firstName":"Albert","lastName":"Romero","email":"aromero4s@behance.net","avatar":"https://robohash.org/corruptiutlaboriosam.png?size=50x50&set=set1"},
174 | {"id":174,"firstName":"Heather","lastName":"Palmer","email":"hpalmer4t@xing.com","avatar":"https://robohash.org/teneturmaioresaliquam.jpg?size=50x50&set=set1"},
175 | {"id":175,"firstName":"Joseph","lastName":"Fox","email":"jfox4u@japanpost.jp","avatar":"https://robohash.org/impeditiurevel.bmp?size=50x50&set=set1"},
176 | {"id":176,"firstName":"Angela","lastName":"Robertson","email":"arobertson4v@artisteer.com","avatar":"https://robohash.org/repellatoditquasi.bmp?size=50x50&set=set1"},
177 | {"id":177,"firstName":"Lisa","lastName":"Chapman","email":"lchapman4w@gravatar.com","avatar":"https://robohash.org/natusnobismagni.bmp?size=50x50&set=set1"},
178 | {"id":178,"firstName":"Kathy","lastName":"Myers","email":"kmyers4x@geocities.com","avatar":"https://robohash.org/etdolorenam.png?size=50x50&set=set1"},
179 | {"id":179,"firstName":"Adam","lastName":"Lee","email":"alee4y@cdbaby.com","avatar":"https://robohash.org/nonblanditiisid.jpg?size=50x50&set=set1"},
180 | {"id":180,"firstName":"Charles","lastName":"Daniels","email":"cdaniels4z@craigslist.org","avatar":"https://robohash.org/quimollitiadoloribus.png?size=50x50&set=set1"},
181 | {"id":181,"firstName":"Edward","lastName":"Bennett","email":"ebennett50@delicious.com","avatar":"https://robohash.org/maioresquiamodi.png?size=50x50&set=set1"},
182 | {"id":182,"firstName":"Wanda","lastName":"Carr","email":"wcarr51@shutterfly.com","avatar":"https://robohash.org/aspernaturrepellendusodio.jpg?size=50x50&set=set1"},
183 | {"id":183,"firstName":"John","lastName":"Morris","email":"jmorris52@home.pl","avatar":"https://robohash.org/reprehenderitpraesentiumomnis.png?size=50x50&set=set1"},
184 | {"id":184,"firstName":"Paul","lastName":"Anderson","email":"panderson53@diigo.com","avatar":"https://robohash.org/earepellatet.png?size=50x50&set=set1"},
185 | {"id":185,"firstName":"Aaron","lastName":"Ryan","email":"aryan54@boston.com","avatar":"https://robohash.org/quietsuscipit.bmp?size=50x50&set=set1"},
186 | {"id":186,"firstName":"Anthony","lastName":"Perry","email":"aperry55@google.fr","avatar":"https://robohash.org/aspernaturutnumquam.bmp?size=50x50&set=set1"},
187 | {"id":187,"firstName":"Frances","lastName":"Simmons","email":"fsimmons56@economist.com","avatar":"https://robohash.org/illuminciduntdolores.bmp?size=50x50&set=set1"},
188 | {"id":188,"firstName":"Jesse","lastName":"Sullivan","email":"jsullivan57@last.fm","avatar":"https://robohash.org/quisednostrum.png?size=50x50&set=set1"},
189 | {"id":189,"firstName":"Joyce","lastName":"Wheeler","email":"jwheeler58@usa.gov","avatar":"https://robohash.org/doloretet.bmp?size=50x50&set=set1"},
190 | {"id":190,"firstName":"Mildred","lastName":"Young","email":"myoung59@hubpages.com","avatar":"https://robohash.org/minimaarchitectoporro.bmp?size=50x50&set=set1"},
191 | {"id":191,"firstName":"Susan","lastName":"Fields","email":"sfields5a@github.com","avatar":"https://robohash.org/autullameos.png?size=50x50&set=set1"},
192 | {"id":192,"firstName":"John","lastName":"Daniels","email":"jdaniels5b@mapquest.com","avatar":"https://robohash.org/estnihilquos.jpg?size=50x50&set=set1"},
193 | {"id":193,"firstName":"Eric","lastName":"Garza","email":"egarza5c@macromedia.com","avatar":"https://robohash.org/sitipsumeum.png?size=50x50&set=set1"},
194 | {"id":194,"firstName":"Catherine","lastName":"Wilson","email":"cwilson5d@nydailynews.com","avatar":"https://robohash.org/aliasiustofacere.bmp?size=50x50&set=set1"},
195 | {"id":195,"firstName":"Teresa","lastName":"Garza","email":"tgarza5e@hexun.com","avatar":"https://robohash.org/fugamodinon.bmp?size=50x50&set=set1"},
196 | {"id":196,"firstName":"Nancy","lastName":"Foster","email":"nfoster5f@pcworld.com","avatar":"https://robohash.org/estnumquamaut.jpg?size=50x50&set=set1"},
197 | {"id":197,"firstName":"Lois","lastName":"Wright","email":"lwright5g@princeton.edu","avatar":"https://robohash.org/sedvoluptatumratione.png?size=50x50&set=set1"},
198 | {"id":198,"firstName":"Sandra","lastName":"Parker","email":"sparker5h@toplist.cz","avatar":"https://robohash.org/atqueeumomnis.bmp?size=50x50&set=set1"},
199 | {"id":199,"firstName":"Patrick","lastName":"Sullivan","email":"psullivan5i@weather.com","avatar":"https://robohash.org/quaeratvoluptatumtotam.png?size=50x50&set=set1"},
200 | {"id":200,"firstName":"Jeremy","lastName":"Lopez","email":"jlopez5j@issuu.com","avatar":"https://robohash.org/adipiscifugiatquam.jpg?size=50x50&set=set1"},
201 | {"id":201,"firstName":"Brenda","lastName":"Lynch","email":"blynch5k@alexa.com","avatar":"https://robohash.org/placeatnisiodit.png?size=50x50&set=set1"},
202 | {"id":202,"firstName":"Donald","lastName":"Peterson","email":"dpeterson5l@ted.com","avatar":"https://robohash.org/etevenietvelit.jpg?size=50x50&set=set1"},
203 | {"id":203,"firstName":"Billy","lastName":"Fields","email":"bfields5m@shareasale.com","avatar":"https://robohash.org/quivitaesed.png?size=50x50&set=set1"},
204 | {"id":204,"firstName":"Sandra","lastName":"Oliver","email":"soliver5n@so-net.ne.jp","avatar":"https://robohash.org/quiaexfacilis.bmp?size=50x50&set=set1"},
205 | {"id":205,"firstName":"Edward","lastName":"Rodriguez","email":"erodriguez5o@icq.com","avatar":"https://robohash.org/dolorumharumquaerat.bmp?size=50x50&set=set1"},
206 | {"id":206,"firstName":"Randy","lastName":"Rose","email":"rrose5p@springer.com","avatar":"https://robohash.org/sitculpaquia.jpg?size=50x50&set=set1"},
207 | {"id":207,"firstName":"Norma","lastName":"James","email":"njames5q@yahoo.com","avatar":"https://robohash.org/omnisdoloret.bmp?size=50x50&set=set1"},
208 | {"id":208,"firstName":"Pamela","lastName":"Reed","email":"preed5r@oaic.gov.au","avatar":"https://robohash.org/quaesitmollitia.bmp?size=50x50&set=set1"},
209 | {"id":209,"firstName":"Ruth","lastName":"Woods","email":"rwoods5s@ovh.net","avatar":"https://robohash.org/laboriosamveritatisassumenda.png?size=50x50&set=set1"},
210 | {"id":210,"firstName":"Harry","lastName":"Turner","email":"hturner5t@is.gd","avatar":"https://robohash.org/quisomnisatque.jpg?size=50x50&set=set1"},
211 | {"id":211,"firstName":"Richard","lastName":"Black","email":"rblack5u@newyorker.com","avatar":"https://robohash.org/doloremqueeiuscumque.jpg?size=50x50&set=set1"},
212 | {"id":212,"firstName":"Anna","lastName":"Jenkins","email":"ajenkins5v@wordpress.org","avatar":"https://robohash.org/quiisteaspernatur.bmp?size=50x50&set=set1"},
213 | {"id":213,"firstName":"Sara","lastName":"Gomez","email":"sgomez5w@opensource.org","avatar":"https://robohash.org/estaperiamvel.jpg?size=50x50&set=set1"},
214 | {"id":214,"firstName":"Heather","lastName":"Simpson","email":"hsimpson5x@istockphoto.com","avatar":"https://robohash.org/nihilquiplaceat.jpg?size=50x50&set=set1"},
215 | {"id":215,"firstName":"Joseph","lastName":"Graham","email":"jgraham5y@ezinearticles.com","avatar":"https://robohash.org/quossimiliquenam.jpg?size=50x50&set=set1"},
216 | {"id":216,"firstName":"Wanda","lastName":"Andrews","email":"wandrews5z@yahoo.com","avatar":"https://robohash.org/illodoloresnam.bmp?size=50x50&set=set1"},
217 | {"id":217,"firstName":"Roger","lastName":"Lynch","email":"rlynch60@t-online.de","avatar":"https://robohash.org/voluptatumblanditiisest.png?size=50x50&set=set1"},
218 | {"id":218,"firstName":"Lisa","lastName":"Alvarez","email":"lalvarez61@miitbeian.gov.cn","avatar":"https://robohash.org/evenietsitconsequatur.bmp?size=50x50&set=set1"},
219 | {"id":219,"firstName":"Kevin","lastName":"Black","email":"kblack62@seattletimes.com","avatar":"https://robohash.org/quaeratestcorporis.jpg?size=50x50&set=set1"},
220 | {"id":220,"firstName":"Catherine","lastName":"Nguyen","email":"cnguyen63@squidoo.com","avatar":"https://robohash.org/velitnemoet.bmp?size=50x50&set=set1"},
221 | {"id":221,"firstName":"Roger","lastName":"Sullivan","email":"rsullivan64@sphinn.com","avatar":"https://robohash.org/aspernaturetnatus.png?size=50x50&set=set1"},
222 | {"id":222,"firstName":"Roger","lastName":"Hansen","email":"rhansen65@latimes.com","avatar":"https://robohash.org/dolortenetursit.jpg?size=50x50&set=set1"},
223 | {"id":223,"firstName":"Jennifer","lastName":"Scott","email":"jscott66@patch.com","avatar":"https://robohash.org/esttotamvoluptatum.png?size=50x50&set=set1"},
224 | {"id":224,"firstName":"Charles","lastName":"Dean","email":"cdean67@salon.com","avatar":"https://robohash.org/omnisveritatismollitia.png?size=50x50&set=set1"},
225 | {"id":225,"firstName":"Patrick","lastName":"Taylor","email":"ptaylor68@vk.com","avatar":"https://robohash.org/fugiatcommodinihil.png?size=50x50&set=set1"},
226 | {"id":226,"firstName":"Mildred","lastName":"Cooper","email":"mcooper69@zimbio.com","avatar":"https://robohash.org/excepturiautmolestiae.bmp?size=50x50&set=set1"},
227 | {"id":227,"firstName":"Barbara","lastName":"Moreno","email":"bmoreno6a@bravesites.com","avatar":"https://robohash.org/nonarchitectoquibusdam.png?size=50x50&set=set1"},
228 | {"id":228,"firstName":"Andrew","lastName":"Scott","email":"ascott6b@epa.gov","avatar":"https://robohash.org/voluptatumeiusin.png?size=50x50&set=set1"},
229 | {"id":229,"firstName":"Sharon","lastName":"Carter","email":"scarter6c@vistaprint.com","avatar":"https://robohash.org/nostrumutdicta.jpg?size=50x50&set=set1"},
230 | {"id":230,"firstName":"Willie","lastName":"Baker","email":"wbaker6d@chicagotribune.com","avatar":"https://robohash.org/cumquesaepeofficiis.jpg?size=50x50&set=set1"},
231 | {"id":231,"firstName":"Kathryn","lastName":"Meyer","email":"kmeyer6e@toplist.cz","avatar":"https://robohash.org/odioquistemporibus.bmp?size=50x50&set=set1"},
232 | {"id":232,"firstName":"Nicole","lastName":"Nguyen","email":"nnguyen6f@pcworld.com","avatar":"https://robohash.org/similiqueofficianeque.bmp?size=50x50&set=set1"},
233 | {"id":233,"firstName":"Sarah","lastName":"Stephens","email":"sstephens6g@uiuc.edu","avatar":"https://robohash.org/doloressedexpedita.bmp?size=50x50&set=set1"},
234 | {"id":234,"firstName":"Douglas","lastName":"Mccoy","email":"dmccoy6h@reuters.com","avatar":"https://robohash.org/etinreprehenderit.bmp?size=50x50&set=set1"},
235 | {"id":235,"firstName":"Deborah","lastName":"Hall","email":"dhall6i@nydailynews.com","avatar":"https://robohash.org/enimiurequis.jpg?size=50x50&set=set1"},
236 | {"id":236,"firstName":"Joyce","lastName":"Robertson","email":"jrobertson6j@indiatimes.com","avatar":"https://robohash.org/odioquamunde.png?size=50x50&set=set1"},
237 | {"id":237,"firstName":"Ashley","lastName":"Price","email":"aprice6k@ihg.com","avatar":"https://robohash.org/doloremrerumalias.jpg?size=50x50&set=set1"},
238 | {"id":238,"firstName":"Gary","lastName":"Garrett","email":"ggarrett6l@over-blog.com","avatar":"https://robohash.org/totamvelinventore.bmp?size=50x50&set=set1"},
239 | {"id":239,"firstName":"Sandra","lastName":"Harrison","email":"sharrison6m@weather.com","avatar":"https://robohash.org/occaecatiinventoreconsequatur.bmp?size=50x50&set=set1"},
240 | {"id":240,"firstName":"Mark","lastName":"Gilbert","email":"mgilbert6n@hc360.com","avatar":"https://robohash.org/mollitiavoluptasvero.jpg?size=50x50&set=set1"},
241 | {"id":241,"firstName":"Gregory","lastName":"Carpenter","email":"gcarpenter6o@feedburner.com","avatar":"https://robohash.org/consecteturtemporenihil.png?size=50x50&set=set1"},
242 | {"id":242,"firstName":"Henry","lastName":"Webb","email":"hwebb6p@army.mil","avatar":"https://robohash.org/assumendaliberoaliquam.png?size=50x50&set=set1"},
243 | {"id":243,"firstName":"Gary","lastName":"Nelson","email":"gnelson6q@chicagotribune.com","avatar":"https://robohash.org/etsitassumenda.bmp?size=50x50&set=set1"},
244 | {"id":244,"firstName":"Jason","lastName":"Lawrence","email":"jlawrence6r@ifeng.com","avatar":"https://robohash.org/enimsaepeincidunt.png?size=50x50&set=set1"},
245 | {"id":245,"firstName":"Alice","lastName":"Jones","email":"ajones6s@nbcnews.com","avatar":"https://robohash.org/etmolestiasharum.png?size=50x50&set=set1"},
246 | {"id":246,"firstName":"Carol","lastName":"Stanley","email":"cstanley6t@ifeng.com","avatar":"https://robohash.org/omnisdolorveritatis.png?size=50x50&set=set1"},
247 | {"id":247,"firstName":"Harry","lastName":"Bennett","email":"hbennett6u@eepurl.com","avatar":"https://robohash.org/minimaporroet.bmp?size=50x50&set=set1"},
248 | {"id":248,"firstName":"Gary","lastName":"Bailey","email":"gbailey6v@about.me","avatar":"https://robohash.org/minimanemoaccusantium.png?size=50x50&set=set1"},
249 | {"id":249,"firstName":"James","lastName":"Rose","email":"jrose6w@gizmodo.com","avatar":"https://robohash.org/consequunturincidunteligendi.bmp?size=50x50&set=set1"},
250 | {"id":250,"firstName":"Philip","lastName":"Webb","email":"pwebb6x@myspace.com","avatar":"https://robohash.org/laborumconsequatursapiente.jpg?size=50x50&set=set1"},
251 | {"id":251,"firstName":"Joan","lastName":"Carter","email":"jcarter6y@apache.org","avatar":"https://robohash.org/inutiste.png?size=50x50&set=set1"},
252 | {"id":252,"firstName":"Deborah","lastName":"Moore","email":"dmoore6z@google.fr","avatar":"https://robohash.org/minusutquidem.bmp?size=50x50&set=set1"},
253 | {"id":253,"firstName":"Patrick","lastName":"Price","email":"pprice70@stumbleupon.com","avatar":"https://robohash.org/quisquamrecusandaedolores.jpg?size=50x50&set=set1"},
254 | {"id":254,"firstName":"Annie","lastName":"Rivera","email":"arivera71@whitehouse.gov","avatar":"https://robohash.org/distinctiomodirepellendus.png?size=50x50&set=set1"},
255 | {"id":255,"firstName":"Ralph","lastName":"Morales","email":"rmorales72@bloglines.com","avatar":"https://robohash.org/fugaautoptio.jpg?size=50x50&set=set1"},
256 | {"id":256,"firstName":"Adam","lastName":"Griffin","email":"agriffin73@apple.com","avatar":"https://robohash.org/illumdoloremiure.jpg?size=50x50&set=set1"},
257 | {"id":257,"firstName":"Johnny","lastName":"Rogers","email":"jrogers74@time.com","avatar":"https://robohash.org/omnishicvoluptates.bmp?size=50x50&set=set1"},
258 | {"id":258,"firstName":"Linda","lastName":"Flores","email":"lflores75@dailymail.co.uk","avatar":"https://robohash.org/dolorvelqui.jpg?size=50x50&set=set1"},
259 | {"id":259,"firstName":"Frances","lastName":"Gilbert","email":"fgilbert76@free.fr","avatar":"https://robohash.org/nobisutunde.bmp?size=50x50&set=set1"},
260 | {"id":260,"firstName":"Virginia","lastName":"Kim","email":"vkim77@google.it","avatar":"https://robohash.org/sedomnisenim.png?size=50x50&set=set1"},
261 | {"id":261,"firstName":"John","lastName":"Ruiz","email":"jruiz78@plala.or.jp","avatar":"https://robohash.org/rerumenimanimi.png?size=50x50&set=set1"},
262 | {"id":262,"firstName":"Judith","lastName":"Jones","email":"jjones79@seattletimes.com","avatar":"https://robohash.org/ducimuscommodiaspernatur.png?size=50x50&set=set1"},
263 | {"id":263,"firstName":"Sara","lastName":"Gilbert","email":"sgilbert7a@mac.com","avatar":"https://robohash.org/vitaequiaratione.bmp?size=50x50&set=set1"},
264 | {"id":264,"firstName":"Timothy","lastName":"Wells","email":"twells7b@disqus.com","avatar":"https://robohash.org/solutaexplicaboet.bmp?size=50x50&set=set1"},
265 | {"id":265,"firstName":"Richard","lastName":"Armstrong","email":"rarmstrong7c@columbia.edu","avatar":"https://robohash.org/repellendusmollitiaodio.jpg?size=50x50&set=set1"},
266 | {"id":266,"firstName":"Brenda","lastName":"Lewis","email":"blewis7d@amazon.de","avatar":"https://robohash.org/molestiaeetvitae.jpg?size=50x50&set=set1"},
267 | {"id":267,"firstName":"George","lastName":"Adams","email":"gadams7e@qq.com","avatar":"https://robohash.org/exidcumque.jpg?size=50x50&set=set1"},
268 | {"id":268,"firstName":"Alan","lastName":"Butler","email":"abutler7f@1688.com","avatar":"https://robohash.org/quisnobisprovident.png?size=50x50&set=set1"},
269 | {"id":269,"firstName":"Michelle","lastName":"Riley","email":"mriley7g@sina.com.cn","avatar":"https://robohash.org/assumendarationevelit.jpg?size=50x50&set=set1"},
270 | {"id":270,"firstName":"Sara","lastName":"Olson","email":"solson7h@liveinternet.ru","avatar":"https://robohash.org/sitquoaperiam.bmp?size=50x50&set=set1"},
271 | {"id":271,"firstName":"Katherine","lastName":"Gibson","email":"kgibson7i@e-recht24.de","avatar":"https://robohash.org/numquamfugitillo.bmp?size=50x50&set=set1"},
272 | {"id":272,"firstName":"Janice","lastName":"Diaz","email":"jdiaz7j@myspace.com","avatar":"https://robohash.org/utoditquia.bmp?size=50x50&set=set1"},
273 | {"id":273,"firstName":"Anna","lastName":"Carter","email":"acarter7k@admin.ch","avatar":"https://robohash.org/excepturinecessitatibusiusto.bmp?size=50x50&set=set1"},
274 | {"id":274,"firstName":"Dorothy","lastName":"Mitchell","email":"dmitchell7l@printfriendly.com","avatar":"https://robohash.org/omnisliberout.bmp?size=50x50&set=set1"},
275 | {"id":275,"firstName":"Amy","lastName":"Mccoy","email":"amccoy7m@nhs.uk","avatar":"https://robohash.org/veritatisoccaecatiincidunt.png?size=50x50&set=set1"},
276 | {"id":276,"firstName":"Marie","lastName":"Crawford","email":"mcrawford7n@nytimes.com","avatar":"https://robohash.org/velitutaut.bmp?size=50x50&set=set1"},
277 | {"id":277,"firstName":"Henry","lastName":"Perkins","email":"hperkins7o@163.com","avatar":"https://robohash.org/officiisdoloret.png?size=50x50&set=set1"},
278 | {"id":278,"firstName":"Juan","lastName":"Owens","email":"jowens7p@google.co.uk","avatar":"https://robohash.org/quisquiiusto.jpg?size=50x50&set=set1"},
279 | {"id":279,"firstName":"Marie","lastName":"Dean","email":"mdean7q@sphinn.com","avatar":"https://robohash.org/laborumsinteos.png?size=50x50&set=set1"},
280 | {"id":280,"firstName":"James","lastName":"Wilson","email":"jwilson7r@webmd.com","avatar":"https://robohash.org/aspernaturillumaut.bmp?size=50x50&set=set1"},
281 | {"id":281,"firstName":"Anne","lastName":"Baker","email":"abaker7s@hatena.ne.jp","avatar":"https://robohash.org/suntetut.png?size=50x50&set=set1"},
282 | {"id":282,"firstName":"Kelly","lastName":"Mason","email":"kmason7t@nasa.gov","avatar":"https://robohash.org/quamaperiamut.jpg?size=50x50&set=set1"},
283 | {"id":283,"firstName":"Ryan","lastName":"Carr","email":"rcarr7u@samsung.com","avatar":"https://robohash.org/quiscommodiculpa.png?size=50x50&set=set1"},
284 | {"id":284,"firstName":"Bonnie","lastName":"Bennett","email":"bbennett7v@virginia.edu","avatar":"https://robohash.org/itaquequisut.png?size=50x50&set=set1"},
285 | {"id":285,"firstName":"Alan","lastName":"Ramos","email":"aramos7w@hp.com","avatar":"https://robohash.org/ipsaautad.png?size=50x50&set=set1"},
286 | {"id":286,"firstName":"Jack","lastName":"Bryant","email":"jbryant7x@cnbc.com","avatar":"https://robohash.org/doloresdolorcupiditate.bmp?size=50x50&set=set1"},
287 | {"id":287,"firstName":"Elizabeth","lastName":"Miller","email":"emiller7y@cnbc.com","avatar":"https://robohash.org/minimaautlabore.bmp?size=50x50&set=set1"},
288 | {"id":288,"firstName":"Chris","lastName":"Morrison","email":"cmorrison7z@slate.com","avatar":"https://robohash.org/nostrumvoluptateet.png?size=50x50&set=set1"},
289 | {"id":289,"firstName":"Kenneth","lastName":"Kennedy","email":"kkennedy80@dion.ne.jp","avatar":"https://robohash.org/eaqueitaqueex.png?size=50x50&set=set1"},
290 | {"id":290,"firstName":"Thomas","lastName":"Andrews","email":"tandrews81@topsy.com","avatar":"https://robohash.org/natusasperioresaut.bmp?size=50x50&set=set1"},
291 | {"id":291,"firstName":"Anthony","lastName":"Berry","email":"aberry82@netscape.com","avatar":"https://robohash.org/porrovelillum.jpg?size=50x50&set=set1"},
292 | {"id":292,"firstName":"Henry","lastName":"Bailey","email":"hbailey83@blogs.com","avatar":"https://robohash.org/quaeratetitaque.jpg?size=50x50&set=set1"},
293 | {"id":293,"firstName":"Jean","lastName":"Davis","email":"jdavis84@guardian.co.uk","avatar":"https://robohash.org/quisquamquiminus.jpg?size=50x50&set=set1"},
294 | {"id":294,"firstName":"Cynthia","lastName":"Freeman","email":"cfreeman85@yelp.com","avatar":"https://robohash.org/cupiditateminimaexplicabo.bmp?size=50x50&set=set1"},
295 | {"id":295,"firstName":"Terry","lastName":"James","email":"tjames86@google.co.uk","avatar":"https://robohash.org/ullamquisquamipsum.png?size=50x50&set=set1"},
296 | {"id":296,"firstName":"Samuel","lastName":"Lewis","email":"slewis87@huffingtonpost.com","avatar":"https://robohash.org/perferendisrationeaut.bmp?size=50x50&set=set1"},
297 | {"id":297,"firstName":"Helen","lastName":"Watkins","email":"hwatkins88@vistaprint.com","avatar":"https://robohash.org/deseruntetitaque.jpg?size=50x50&set=set1"},
298 | {"id":298,"firstName":"Roger","lastName":"Scott","email":"rscott89@jugem.jp","avatar":"https://robohash.org/veritatisinvel.png?size=50x50&set=set1"},
299 | {"id":299,"firstName":"Kenneth","lastName":"Cruz","email":"kcruz8a@rambler.ru","avatar":"https://robohash.org/quisquamquiaqui.jpg?size=50x50&set=set1"},
300 | {"id":300,"firstName":"Donald","lastName":"Dean","email":"ddean8b@i2i.jp","avatar":"https://robohash.org/eaeosvoluptatem.png?size=50x50&set=set1"}
301 | ]
--------------------------------------------------------------------------------