提交 916b6b93 编写于 作者: J Jeff Fox

Init App

上级
{
"name": "101-app",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"prettify": "prettier -l --write \"**/*.js\"",
"test": "jest",
"dev": "nodemon src/index.js"
},
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"mysql": "^2.17.1",
"sqlite3": "^4.1.0",
"uuid": "^3.3.3",
"wait-port": "^0.2.2"
},
"prettier": {
"trailingComma": "all",
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": true
},
"devDependencies": {
"jest": "^24.9.0",
"nodemon": "^1.19.2",
"prettier": "^1.18.2"
}
}
const db = require('../../src/persistence/sqlite');
const fs = require('fs');
const ITEM = {
id: '7aef3d7c-d301-4846-8358-2a91ec9d6be3',
name: 'Test',
completed: false,
};
beforeEach(() => {
if (fs.existsSync('/etc/todos/todo.db')) {
fs.unlinkSync('/etc/todos/todo.db');
}
});
test('it initializes correctly', async () => {
await db.init();
});
test('it can store and retrieve items', async () => {
await db.init();
await db.storeItem(ITEM);
const items = await db.getItems();
expect(items.length).toBe(1);
expect(items[0]).toEqual(ITEM);
});
test('it can update an existing item', async () => {
await db.init();
const initialItems = await db.getItems();
expect(initialItems.length).toBe(0);
await db.storeItem(ITEM);
await db.updateItem(
ITEM.id,
Object.assign({}, ITEM, { completed: !ITEM.completed }),
);
const items = await db.getItems();
expect(items.length).toBe(1);
expect(items[0].completed).toBe(!ITEM.completed);
});
test('it can remove an existing item', async () => {
await db.init();
await db.storeItem(ITEM);
await db.removeItem(ITEM.id);
const items = await db.getItems();
expect(items.length).toBe(0);
});
test('it can get a single item', async () => {
await db.init();
await db.storeItem(ITEM);
const item = await db.getItem(ITEM.id);
expect(item).toEqual(ITEM);
});
const db = require('../../src/persistence');
const addItem = require('../../src/routes/addItem');
const ITEM = { id: 12345 };
const uuid = require('uuid/v4');
jest.mock('uuid/v4', () => jest.fn());
jest.mock('../../src/persistence', () => ({
removeItem: jest.fn(),
storeItem: jest.fn(),
getItem: jest.fn(),
}));
test('it stores item correctly', async () => {
const id = 'something-not-a-uuid';
const name = 'A sample item';
const req = { body: { name } };
const res = { send: jest.fn() };
uuid.mockReturnValue(id);
await addItem(req, res);
const expectedItem = { id, name, completed: false };
expect(db.storeItem.mock.calls.length).toBe(1);
expect(db.storeItem.mock.calls[0][0]).toEqual(expectedItem);
expect(res.send.mock.calls[0].length).toBe(1);
expect(res.send.mock.calls[0][0]).toEqual(expectedItem);
});
const db = require('../../src/persistence');
const deleteItem = require('../../src/routes/deleteItem');
const ITEM = { id: 12345 };
jest.mock('../../src/persistence', () => ({
removeItem: jest.fn(),
getItem: jest.fn(),
}));
test('it removes item correctly', async () => {
const req = { params: { id: 12345 } };
const res = { sendStatus: jest.fn() };
await deleteItem(req, res);
expect(db.removeItem.mock.calls.length).toBe(1);
expect(db.removeItem.mock.calls[0][0]).toBe(req.params.id);
expect(res.sendStatus.mock.calls[0].length).toBe(1);
expect(res.sendStatus.mock.calls[0][0]).toBe(200);
});
const db = require('../../src/persistence');
const getItems = require('../../src/routes/getItems');
const ITEMS = [{ id: 12345 }];
jest.mock('../../src/persistence', () => ({
getItems: jest.fn(),
}));
test('it gets items correctly', async () => {
const req = {};
const res = { send: jest.fn() };
db.getItems.mockReturnValue(Promise.resolve(ITEMS));
await getItems(req, res);
expect(db.getItems.mock.calls.length).toBe(1);
expect(res.send.mock.calls[0].length).toBe(1);
expect(res.send.mock.calls[0][0]).toEqual(ITEMS);
});
const db = require('../../src/persistence');
const updateItem = require('../../src/routes/updateItem');
const ITEM = { id: 12345 };
jest.mock('../../src/persistence', () => ({
getItem: jest.fn(),
updateItem: jest.fn(),
}));
test('it updates items correctly', async () => {
const req = {
params: { id: 1234 },
body: { name: 'New title', completed: false },
};
const res = { send: jest.fn() };
db.getItem.mockReturnValue(Promise.resolve(ITEM));
await updateItem(req, res);
expect(db.updateItem.mock.calls.length).toBe(1);
expect(db.updateItem.mock.calls[0][0]).toBe(req.params.id);
expect(db.updateItem.mock.calls[0][1]).toEqual({
name: 'New title',
completed: false,
});
expect(db.getItem.mock.calls.length).toBe(1);
expect(db.getItem.mock.calls[0][0]).toBe(req.params.id);
expect(res.send.mock.calls[0].length).toBe(1);
expect(res.send.mock.calls[0][0]).toEqual(ITEM);
});
const express = require('express');
const app = express();
const db = require('./persistence');
const getItems = require('./routes/getItems');
const addItem = require('./routes/addItem');
const updateItem = require('./routes/updateItem');
const deleteItem = require('./routes/deleteItem');
app.use(require('body-parser').json());
app.use(express.static(__dirname + '/static'));
app.get('/items', getItems);
app.post('/items', addItem);
app.put('/items/:id', updateItem);
app.delete('/items/:id', deleteItem);
db.init().then(() => {
app.listen(3000, () => console.log('Listening on port 3000'));
}).catch((err) => {
console.error(err);
process.exit(1);
});
const gracefulShutdown = () => {
db.teardown()
.catch(() => {})
.then(() => process.exit());
};
process.on('SIGINT', gracefulShutdown);
process.on('SIGTERM', gracefulShutdown);
process.on('SIGUSR2', gracefulShutdown); // Sent by nodemon
if (process.env.MYSQL_HOST) module.exports = require('./mysql');
else module.exports = require('./sqlite');
const waitPort = require('wait-port');
const fs = require('fs');
const mysql = require('mysql');
const {
MYSQL_HOST: HOST,
MYSQL_HOST_FILE: HOST_FILE,
MYSQL_USER: USER,
MYSQL_USER_FILE: USER_FILE,
MYSQL_PASSWORD: PASSWORD,
MYSQL_PASSWORD_FILE: PASSWORD_FILE,
MYSQL_DB: DB,
MYSQL_DB_FILE: DB_FILE,
} = process.env;
let pool;
async function init() {
const host = HOST_FILE ? fs.readFileSync(HOST_FILE) : HOST;
const user = USER_FILE ? fs.readFileSync(USER_FILE) : USER;
const password = PASSWORD_FILE ? fs.readFileSync(PASSWORD_FILE) : PASSWORD;
const database = DB_FILE ? fs.readFileSync(DB_FILE) : DB;
await waitPort({ host, port : 3306});
pool = mysql.createPool({
connectionLimit: 5,
host,
user,
password,
database,
});
return new Promise((acc, rej) => {
pool.query(
'CREATE TABLE IF NOT EXISTS todo_items (id varchar(36), name varchar(255), completed boolean)',
err => {
if (err) return rej(err);
console.log(`Connected to mysql db at host ${HOST}`);
acc();
},
);
});
}
async function teardown() {
return new Promise((acc, rej) => {
pool.end(err => {
if (err) rej(err);
else acc();
});
});
}
async function getItems() {
return new Promise((acc, rej) => {
pool.query('SELECT * FROM todo_items', (err, rows) => {
if (err) return rej(err);
acc(
rows.map(item =>
Object.assign({}, item, {
completed: item.completed === 1,
}),
),
);
});
});
}
async function getItem(id) {
return new Promise((acc, rej) => {
pool.query('SELECT * FROM todo_items WHERE id=?', [id], (err, rows) => {
if (err) return rej(err);
acc(
rows.map(item =>
Object.assign({}, item, {
completed: item.completed === 1,
}),
)[0],
);
});
});
}
async function storeItem(item) {
return new Promise((acc, rej) => {
pool.query(
'INSERT INTO todo_items (id, name, completed) VALUES (?, ?, ?)',
[item.id, item.name, item.completed ? 1 : 0],
err => {
if (err) return rej(err);
acc();
},
);
});
}
async function updateItem(id, item) {
return new Promise((acc, rej) => {
pool.query(
'UPDATE todo_items SET name=?, completed=? WHERE id=?',
[item.name, item.completed ? 1 : 0, id],
err => {
if (err) return rej(err);
acc();
},
);
});
}
async function removeItem(id) {
return new Promise((acc, rej) => {
pool.query('DELETE FROM todo_items WHERE id = ?', [id], err => {
if (err) return rej(err);
acc();
});
});
}
module.exports = {
init,
teardown,
getItems,
getItem,
storeItem,
updateItem,
removeItem,
};
const sqlite3 = require('sqlite3').verbose();
const fs = require('fs');
const location = process.env.SQLITE_DB_LOCATION || '/etc/todos/todo.db';
let db, dbAll, dbRun;
function init() {
const dirName = require('path').dirname(location);
if (!fs.existsSync(dirName)) {
fs.mkdirSync(dirName, { recursive: true });
}
return new Promise((acc, rej) => {
db = new sqlite3.Database(location, err => {
if (err) return rej(err);
if (process.env.NODE_ENV !== 'test')
console.log(`Using sqlite database at ${location}`);
db.run(
'CREATE TABLE IF NOT EXISTS todo_items (id varchar(36), name varchar(255), completed boolean)',
(err, result) => {
if (err) return rej(err);
acc();
},
);
});
});
}
async function teardown() {
return new Promise((acc, rej) => {
db.close(err => {
if (err) rej(err);
else acc();
});
});
}
async function getItems() {
return new Promise((acc, rej) => {
db.all('SELECT * FROM todo_items', (err, rows) => {
if (err) return rej(err);
acc(
rows.map(item =>
Object.assign({}, item, {
completed: item.completed === 1,
}),
),
);
});
});
}
async function getItem(id) {
return new Promise((acc, rej) => {
db.all('SELECT * FROM todo_items WHERE id=?', [id], (err, rows) => {
if (err) return rej(err);
acc(
rows.map(item =>
Object.assign({}, item, {
completed: item.completed === 1,
}),
)[0],
);
});
});
}
async function storeItem(item) {
return new Promise((acc, rej) => {
db.run(
'INSERT INTO todo_items (id, name, completed) VALUES (?, ?, ?)',
[item.id, item.name, item.completed ? 1 : 0],
err => {
if (err) return rej(err);
acc();
},
);
});
}
async function updateItem(id, item) {
return new Promise((acc, rej) => {
db.run(
'UPDATE todo_items SET name=?, completed=? WHERE id = ?',
[item.name, item.completed ? 1 : 0, id],
err => {
if (err) return rej(err);
acc();
},
);
});
}
async function removeItem(id) {
return new Promise((acc, rej) => {
db.run('DELETE FROM todo_items WHERE id = ?', [id], err => {
if (err) return rej(err);
acc();
});
});
}
module.exports = {
init,
teardown,
getItems,
getItem,
storeItem,
updateItem,
removeItem,
};
const db = require('../persistence');
const uuid = require('uuid/v4');
module.exports = async (req, res) => {
const item = {
id: uuid(),
name: req.body.name,
completed: false,
};
await db.storeItem(item);
res.send(item);
};
const db = require('../persistence');
module.exports = async (req, res) => {
await db.removeItem(req.params.id);
res.sendStatus(200);
};
const db = require('../persistence');
module.exports = async (req, res) => {
const items = await db.getItems();
res.send(items);
};
const db = require('../persistence');
module.exports = async (req, res) => {
await db.updateItem(req.params.id, {
name: req.body.name,
completed: req.body.completed,
});
const item = await db.getItem(req.params.id);
res.send(item);
};
此差异已折叠。
此差异已折叠。
body {
background-color: #f4f4f4;
margin-top: 50px;
font-family: 'Lato';
}
.item {
background-color: white;
padding: 15px;
margin-bottom: 15px;
border: transparent;
border-radius: 5px;
box-shadow: 0 0 1em #ccc;
transition: all .2s ease-in-out;
}
.item:hover {
box-shadow: 0 0 1em #aaa;
}
.item.completed {
text-decoration: line-through;
}
.toggles {
color: black;
}
.name {
padding-top: 3px;
}
.remove {
padding-left: 0;
}
button:focus {
border: 1px solid #333;
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0" />
<link rel="stylesheet" href="css/bootstrap.min.css" crossorigin="anonymous" />
<link rel="stylesheet" href="css/font-awesome/all.min.css" crossorigin="anonymous" />
<link href="https://fonts.googleapis.com/css?family=Lato&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="css/styles.css" />
<title>Todo App</title>
</head>
<body>
<div id="root"></div>
<script src="js/react.production.min.js"></script>
<script src="js/react-dom.production.min.js"></script>
<script src="js/react-bootstrap.js"></script>
<script src="js/babel.min.js"></script>
<script type="text/babel" src="js/app.js"></script>
</body>
</html>
function App() {
const { Container, Row, Col } = ReactBootstrap;
return (
<Container>
<Row>
<Col md={{ offset: 3, span: 6 }}>
<TodoListCard />
</Col>
</Row>
</Container>
);
}
function TodoListCard() {
const [items, setItems] = React.useState(null);
React.useEffect(() => {
fetch('/items')
.then(r => r.json())
.then(setItems);
}, []);
const onNewItem = React.useCallback(
newItem => {
setItems([...items, newItem]);
},
[items],
);
const onItemUpdate = React.useCallback(
item => {
const index = items.findIndex(i => i.id === item.id);
setItems([
...items.slice(0, index),
item,
...items.slice(index + 1),
]);
},
[items],
);
const onItemRemoval = React.useCallback(
item => {
const index = items.findIndex(i => i.id === item.id);
setItems([...items.slice(0, index), ...items.slice(index + 1)]);
},
[items],
);
if (items === null) return 'Loading...';
return (
<React.Fragment>
<AddItemForm onNewItem={onNewItem} />
{items.length === 0 && (
<p className="text-center">No items yet! Add one above!</p>
)}
{items.map(item => (
<ItemDisplay
item={item}
key={item.id}
onItemUpdate={onItemUpdate}
onItemRemoval={onItemRemoval}
/>
))}
</React.Fragment>
);
}
function AddItemForm({ onNewItem }) {
const { Form, InputGroup, Button } = ReactBootstrap;
const [newItem, setNewItem] = React.useState('');
const [submitting, setSubmitting] = React.useState(false);
const submitNewItem = e => {
e.preventDefault();
setSubmitting(true);
fetch('/items', {
method: 'POST',
body: JSON.stringify({ name: newItem }),
headers: { 'Content-Type': 'application/json' },
})
.then(r => r.json())
.then(item => {
onNewItem(item);
setSubmitting(false);
setNewItem('');
});
};
return (
<Form onSubmit={submitNewItem}>
<InputGroup className="mb-3">
<Form.Control
value={newItem}
onChange={e => setNewItem(e.target.value)}
type="text"
placeholder="New Item"
aria-describedby="basic-addon1"
/>
<InputGroup.Append>
<Button
type="submit"
variant="success"
disabled={!newItem.length}
className={submitting ? 'disabled' : ''}
>
{submitting ? 'Adding...' : 'Add Item'}
</Button>
</InputGroup.Append>
</InputGroup>
</Form>
);
}
function ItemDisplay({ item, onItemUpdate, onItemRemoval }) {
const { Container, Row, Col, Button } = ReactBootstrap;
const toggleCompletion = () => {
fetch(`/items/${item.id}`, {
method: 'PUT',
body: JSON.stringify({
name: item.name,
completed: !item.completed,
}),
headers: { 'Content-Type': 'application/json' },
})
.then(r => r.json())
.then(onItemUpdate);
};
const removeItem = () => {
fetch(`/items/${item.id}`, { method: 'DELETE' }).then(() =>
onItemRemoval(item),
);
};
return (
<Container fluid className={`item ${item.completed && 'completed'}`}>
<Row>
<Col xs={1} className="text-center">
<Button
className="toggles"
size="sm"
variant="link"
onClick={toggleCompletion}
aria-label={
item.completed
? 'Mark item as incomplete'
: 'Mark item as complete'
}
>
<i
className={`far ${
item.completed ? 'fa-check-square' : 'fa-square'
}`}
/>
</Button>
</Col>
<Col xs={10} className="name">
{item.name}
</Col>
<Col xs={1} className="text-center remove">
<Button
size="sm"
variant="link"
onClick={removeItem}
aria-label="Remove Item"
>
<i className="fa fa-trash text-danger" />
</Button>
</Col>
</Row>
</Container>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
此差异已折叠。
此差异已折叠。
此差异已折叠。
/** @license React v16.8.6
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';(function(N,q){"object"===typeof exports&&"undefined"!==typeof module?module.exports=q():"function"===typeof define&&define.amd?define(q):N.React=q()})(this,function(){function N(a,b,d,g,p,c,e,h){if(!a){a=void 0;if(void 0===b)a=Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var n=[d,g,p,c,e,h],f=0;a=Error(b.replace(/%s/g,function(){return n[f++]}));a.name="Invariant Violation"}a.framesToPop=1;
throw a;}}function q(a){for(var b=arguments.length-1,d="https://reactjs.org/docs/error-decoder.html?invariant="+a,g=0;g<b;g++)d+="&args[]="+encodeURIComponent(arguments[g+1]);N(!1,"Minified React error #"+a+"; visit %s for the full message or use the non-minified dev environment for full errors and additional helpful warnings. ",d)}function t(a,b,d){this.props=a;this.context=b;this.refs=ba;this.updater=d||ca}function da(){}function O(a,b,d){this.props=a;this.context=b;this.refs=ba;this.updater=d||
ca}function u(){if(!x){var a=c.expirationTime;C?P():C=!0;D(ta,a)}}function Q(){var a=c,b=c.next;if(c===b)c=null;else{var d=c.previous;c=d.next=b;b.previous=d}a.next=a.previous=null;d=a.callback;b=a.expirationTime;a=a.priorityLevel;var g=f,p=E;f=a;E=b;try{var n=d()}finally{f=g,E=p}if("function"===typeof n)if(n={callback:n,priorityLevel:a,expirationTime:b,next:null,previous:null},null===c)c=n.next=n.previous=n;else{d=null;a=c;do{if(a.expirationTime>=b){d=a;break}a=a.next}while(a!==c);null===d?d=c:d===
c&&(c=n,u());b=d.previous;b.next=d.previous=n;n.next=d;n.previous=b}}function F(){if(-1===k&&null!==c&&1===c.priorityLevel){x=!0;try{do Q();while(null!==c&&1===c.priorityLevel)}finally{x=!1,null!==c?u():C=!1}}}function ta(a){x=!0;var b=G;G=a;try{if(a)for(;null!==c;){var d=l();if(c.expirationTime<=d){do Q();while(null!==c&&c.expirationTime<=d)}else break}else if(null!==c){do Q();while(null!==c&&!H())}}finally{x=!1,G=b,null!==c?u():C=!1,F()}}function ea(a,b,d){var g=void 0,p={},c=null,e=null;if(null!=
b)for(g in void 0!==b.ref&&(e=b.ref),void 0!==b.key&&(c=""+b.key),b)fa.call(b,g)&&!ha.hasOwnProperty(g)&&(p[g]=b[g]);var h=arguments.length-2;if(1===h)p.children=d;else if(1<h){for(var f=Array(h),k=0;k<h;k++)f[k]=arguments[k+2];p.children=f}if(a&&a.defaultProps)for(g in h=a.defaultProps,h)void 0===p[g]&&(p[g]=h[g]);return{$$typeof:y,type:a,key:c,ref:e,props:p,_owner:R.current}}function ua(a,b){return{$$typeof:y,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function S(a){return"object"===
typeof a&&null!==a&&a.$$typeof===y}function va(a){var b={"=":"=0",":":"=2"};return"$"+(""+a).replace(/[=:]/g,function(a){return b[a]})}function ia(a,b,d,g){if(I.length){var c=I.pop();c.result=a;c.keyPrefix=b;c.func=d;c.context=g;c.count=0;return c}return{result:a,keyPrefix:b,func:d,context:g,count:0}}function ja(a){a.result=null;a.keyPrefix=null;a.func=null;a.context=null;a.count=0;10>I.length&&I.push(a)}function T(a,b,d,g){var c=typeof a;if("undefined"===c||"boolean"===c)a=null;var e=!1;if(null===
a)e=!0;else switch(c){case "string":case "number":e=!0;break;case "object":switch(a.$$typeof){case y:case wa:e=!0}}if(e)return d(g,a,""===b?"."+U(a,0):b),1;e=0;b=""===b?".":b+":";if(Array.isArray(a))for(var f=0;f<a.length;f++){c=a[f];var h=b+U(c,f);e+=T(c,h,d,g)}else if(null===a||"object"!==typeof a?h=null:(h=ka&&a[ka]||a["@@iterator"],h="function"===typeof h?h:null),"function"===typeof h)for(a=h.call(a),f=0;!(c=a.next()).done;)c=c.value,h=b+U(c,f++),e+=T(c,h,d,g);else"object"===c&&(d=""+a,q("31",
"[object Object]"===d?"object with keys {"+Object.keys(a).join(", ")+"}":d,""));return e}function V(a,b,d){return null==a?0:T(a,"",b,d)}function U(a,b){return"object"===typeof a&&null!==a&&null!=a.key?va(a.key):b.toString(36)}function xa(a,b,d){a.func.call(a.context,b,a.count++)}function ya(a,b,d){var g=a.result,c=a.keyPrefix;a=a.func.call(a.context,b,a.count++);Array.isArray(a)?W(a,g,d,function(a){return a}):null!=a&&(S(a)&&(a=ua(a,c+(!a.key||b&&b.key===a.key?"":(""+a.key).replace(la,"$&/")+"/")+
d)),g.push(a))}function W(a,b,d,g,c){var e="";null!=d&&(e=(""+d).replace(la,"$&/")+"/");b=ia(b,e,g,c);V(a,ya,b);ja(b)}function m(){var a=ma.current;null===a?q("321"):void 0;return a}var e="function"===typeof Symbol&&Symbol.for,y=e?Symbol.for("react.element"):60103,wa=e?Symbol.for("react.portal"):60106,r=e?Symbol.for("react.fragment"):60107,X=e?Symbol.for("react.strict_mode"):60108,za=e?Symbol.for("react.profiler"):60114,Aa=e?Symbol.for("react.provider"):60109,Ba=e?Symbol.for("react.context"):60110,
Ca=e?Symbol.for("react.concurrent_mode"):60111,Da=e?Symbol.for("react.forward_ref"):60112,Ea=e?Symbol.for("react.suspense"):60113,Fa=e?Symbol.for("react.memo"):60115,Ga=e?Symbol.for("react.lazy"):60116,ka="function"===typeof Symbol&&Symbol.iterator,na=Object.getOwnPropertySymbols,Ha=Object.prototype.hasOwnProperty,Ia=Object.prototype.propertyIsEnumerable,J=function(){try{if(!Object.assign)return!1;var a=new String("abc");a[5]="de";if("5"===Object.getOwnPropertyNames(a)[0])return!1;var b={};for(a=
0;10>a;a++)b["_"+String.fromCharCode(a)]=a;if("0123456789"!==Object.getOwnPropertyNames(b).map(function(a){return b[a]}).join(""))return!1;var d={};"abcdefghijklmnopqrst".split("").forEach(function(a){d[a]=a});return"abcdefghijklmnopqrst"!==Object.keys(Object.assign({},d)).join("")?!1:!0}catch(g){return!1}}()?Object.assign:function(a,b){if(null===a||void 0===a)throw new TypeError("Object.assign cannot be called with null or undefined");var d=Object(a);for(var c,e=1;e<arguments.length;e++){var f=Object(arguments[e]);
for(var k in f)Ha.call(f,k)&&(d[k]=f[k]);if(na){c=na(f);for(var h=0;h<c.length;h++)Ia.call(f,c[h])&&(d[c[h]]=f[c[h]])}}return d},ca={isMounted:function(a){return!1},enqueueForceUpdate:function(a,b,d){},enqueueReplaceState:function(a,b,d,c){},enqueueSetState:function(a,b,d,c){}},ba={};t.prototype.isReactComponent={};t.prototype.setState=function(a,b){"object"!==typeof a&&"function"!==typeof a&&null!=a?q("85"):void 0;this.updater.enqueueSetState(this,a,b,"setState")};t.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,
a,"forceUpdate")};da.prototype=t.prototype;e=O.prototype=new da;e.constructor=O;J(e,t.prototype);e.isPureReactComponent=!0;var c=null,G=!1,f=3,k=-1,E=-1,x=!1,C=!1,Ja=Date,Ka="function"===typeof setTimeout?setTimeout:void 0,La="function"===typeof clearTimeout?clearTimeout:void 0,oa="function"===typeof requestAnimationFrame?requestAnimationFrame:void 0,pa="function"===typeof cancelAnimationFrame?cancelAnimationFrame:void 0,qa,ra,Y=function(a){qa=oa(function(b){La(ra);a(b)});ra=Ka(function(){pa(qa);
a(l())},100)};if("object"===typeof performance&&"function"===typeof performance.now){var Ma=performance;var l=function(){return Ma.now()}}else l=function(){return Ja.now()};e=null;"undefined"!==typeof window?e=window:"undefined"!==typeof global&&(e=global);if(e&&e._schedMock){e=e._schedMock;var D=e[0];var P=e[1];var H=e[2];l=e[3]}else if("undefined"===typeof window||"function"!==typeof MessageChannel){var v=null,Na=function(a){if(null!==v)try{v(a)}finally{v=null}};D=function(a,b){null!==v?setTimeout(D,
0,a):(v=a,setTimeout(Na,0,!1))};P=function(){v=null};H=function(){return!1}}else{"undefined"!==typeof console&&("function"!==typeof oa&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!==typeof pa&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"));var w=null,K=!1,z=-1,A=!1,Z=!1,L=0,
M=33,B=33;H=function(){return L<=l()};e=new MessageChannel;var sa=e.port2;e.port1.onmessage=function(a){K=!1;a=w;var b=z;w=null;z=-1;var d=l(),c=!1;if(0>=L-d)if(-1!==b&&b<=d)c=!0;else{A||(A=!0,Y(aa));w=a;z=b;return}if(null!==a){Z=!0;try{a(c)}finally{Z=!1}}};var aa=function(a){if(null!==w){Y(aa);var b=a-L+B;b<B&&M<B?(8>b&&(b=8),B=b<M?M:b):M=b;L=a+B;K||(K=!0,sa.postMessage(void 0))}else A=!1};D=function(a,b){w=a;z=b;Z||0>b?sa.postMessage(void 0):A||(A=!0,Y(aa))};P=function(){w=null;K=!1;z=-1}}var Oa=
0,ma={current:null},R={current:null};e={ReactCurrentDispatcher:ma,ReactCurrentOwner:R,assign:J};J(e,{Scheduler:{unstable_cancelCallback:function(a){var b=a.next;if(null!==b){if(b===a)c=null;else{a===c&&(c=b);var d=a.previous;d.next=b;b.previous=d}a.next=a.previous=null}},unstable_shouldYield:function(){return!G&&(null!==c&&c.expirationTime<E||H())},unstable_now:l,unstable_scheduleCallback:function(a,b){var d=-1!==k?k:l();if("object"===typeof b&&null!==b&&"number"===typeof b.timeout)b=d+b.timeout;
else switch(f){case 1:b=d+-1;break;case 2:b=d+250;break;case 5:b=d+1073741823;break;case 4:b=d+1E4;break;default:b=d+5E3}a={callback:a,priorityLevel:f,expirationTime:b,next:null,previous:null};if(null===c)c=a.next=a.previous=a,u();else{d=null;var g=c;do{if(g.expirationTime>b){d=g;break}g=g.next}while(g!==c);null===d?d=c:d===c&&(c=a,u());b=d.previous;b.next=d.previous=a;a.next=d;a.previous=b}return a},unstable_runWithPriority:function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=
3}var d=f,c=k;f=a;k=l();try{return b()}finally{f=d,k=c,F()}},unstable_next:function(a){switch(f){case 1:case 2:case 3:var b=3;break;default:b=f}var d=f,c=k;f=b;k=l();try{return a()}finally{f=d,k=c,F()}},unstable_wrapCallback:function(a){var b=f;return function(){var d=f,c=k;f=b;k=l();try{return a.apply(this,arguments)}finally{f=d,k=c,F()}}},unstable_getFirstCallbackNode:function(){return c},unstable_pauseExecution:function(){},unstable_continueExecution:function(){null!==c&&u()},unstable_getCurrentPriorityLevel:function(){return f},
unstable_IdlePriority:5,unstable_ImmediatePriority:1,unstable_LowPriority:4,unstable_NormalPriority:3,unstable_UserBlockingPriority:2},SchedulerTracing:{__interactionsRef:null,__subscriberRef:null,unstable_clear:function(a){return a()},unstable_getCurrent:function(){return null},unstable_getThreadID:function(){return++Oa},unstable_subscribe:function(a){},unstable_trace:function(a,b,d){return d()},unstable_unsubscribe:function(a){},unstable_wrap:function(a){return a}}});var fa=Object.prototype.hasOwnProperty,
ha={key:!0,ref:!0,__self:!0,__source:!0},la=/\/+/g,I=[];r={Children:{map:function(a,b,d){if(null==a)return a;var c=[];W(a,c,null,b,d);return c},forEach:function(a,b,d){if(null==a)return a;b=ia(null,null,b,d);V(a,xa,b);ja(b)},count:function(a){return V(a,function(){return null},null)},toArray:function(a){var b=[];W(a,b,null,function(a){return a});return b},only:function(a){S(a)?void 0:q("143");return a}},createRef:function(){return{current:null}},Component:t,PureComponent:O,createContext:function(a,
b){void 0===b&&(b=null);a={$$typeof:Ba,_calculateChangedBits:b,_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null};a.Provider={$$typeof:Aa,_context:a};return a.Consumer=a},forwardRef:function(a){return{$$typeof:Da,render:a}},lazy:function(a){return{$$typeof:Ga,_ctor:a,_status:-1,_result:null}},memo:function(a,b){return{$$typeof:Fa,type:a,compare:void 0===b?null:b}},useCallback:function(a,b){return m().useCallback(a,b)},useContext:function(a,b){return m().useContext(a,b)},
useEffect:function(a,b){return m().useEffect(a,b)},useImperativeHandle:function(a,b,d){return m().useImperativeHandle(a,b,d)},useDebugValue:function(a,b){},useLayoutEffect:function(a,b){return m().useLayoutEffect(a,b)},useMemo:function(a,b){return m().useMemo(a,b)},useReducer:function(a,b,d){return m().useReducer(a,b,d)},useRef:function(a){return m().useRef(a)},useState:function(a){return m().useState(a)},Fragment:r,StrictMode:X,Suspense:Ea,createElement:ea,cloneElement:function(a,b,d){null===a||
void 0===a?q("267",a):void 0;var c=void 0,e=J({},a.props),f=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=R.current);void 0!==b.key&&(f=""+b.key);var l=void 0;a.type&&a.type.defaultProps&&(l=a.type.defaultProps);for(c in b)fa.call(b,c)&&!ha.hasOwnProperty(c)&&(e[c]=void 0===b[c]&&void 0!==l?l[c]:b[c])}c=arguments.length-2;if(1===c)e.children=d;else if(1<c){l=Array(c);for(var m=0;m<c;m++)l[m]=arguments[m+2];e.children=l}return{$$typeof:y,type:a.type,key:f,ref:k,props:e,_owner:h}},
createFactory:function(a){var b=ea.bind(null,a);b.type=a;return b},isValidElement:S,version:"16.8.6",unstable_ConcurrentMode:Ca,unstable_Profiler:za,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:e};r=(X={default:r},r)||X;return r.default||r});
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册