├── .gitignore ├── README.md ├── node-server ├── README.md ├── app.js ├── package.json ├── stream_read_write.js ├── utils.js └── yarn.lock ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── src ├── App.js ├── App.test.js ├── components │ ├── PDF │ │ ├── index.js │ │ └── style.css │ ├── PDFViewer │ │ ├── images │ │ │ └── shadow.png │ │ ├── index.js │ │ ├── style.css │ │ └── utils.js │ ├── Upload │ │ ├── index.js │ │ └── style.css │ ├── VirtualizedPdf │ │ ├── index.js │ │ └── style.css │ └── index.js ├── demo.pdf ├── index.css ├── index.js ├── logo.svg ├── pages │ ├── other │ │ └── index.js │ └── uploadFile │ │ ├── index.js │ │ └── style.css ├── serviceWorker.js └── setupTests.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | /node-server/node_modules/ 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > 使用 PDF.js 在 react页面渲染 pdf 文件,不使用官方提供的viewe.html 工具,实现简单的工具栏操作 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## 文件说明 6 | 7 | > 本项目原来是为了PDF预览的几种方式创建,后来又添加了大文件分片上传的服务,让整个项目更加灵活 8 | 9 | - App.js 10 | 11 | ```react 12 | import React from 'react' 13 | // 通过修改引入pages的文件不同显示不同的界面 14 | // uploadFile 上传文件服务的客户端 15 | // other PDF 预览页面 16 | import Other from './pages/other' 17 | 18 | const Index = props => { 19 | return 20 | } 21 | 22 | export default Index; 23 | ``` 24 | 25 | - other/index.js 26 | 27 | ```react 28 | import React from 'react' 29 | // 引入不同的组件 30 | import { PDFViewer } from '../../components' 31 | 32 | const url = 'http://127.0.0.1:9002/demo.pdf' 33 | 34 | const Index = props => { 35 | return (
36 | 37 |
) 38 | } 39 | 40 | export default Index; 41 | ``` 42 | 43 | - components/index.js 44 | 45 | > components 是项目的组件目录 46 | > 47 | > - PDF 正常的PDF预览方式 实现功能有翻页,缩放 48 | > - PDFViewer 使用pdf.js 推荐的方式实现预览,实现功能有 翻页 缩放 文字查找高亮显示 49 | > - Upload 文件上传的组件 50 | > - VirtualizedPdf 使用react-virtualized实现大文件预览,其实PDFViewer也支持大文件预览 51 | 52 | ## 如何使用 53 | 54 | ``` 55 | git clone https://github.com/LiuSandy/react-pdf-render.git 56 | cd react-pdf-render 57 | npm install / yarn install 58 | npm start / yarn start 59 | ``` 60 | 61 | ## Learn More 62 | 63 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 64 | 65 | To learn React, check out the [React documentation](https://reactjs.org/). 66 | 67 | ### Code Splitting 68 | 69 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 70 | 71 | ### Analyzing the Bundle Size 72 | 73 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 74 | 75 | ### Making a Progressive Web App 76 | 77 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 78 | 79 | ### Advanced Configuration 80 | 81 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 82 | 83 | ### Deployment 84 | 85 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 86 | 87 | ### `yarn build` fails to minify 88 | 89 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 90 | -------------------------------------------------------------------------------- /node-server/README.md: -------------------------------------------------------------------------------- 1 | > 文件上传服务,使用 node + koa2 实现大文件的分片上传功能,**有待完善** 2 | 3 | ## 如何使用 4 | 5 | - 服务代码 6 | 7 | ``` 8 | # 下载代码 9 | git clone https://github.com/LiuSandy/react-pdf-render 10 | # 进入文件使用 11 | cd react-pdf-render/node-serve 12 | # 安装依赖 13 | npm install / yarn install 14 | # 运行项目 15 | node app.js 16 | ``` 17 | 18 | - 客户端启动 19 | 20 | > 在他的父级文件夹说明 -------------------------------------------------------------------------------- /node-server/app.js: -------------------------------------------------------------------------------- 1 | const Koa = require("koa"); 2 | const cors = require("koa2-cors"); 3 | // const bodyParser = require("koa-bodyparser"); 4 | const KoaBody = require('koa-body') 5 | const Router = require("koa-router"); 6 | const stdout = require("shancw-stdout"); 7 | const fs = require('fs') 8 | const { renameFile, mergeChunkFile } = require('./utils') 9 | const path = require('path') 10 | const PORT = 5000; 11 | const server = new Koa(); 12 | const router = new Router() 13 | 14 | const uploadChunkPath = path.resolve(__dirname, './data') 15 | 16 | if (!fs.existsSync(uploadChunkPath)) { 17 | fs.mkdirSync(uploadChunkPath) 18 | } 19 | 20 | server.listen(PORT, () => { 21 | stdout.bgGreen(`server start at port:${PORT}`); 22 | }); 23 | 24 | router.post('/upload', ctx => { 25 | if (ctx.request.body.type === 'merge') { 26 | try { 27 | const { token, chunkCount, fileName } = ctx.request.body 28 | mergeChunkFile(fileName, uploadChunkPath, chunkCount, token, './data') 29 | ctx.body = 'ok' 30 | } catch (e) { 31 | ctx.body = "merge fail" 32 | } 33 | } else if (ctx.request.body.type === 'upload') { 34 | try { 35 | const { index, token, name } = ctx.request.body 36 | const chunkFile = ctx.request.files.chunk 37 | const chunkName = chunkFile.path.split('/').pop() 38 | renameFile(uploadChunkPath, chunkName, `${name}-${index}-${token}`) 39 | ctx.body = 'upload chunk success' 40 | } catch (e) { 41 | ctx.body = 'upload chunk fail' 42 | } 43 | } else { 44 | ctx.body = "unkown type" 45 | } 46 | }) 47 | 48 | server 49 | .use(cors()) 50 | .use(KoaBody({ 51 | multipart: true, // 支持文件上传 52 | formidable: { 53 | //设置文件的默认保存目录,不设置则保存在系统临时目录下 os 54 | uploadDir: uploadChunkPath 55 | }, 56 | })) 57 | .use(router.allowedMethods()) 58 | .use(router.routes()) -------------------------------------------------------------------------------- /node-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "node 服务端demo", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "lius", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.17.1", 13 | "fs-extra": "^9.0.0", 14 | "global": "^4.4.0", 15 | "hotnode": "^0.0.8", 16 | "koa": "^2.11.0", 17 | "koa-body": "^4.1.1", 18 | "koa-router": "^8.0.8", 19 | "koa2-cors": "^2.0.6", 20 | "moment": "^2.24.0", 21 | "multer": "^1.4.2", 22 | "multiparty": "^4.2.1", 23 | "nodemon": "^2.0.3", 24 | "shancw-stdout": "^1.0.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /node-server/stream_read_write.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | /** 5 | * 6 | * @param {String} fileName 生成文件的文件名 7 | * @param {String} chunkPath 缓存目录的路径 8 | * @param {String} fileToken 文件的token 9 | * @param {String} dataDir 可选,生成文件的相对路径 10 | */ 11 | const mergeChunkFile = (fileName,chunkPath,chunkCount,fileToken,dataDir="")=>{ 12 | //如果chunkPath 不存在 则直接结束 13 | if(!fs.existsSync(path.resolve(__dirname,chunkPath))) return _=>console.log('chunkDir is not exist') 14 | 15 | const dataPath = path.resolve(__dirname, dataDir+'/'+fileName); 16 | let writeStream = fs.createWriteStream(dataPath); 17 | let mergedChunkNum = 0 18 | return function mergeCore(){ 19 | if (mergedChunkNum > chunkCount) { 20 | //删除chunkDir 21 | fs.rmdirSync(path.resolve(__dirname,chunkPath)) 22 | return 23 | }; 24 | //创建chunk readStream 25 | const curChunk = path.resolve( 26 | __dirname, 27 | `${chunkPath}/${fileName}-${mergedChunkNum}-${fileToken}` 28 | ); 29 | const curChunkReadStream = fs.createReadStream(curChunk); 30 | //将readStream 写入 writeStream 31 | curChunkReadStream.pipe(writeStream, { end: false }); //end = false 则可以连续给writeStream 写数据 32 | curChunkReadStream.on("end", () => { 33 | //readStream 传输结束 则 递归 进行下一个文件流的读写操作 34 | console.log(curChunk) 35 | fs.unlinkSync(curChunk) //删除chunkFile 36 | mergedChunkNum += 1 37 | mergeCore(); 38 | }); 39 | 40 | } 41 | } 42 | 43 | const mergeUserTxt = mergeChunkFile('shancw.txt','./data/chunkList',5,'xx','./data') -------------------------------------------------------------------------------- /node-server/utils.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const fs = require('fs') 3 | function renameFile(dir, oldName, newName) { 4 | const oldPath = path.resolve(dir, oldName) 5 | const newPath = path.resolve(dir, newName) 6 | fs.renameSync(oldPath, newPath) 7 | } 8 | /** 9 | * 10 | * @param {String} fileName 生成文件的文件名 11 | * @param {String} chunkPath 缓存目录的路径 12 | * @param {String} fileToken 文件的token 13 | * @param {String} dataDir 可选,生成文件的相对路径 14 | * @returns {Boolean} 15 | */ 16 | const mergeChunkFile = (fileName, chunkPath, chunkCount, fileToken, dataDir = "./") => { 17 | //如果chunkPath 不存在 则直接结束` 18 | if (!fs.existsSync(chunkPath)) return false 19 | const dataPath = path.join(__dirname, dataDir, fileName); 20 | let writeStream = fs.createWriteStream(dataPath); 21 | let mergedChunkNum = 0 22 | 23 | return mergeCore() 24 | 25 | function mergeCore() { 26 | if (mergedChunkNum >= chunkCount) { 27 | return true 28 | }; 29 | const curChunk = path.resolve(chunkPath, `${fileName}-${mergedChunkNum}-${fileToken}`) 30 | const curChunkReadStream = fs.createReadStream(curChunk); 31 | //将readStream 写入 writeStream 32 | curChunkReadStream.pipe(writeStream, { end: false }); //end = false 则可以连续给writeStream 写数据 33 | curChunkReadStream.on("end", () => { 34 | //readStream 传输结束 则 递归 进行下一个文件流的读写操作 35 | fs.unlinkSync(curChunk) //删除chunkFile 36 | mergedChunkNum += 1 37 | mergeCore(); 38 | }); 39 | curChunkReadStream.on('error', () => { 40 | return false 41 | }) 42 | 43 | } 44 | } 45 | 46 | 47 | module.exports = { renameFile, mergeChunkFile } -------------------------------------------------------------------------------- /node-server/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@sindresorhus/is@^0.14.0": 6 | version "0.14.0" 7 | resolved "https://registry.npm.taobao.org/@sindresorhus/is/download/@sindresorhus/is-0.14.0.tgz?cache=0&sync_timestamp=1581924347665&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40sindresorhus%2Fis%2Fdownload%2F%40sindresorhus%2Fis-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" 8 | integrity sha1-n7OjzzEyMoFR81PeRjLgHlIQK+o= 9 | 10 | "@szmarczak/http-timer@^1.1.2": 11 | version "1.1.2" 12 | resolved "https://registry.npm.taobao.org/@szmarczak/http-timer/download/@szmarczak/http-timer-1.1.2.tgz?cache=0&sync_timestamp=1580758852337&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40szmarczak%2Fhttp-timer%2Fdownload%2F%40szmarczak%2Fhttp-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" 13 | integrity sha1-sWZeLEYaLNkvTBu/UNVFTeDUtCE= 14 | dependencies: 15 | defer-to-connect "^1.0.1" 16 | 17 | "@types/color-name@^1.1.1": 18 | version "1.1.1" 19 | resolved "https://registry.npm.taobao.org/@types/color-name/download/@types/color-name-1.1.1.tgz?cache=0&sync_timestamp=1580841712213&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcolor-name%2Fdownload%2F%40types%2Fcolor-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" 20 | integrity sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA= 21 | 22 | "@types/events@*": 23 | version "3.0.0" 24 | resolved "https://registry.npm.taobao.org/@types/events/download/@types/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" 25 | integrity sha1-KGLz9Yqaf3w+eNefEw3U1xwlwqc= 26 | 27 | "@types/formidable@^1.0.31": 28 | version "1.0.31" 29 | resolved "https://registry.npm.taobao.org/@types/formidable/download/@types/formidable-1.0.31.tgz#274f9dc2d0a1a9ce1feef48c24ca0859e7ec947b" 30 | integrity sha1-J0+dwtChqc4f7vSMJMoIWefslHs= 31 | dependencies: 32 | "@types/events" "*" 33 | "@types/node" "*" 34 | 35 | "@types/node@*": 36 | version "13.11.1" 37 | resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7" 38 | integrity sha1-SaKoPfnSbarOrTDQzMh2KxKNU8c= 39 | 40 | abbrev@1: 41 | version "1.1.1" 42 | resolved "https://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 43 | integrity sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg= 44 | 45 | accepts@^1.3.5, accepts@~1.3.7: 46 | version "1.3.7" 47 | resolved "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" 48 | integrity sha1-UxvHJlF6OytB+FACHGzBXqq1B80= 49 | dependencies: 50 | mime-types "~2.1.24" 51 | negotiator "0.6.2" 52 | 53 | ansi-align@^3.0.0: 54 | version "3.0.0" 55 | resolved "https://registry.npm.taobao.org/ansi-align/download/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" 56 | integrity sha1-tTazcc9ofKrvI2wY0+If43l0Z8s= 57 | dependencies: 58 | string-width "^3.0.0" 59 | 60 | ansi-regex@^4.1.0: 61 | version "4.1.0" 62 | resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" 63 | integrity sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc= 64 | 65 | ansi-regex@^5.0.0: 66 | version "5.0.0" 67 | resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" 68 | integrity sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U= 69 | 70 | ansi-styles@^4.1.0: 71 | version "4.2.1" 72 | resolved "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" 73 | integrity sha1-kK51xCTQCNJiTFvynq0xd+v881k= 74 | dependencies: 75 | "@types/color-name" "^1.1.1" 76 | color-convert "^2.0.1" 77 | 78 | any-promise@^1.1.0: 79 | version "1.3.0" 80 | resolved "https://registry.npm.taobao.org/any-promise/download/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" 81 | integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= 82 | 83 | anymatch@~3.1.1: 84 | version "3.1.1" 85 | resolved "https://registry.npm.taobao.org/anymatch/download/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" 86 | integrity sha1-xV7PAhheJGklk5kxDBc84xIzsUI= 87 | dependencies: 88 | normalize-path "^3.0.0" 89 | picomatch "^2.0.4" 90 | 91 | append-field@^1.0.0: 92 | version "1.0.0" 93 | resolved "https://registry.npm.taobao.org/append-field/download/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" 94 | integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY= 95 | 96 | array-flatten@1.1.1: 97 | version "1.1.1" 98 | resolved "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz?cache=0&sync_timestamp=1574313293899&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 99 | integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= 100 | 101 | at-least-node@^1.0.0: 102 | version "1.0.0" 103 | resolved "https://registry.npm.taobao.org/at-least-node/download/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" 104 | integrity sha1-YCzUtG6EStTv/JKoARo8RuAjjcI= 105 | 106 | balanced-match@^1.0.0: 107 | version "1.0.0" 108 | resolved "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 109 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 110 | 111 | binary-extensions@^2.0.0: 112 | version "2.0.0" 113 | resolved "https://registry.npm.taobao.org/binary-extensions/download/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" 114 | integrity sha1-I8DfFPaogHf1+YbA0WfsA8PVU3w= 115 | 116 | body-parser@1.19.0: 117 | version "1.19.0" 118 | resolved "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 119 | integrity sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io= 120 | dependencies: 121 | bytes "3.1.0" 122 | content-type "~1.0.4" 123 | debug "2.6.9" 124 | depd "~1.1.2" 125 | http-errors "1.7.2" 126 | iconv-lite "0.4.24" 127 | on-finished "~2.3.0" 128 | qs "6.7.0" 129 | raw-body "2.4.0" 130 | type-is "~1.6.17" 131 | 132 | boxen@^4.2.0: 133 | version "4.2.0" 134 | resolved "https://registry.npm.taobao.org/boxen/download/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" 135 | integrity sha1-5BG2I1fW1tNlh8isPV2XTaoHDmQ= 136 | dependencies: 137 | ansi-align "^3.0.0" 138 | camelcase "^5.3.1" 139 | chalk "^3.0.0" 140 | cli-boxes "^2.2.0" 141 | string-width "^4.1.0" 142 | term-size "^2.1.0" 143 | type-fest "^0.8.1" 144 | widest-line "^3.1.0" 145 | 146 | brace-expansion@^1.1.7: 147 | version "1.1.11" 148 | resolved "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 149 | integrity sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0= 150 | dependencies: 151 | balanced-match "^1.0.0" 152 | concat-map "0.0.1" 153 | 154 | braces@~3.0.2: 155 | version "3.0.2" 156 | resolved "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 157 | integrity sha1-NFThpGLujVmeI23zNs2epPiv4Qc= 158 | dependencies: 159 | fill-range "^7.0.1" 160 | 161 | buffer-from@^1.0.0: 162 | version "1.1.1" 163 | resolved "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 164 | integrity sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8= 165 | 166 | busboy@^0.2.11: 167 | version "0.2.14" 168 | resolved "https://registry.npm.taobao.org/busboy/download/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" 169 | integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= 170 | dependencies: 171 | dicer "0.2.5" 172 | readable-stream "1.1.x" 173 | 174 | bytes@3.1.0: 175 | version "3.1.0" 176 | resolved "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" 177 | integrity sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY= 178 | 179 | cache-content-type@^1.0.0: 180 | version "1.0.1" 181 | resolved "https://registry.npm.taobao.org/cache-content-type/download/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" 182 | integrity sha1-A1zeKwjuISn0qDFeqPAKANuhRTw= 183 | dependencies: 184 | mime-types "^2.1.18" 185 | ylru "^1.2.0" 186 | 187 | cacheable-request@^6.0.0: 188 | version "6.1.0" 189 | resolved "https://registry.npm.taobao.org/cacheable-request/download/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" 190 | integrity sha1-IP+4vRYrpL4R6VZ9gj22UQUsqRI= 191 | dependencies: 192 | clone-response "^1.0.2" 193 | get-stream "^5.1.0" 194 | http-cache-semantics "^4.0.0" 195 | keyv "^3.0.0" 196 | lowercase-keys "^2.0.0" 197 | normalize-url "^4.1.0" 198 | responselike "^1.0.2" 199 | 200 | camelcase@^5.3.1: 201 | version "5.3.1" 202 | resolved "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz?cache=0&sync_timestamp=1586229901005&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 203 | integrity sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA= 204 | 205 | chalk@^3.0.0: 206 | version "3.0.0" 207 | resolved "https://registry.npm.taobao.org/chalk/download/chalk-3.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" 208 | integrity sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ= 209 | dependencies: 210 | ansi-styles "^4.1.0" 211 | supports-color "^7.1.0" 212 | 213 | chokidar@^3.2.2: 214 | version "3.3.1" 215 | resolved "https://registry.npm.taobao.org/chokidar/download/chokidar-3.3.1.tgz?cache=0&sync_timestamp=1584609518131&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" 216 | integrity sha1-yE5bPRjZpNd1WP70ZrG/FrvrNFA= 217 | dependencies: 218 | anymatch "~3.1.1" 219 | braces "~3.0.2" 220 | glob-parent "~5.1.0" 221 | is-binary-path "~2.1.0" 222 | is-glob "~4.0.1" 223 | normalize-path "~3.0.0" 224 | readdirp "~3.3.0" 225 | optionalDependencies: 226 | fsevents "~2.1.2" 227 | 228 | ci-info@^2.0.0: 229 | version "2.0.0" 230 | resolved "https://registry.npm.taobao.org/ci-info/download/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" 231 | integrity sha1-Z6npZL4xpR4V5QENWObxKDQAL0Y= 232 | 233 | cli-boxes@^2.2.0: 234 | version "2.2.0" 235 | resolved "https://registry.npm.taobao.org/cli-boxes/download/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d" 236 | integrity sha1-U47K6PnGylCOPDyVtFP+k8tMFo0= 237 | 238 | clone-response@^1.0.2: 239 | version "1.0.2" 240 | resolved "https://registry.npm.taobao.org/clone-response/download/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" 241 | integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= 242 | dependencies: 243 | mimic-response "^1.0.0" 244 | 245 | co-body@^5.1.1: 246 | version "5.2.0" 247 | resolved "https://registry.npm.taobao.org/co-body/download/co-body-5.2.0.tgz#5a0a658c46029131e0e3a306f67647302f71c124" 248 | integrity sha1-WgpljEYCkTHg46MG9nZHMC9xwSQ= 249 | dependencies: 250 | inflation "^2.0.0" 251 | qs "^6.4.0" 252 | raw-body "^2.2.0" 253 | type-is "^1.6.14" 254 | 255 | co@^4.6.0: 256 | version "4.6.0" 257 | resolved "https://registry.npm.taobao.org/co/download/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" 258 | integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= 259 | 260 | color-convert@^2.0.1: 261 | version "2.0.1" 262 | resolved "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 263 | integrity sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM= 264 | dependencies: 265 | color-name "~1.1.4" 266 | 267 | color-name@~1.1.4: 268 | version "1.1.4" 269 | resolved "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 270 | integrity sha1-wqCah6y95pVD3m9j+jmVyCbFNqI= 271 | 272 | concat-map@0.0.1: 273 | version "0.0.1" 274 | resolved "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 275 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 276 | 277 | concat-stream@^1.5.2: 278 | version "1.6.2" 279 | resolved "https://registry.npm.taobao.org/concat-stream/download/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" 280 | integrity sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ= 281 | dependencies: 282 | buffer-from "^1.0.0" 283 | inherits "^2.0.3" 284 | readable-stream "^2.2.2" 285 | typedarray "^0.0.6" 286 | 287 | configstore@^5.0.1: 288 | version "5.0.1" 289 | resolved "https://registry.npm.taobao.org/configstore/download/configstore-5.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconfigstore%2Fdownload%2Fconfigstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" 290 | integrity sha1-02UCG130uYzdGH1qOw4/anzF7ZY= 291 | dependencies: 292 | dot-prop "^5.2.0" 293 | graceful-fs "^4.1.2" 294 | make-dir "^3.0.0" 295 | unique-string "^2.0.0" 296 | write-file-atomic "^3.0.0" 297 | xdg-basedir "^4.0.0" 298 | 299 | content-disposition@0.5.3, content-disposition@~0.5.2: 300 | version "0.5.3" 301 | resolved "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" 302 | integrity sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70= 303 | dependencies: 304 | safe-buffer "5.1.2" 305 | 306 | content-type@^1.0.4, content-type@~1.0.4: 307 | version "1.0.4" 308 | resolved "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 309 | integrity sha1-4TjMdeBAxyexlm/l5fjJruJW/js= 310 | 311 | cookie-signature@1.0.6: 312 | version "1.0.6" 313 | resolved "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 314 | integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= 315 | 316 | cookie@0.4.0: 317 | version "0.4.0" 318 | resolved "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" 319 | integrity sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo= 320 | 321 | cookies@~0.8.0: 322 | version "0.8.0" 323 | resolved "https://registry.npm.taobao.org/cookies/download/cookies-0.8.0.tgz?cache=0&sync_timestamp=1570851324736&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcookies%2Fdownload%2Fcookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90" 324 | integrity sha1-EpPOSzkXQKhAbjyYcOgoxLVPP5A= 325 | dependencies: 326 | depd "~2.0.0" 327 | keygrip "~1.1.0" 328 | 329 | core-util-is@~1.0.0: 330 | version "1.0.2" 331 | resolved "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 332 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 333 | 334 | crypto-random-string@^2.0.0: 335 | version "2.0.0" 336 | resolved "https://registry.npm.taobao.org/crypto-random-string/download/crypto-random-string-2.0.0.tgz?cache=0&sync_timestamp=1583560595499&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcrypto-random-string%2Fdownload%2Fcrypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" 337 | integrity sha1-7yp6lm7BEIM4g2m6oC6+rSKbMNU= 338 | 339 | debug@2.6.9, debug@^2.2.0: 340 | version "2.6.9" 341 | resolved "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 342 | integrity sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8= 343 | dependencies: 344 | ms "2.0.0" 345 | 346 | debug@^3.2.6: 347 | version "3.2.6" 348 | resolved "https://registry.npm.taobao.org/debug/download/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 349 | integrity sha1-6D0X3hbYp++3cX7b5fsQE17uYps= 350 | dependencies: 351 | ms "^2.1.1" 352 | 353 | debug@^4.1.1: 354 | version "4.1.1" 355 | resolved "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" 356 | integrity sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E= 357 | dependencies: 358 | ms "^2.1.1" 359 | 360 | debug@~3.1.0: 361 | version "3.1.0" 362 | resolved "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 363 | integrity sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE= 364 | dependencies: 365 | ms "2.0.0" 366 | 367 | decompress-response@^3.3.0: 368 | version "3.3.0" 369 | resolved "https://registry.npm.taobao.org/decompress-response/download/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" 370 | integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= 371 | dependencies: 372 | mimic-response "^1.0.0" 373 | 374 | deep-equal@~1.0.1: 375 | version "1.0.1" 376 | resolved "https://registry.npm.taobao.org/deep-equal/download/deep-equal-1.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdeep-equal%2Fdownload%2Fdeep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" 377 | integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= 378 | 379 | deep-extend@^0.6.0: 380 | version "0.6.0" 381 | resolved "https://registry.npm.taobao.org/deep-extend/download/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" 382 | integrity sha1-xPp8lUBKF6nD6Mp+FTcxK3NjMKw= 383 | 384 | defer-to-connect@^1.0.1: 385 | version "1.1.3" 386 | resolved "https://registry.npm.taobao.org/defer-to-connect/download/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" 387 | integrity sha1-MxrgUMCNz3ifjIOnuB8O2U9KxZE= 388 | 389 | delegates@^1.0.0: 390 | version "1.0.0" 391 | resolved "https://registry.npm.taobao.org/delegates/download/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 392 | integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= 393 | 394 | depd@^1.1.2, depd@~1.1.2: 395 | version "1.1.2" 396 | resolved "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 397 | integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 398 | 399 | depd@~2.0.0: 400 | version "2.0.0" 401 | resolved "https://registry.npm.taobao.org/depd/download/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" 402 | integrity sha1-tpYWPMdXVg0JzyLMj60Vcbeedt8= 403 | 404 | destroy@^1.0.4, destroy@~1.0.4: 405 | version "1.0.4" 406 | resolved "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 407 | integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 408 | 409 | dicer@0.2.5: 410 | version "0.2.5" 411 | resolved "https://registry.npm.taobao.org/dicer/download/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" 412 | integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= 413 | dependencies: 414 | readable-stream "1.1.x" 415 | streamsearch "0.1.2" 416 | 417 | dom-walk@^0.1.0: 418 | version "0.1.2" 419 | resolved "https://registry.npm.taobao.org/dom-walk/download/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" 420 | integrity sha1-DFSL7wSPTR8qlySQAiNgYNqj/YQ= 421 | 422 | dot-prop@^5.2.0: 423 | version "5.2.0" 424 | resolved "https://registry.npm.taobao.org/dot-prop/download/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" 425 | integrity sha1-w07MKVVtxF8fTCJpe29JBODMT8s= 426 | dependencies: 427 | is-obj "^2.0.0" 428 | 429 | duplexer3@^0.1.4: 430 | version "0.1.4" 431 | resolved "https://registry.npm.taobao.org/duplexer3/download/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" 432 | integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= 433 | 434 | ee-first@1.1.1: 435 | version "1.1.1" 436 | resolved "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 437 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 438 | 439 | emoji-regex@^7.0.1: 440 | version "7.0.3" 441 | resolved "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" 442 | integrity sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY= 443 | 444 | emoji-regex@^8.0.0: 445 | version "8.0.0" 446 | resolved "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 447 | integrity sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc= 448 | 449 | encodeurl@^1.0.2, encodeurl@~1.0.2: 450 | version "1.0.2" 451 | resolved "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 452 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 453 | 454 | end-of-stream@^1.1.0: 455 | version "1.4.4" 456 | resolved "https://registry.npm.taobao.org/end-of-stream/download/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 457 | integrity sha1-WuZKX0UFe682JuwU2gyl5LJDHrA= 458 | dependencies: 459 | once "^1.4.0" 460 | 461 | error-inject@^1.0.0: 462 | version "1.0.0" 463 | resolved "https://registry.npm.taobao.org/error-inject/download/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" 464 | integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= 465 | 466 | escape-goat@^2.0.0: 467 | version "2.1.1" 468 | resolved "https://registry.npm.taobao.org/escape-goat/download/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" 469 | integrity sha1-Gy3HcANnbEV+x2Cy3GjttkgYhnU= 470 | 471 | escape-html@^1.0.3, escape-html@~1.0.3: 472 | version "1.0.3" 473 | resolved "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 474 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 475 | 476 | etag@~1.8.1: 477 | version "1.8.1" 478 | resolved "https://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 479 | integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= 480 | 481 | express@^4.17.1: 482 | version "4.17.1" 483 | resolved "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexpress%2Fdownload%2Fexpress-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" 484 | integrity sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ= 485 | dependencies: 486 | accepts "~1.3.7" 487 | array-flatten "1.1.1" 488 | body-parser "1.19.0" 489 | content-disposition "0.5.3" 490 | content-type "~1.0.4" 491 | cookie "0.4.0" 492 | cookie-signature "1.0.6" 493 | debug "2.6.9" 494 | depd "~1.1.2" 495 | encodeurl "~1.0.2" 496 | escape-html "~1.0.3" 497 | etag "~1.8.1" 498 | finalhandler "~1.1.2" 499 | fresh "0.5.2" 500 | merge-descriptors "1.0.1" 501 | methods "~1.1.2" 502 | on-finished "~2.3.0" 503 | parseurl "~1.3.3" 504 | path-to-regexp "0.1.7" 505 | proxy-addr "~2.0.5" 506 | qs "6.7.0" 507 | range-parser "~1.2.1" 508 | safe-buffer "5.1.2" 509 | send "0.17.1" 510 | serve-static "1.14.1" 511 | setprototypeof "1.1.1" 512 | statuses "~1.5.0" 513 | type-is "~1.6.18" 514 | utils-merge "1.0.1" 515 | vary "~1.1.2" 516 | 517 | fd-slicer@1.1.0: 518 | version "1.1.0" 519 | resolved "https://registry.npm.taobao.org/fd-slicer/download/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" 520 | integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= 521 | dependencies: 522 | pend "~1.2.0" 523 | 524 | fill-range@^7.0.1: 525 | version "7.0.1" 526 | resolved "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 527 | integrity sha1-GRmmp8df44ssfHflGYU12prN2kA= 528 | dependencies: 529 | to-regex-range "^5.0.1" 530 | 531 | finalhandler@~1.1.2: 532 | version "1.1.2" 533 | resolved "https://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" 534 | integrity sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0= 535 | dependencies: 536 | debug "2.6.9" 537 | encodeurl "~1.0.2" 538 | escape-html "~1.0.3" 539 | on-finished "~2.3.0" 540 | parseurl "~1.3.3" 541 | statuses "~1.5.0" 542 | unpipe "~1.0.0" 543 | 544 | formidable@^1.1.1: 545 | version "1.2.2" 546 | resolved "https://registry.npm.taobao.org/formidable/download/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" 547 | integrity sha1-v2muopcpgmdfAIZTQrmCmG9rjdk= 548 | 549 | forwarded@~0.1.2: 550 | version "0.1.2" 551 | resolved "https://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" 552 | integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= 553 | 554 | fresh@0.5.2, fresh@~0.5.2: 555 | version "0.5.2" 556 | resolved "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 557 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 558 | 559 | fs-extra@^9.0.0: 560 | version "9.0.0" 561 | resolved "https://registry.npm.taobao.org/fs-extra/download/fs-extra-9.0.0.tgz#b6afc31036e247b2466dc99c29ae797d5d4580a3" 562 | integrity sha1-tq/DEDbiR7JGbcmcKa55fV1FgKM= 563 | dependencies: 564 | at-least-node "^1.0.0" 565 | graceful-fs "^4.2.0" 566 | jsonfile "^6.0.1" 567 | universalify "^1.0.0" 568 | 569 | fsevents@~2.1.2: 570 | version "2.1.2" 571 | resolved "https://registry.npm.taobao.org/fsevents/download/fsevents-2.1.2.tgz?cache=0&sync_timestamp=1584609406420&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffsevents%2Fdownload%2Ffsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" 572 | integrity sha1-TAofs0vGjlQ7S4Kp7Dkr+9qECAU= 573 | 574 | get-stream@^4.1.0: 575 | version "4.1.0" 576 | resolved "https://registry.npm.taobao.org/get-stream/download/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" 577 | integrity sha1-wbJVV189wh1Zv8ec09K0axw6VLU= 578 | dependencies: 579 | pump "^3.0.0" 580 | 581 | get-stream@^5.1.0: 582 | version "5.1.0" 583 | resolved "https://registry.npm.taobao.org/get-stream/download/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" 584 | integrity sha1-ASA83JJZf5uQkGfD5lbMH008Tck= 585 | dependencies: 586 | pump "^3.0.0" 587 | 588 | glob-parent@~5.1.0: 589 | version "5.1.1" 590 | resolved "https://registry.npm.taobao.org/glob-parent/download/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" 591 | integrity sha1-tsHvQXxOVmPqSY8cRa+saRa7wik= 592 | dependencies: 593 | is-glob "^4.0.1" 594 | 595 | global-dirs@^2.0.1: 596 | version "2.0.1" 597 | resolved "https://registry.npm.taobao.org/global-dirs/download/global-dirs-2.0.1.tgz?cache=0&sync_timestamp=1573231918216&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglobal-dirs%2Fdownload%2Fglobal-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201" 598 | integrity sha1-rN87tmhbzVXLNeigUiZlaelGkgE= 599 | dependencies: 600 | ini "^1.3.5" 601 | 602 | global@^4.4.0: 603 | version "4.4.0" 604 | resolved "https://registry.npm.taobao.org/global/download/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" 605 | integrity sha1-PnsQUXkAajI+1xqvyj6cV6XMZAY= 606 | dependencies: 607 | min-document "^2.19.0" 608 | process "^0.11.10" 609 | 610 | got@^9.6.0: 611 | version "9.6.0" 612 | resolved "https://registry.npm.taobao.org/got/download/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" 613 | integrity sha1-7fRefWf5lUVwXeH3u+7rEhdl7YU= 614 | dependencies: 615 | "@sindresorhus/is" "^0.14.0" 616 | "@szmarczak/http-timer" "^1.1.2" 617 | cacheable-request "^6.0.0" 618 | decompress-response "^3.3.0" 619 | duplexer3 "^0.1.4" 620 | get-stream "^4.1.0" 621 | lowercase-keys "^1.0.1" 622 | mimic-response "^1.0.1" 623 | p-cancelable "^1.0.0" 624 | to-readable-stream "^1.0.0" 625 | url-parse-lax "^3.0.0" 626 | 627 | graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: 628 | version "4.2.3" 629 | resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" 630 | integrity sha1-ShL/G2A3bvCYYsIJPt2Qgyi+hCM= 631 | 632 | has-flag@^3.0.0: 633 | version "3.0.0" 634 | resolved "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 635 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 636 | 637 | has-flag@^4.0.0: 638 | version "4.0.0" 639 | resolved "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 640 | integrity sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s= 641 | 642 | has-yarn@^2.1.0: 643 | version "2.1.0" 644 | resolved "https://registry.npm.taobao.org/has-yarn/download/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" 645 | integrity sha1-E34RNUp7W/EapctknPDG8/8rLnc= 646 | 647 | hotnode@^0.0.8: 648 | version "0.0.8" 649 | resolved "https://registry.npm.taobao.org/hotnode/download/hotnode-0.0.8.tgz#3adaa63d5b252c26f12945c827d6125c60c80733" 650 | integrity sha1-OtqmPVslLCbxKUXIJ9YSXGDIBzM= 651 | dependencies: 652 | watch "0.5.0" 653 | 654 | http-assert@^1.3.0: 655 | version "1.4.1" 656 | resolved "https://registry.npm.taobao.org/http-assert/download/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878" 657 | integrity sha1-xfcl1neqfoc+9zYZm4lobM6zeHg= 658 | dependencies: 659 | deep-equal "~1.0.1" 660 | http-errors "~1.7.2" 661 | 662 | http-cache-semantics@^4.0.0: 663 | version "4.1.0" 664 | resolved "https://registry.npm.taobao.org/http-cache-semantics/download/http-cache-semantics-4.1.0.tgz?cache=0&sync_timestamp=1583107845365&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-cache-semantics%2Fdownload%2Fhttp-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" 665 | integrity sha1-SekcXL82yblLz81xwj1SSex045A= 666 | 667 | http-errors@1.7.2: 668 | version "1.7.2" 669 | resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" 670 | integrity sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8= 671 | dependencies: 672 | depd "~1.1.2" 673 | inherits "2.0.3" 674 | setprototypeof "1.1.1" 675 | statuses ">= 1.5.0 < 2" 676 | toidentifier "1.0.0" 677 | 678 | http-errors@1.7.3, http-errors@^1.6.3, http-errors@^1.7.3, http-errors@~1.7.0, http-errors@~1.7.2: 679 | version "1.7.3" 680 | resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" 681 | integrity sha1-bGGeT5xgMIw4UZSYwU+7EKrOuwY= 682 | dependencies: 683 | depd "~1.1.2" 684 | inherits "2.0.4" 685 | setprototypeof "1.1.1" 686 | statuses ">= 1.5.0 < 2" 687 | toidentifier "1.0.0" 688 | 689 | iconv-lite@0.4.24: 690 | version "0.4.24" 691 | resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 692 | integrity sha1-ICK0sl+93CHS9SSXSkdKr+czkIs= 693 | dependencies: 694 | safer-buffer ">= 2.1.2 < 3" 695 | 696 | ignore-by-default@^1.0.1: 697 | version "1.0.1" 698 | resolved "https://registry.npm.taobao.org/ignore-by-default/download/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" 699 | integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= 700 | 701 | import-lazy@^2.1.0: 702 | version "2.1.0" 703 | resolved "https://registry.npm.taobao.org/import-lazy/download/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" 704 | integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= 705 | 706 | imurmurhash@^0.1.4: 707 | version "0.1.4" 708 | resolved "https://registry.npm.taobao.org/imurmurhash/download/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 709 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 710 | 711 | inflation@^2.0.0: 712 | version "2.0.0" 713 | resolved "https://registry.npm.taobao.org/inflation/download/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f" 714 | integrity sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8= 715 | 716 | inherits@2.0.3: 717 | version "2.0.3" 718 | resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 719 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 720 | 721 | inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: 722 | version "2.0.4" 723 | resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 724 | integrity sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w= 725 | 726 | ini@^1.3.5, ini@~1.3.0: 727 | version "1.3.5" 728 | resolved "https://registry.npm.taobao.org/ini/download/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" 729 | integrity sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc= 730 | 731 | ipaddr.js@1.9.1: 732 | version "1.9.1" 733 | resolved "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" 734 | integrity sha1-v/OFQ+64mEglB5/zoqjmy9RngbM= 735 | 736 | is-binary-path@~2.1.0: 737 | version "2.1.0" 738 | resolved "https://registry.npm.taobao.org/is-binary-path/download/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 739 | integrity sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk= 740 | dependencies: 741 | binary-extensions "^2.0.0" 742 | 743 | is-ci@^2.0.0: 744 | version "2.0.0" 745 | resolved "https://registry.npm.taobao.org/is-ci/download/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" 746 | integrity sha1-a8YzQYGBDgS1wis9WJ/cpVAmQEw= 747 | dependencies: 748 | ci-info "^2.0.0" 749 | 750 | is-extglob@^2.1.1: 751 | version "2.1.1" 752 | resolved "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 753 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 754 | 755 | is-fullwidth-code-point@^2.0.0: 756 | version "2.0.0" 757 | resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 758 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 759 | 760 | is-fullwidth-code-point@^3.0.0: 761 | version "3.0.0" 762 | resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 763 | integrity sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0= 764 | 765 | is-generator-function@^1.0.7: 766 | version "1.0.7" 767 | resolved "https://registry.npm.taobao.org/is-generator-function/download/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" 768 | integrity sha1-0hMuUpuwAAp/gHlNS99c1eWBNSI= 769 | 770 | is-glob@^4.0.1, is-glob@~4.0.1: 771 | version "4.0.1" 772 | resolved "https://registry.npm.taobao.org/is-glob/download/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" 773 | integrity sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw= 774 | dependencies: 775 | is-extglob "^2.1.1" 776 | 777 | is-installed-globally@^0.3.1: 778 | version "0.3.2" 779 | resolved "https://registry.npm.taobao.org/is-installed-globally/download/is-installed-globally-0.3.2.tgz?cache=0&sync_timestamp=1586162509580&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-installed-globally%2Fdownload%2Fis-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" 780 | integrity sha1-/T76ee5nDRGHIzGC1bCh3QAxMUE= 781 | dependencies: 782 | global-dirs "^2.0.1" 783 | is-path-inside "^3.0.1" 784 | 785 | is-npm@^4.0.0: 786 | version "4.0.0" 787 | resolved "https://registry.npm.taobao.org/is-npm/download/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" 788 | integrity sha1-yQ3YOAaW34enptgjwg0LErvjyE0= 789 | 790 | is-number@^7.0.0: 791 | version "7.0.0" 792 | resolved "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 793 | integrity sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss= 794 | 795 | is-obj@^2.0.0: 796 | version "2.0.0" 797 | resolved "https://registry.npm.taobao.org/is-obj/download/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" 798 | integrity sha1-Rz+wXZc3BeP9liBUUBjKjiLvSYI= 799 | 800 | is-path-inside@^3.0.1: 801 | version "3.0.2" 802 | resolved "https://registry.npm.taobao.org/is-path-inside/download/is-path-inside-3.0.2.tgz?cache=0&sync_timestamp=1569835754259&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-path-inside%2Fdownload%2Fis-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" 803 | integrity sha1-9SIPyCo+IzdXKR3dycWHfyofMBc= 804 | 805 | is-typedarray@^1.0.0: 806 | version "1.0.0" 807 | resolved "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 808 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= 809 | 810 | is-yarn-global@^0.3.0: 811 | version "0.3.0" 812 | resolved "https://registry.npm.taobao.org/is-yarn-global/download/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" 813 | integrity sha1-1QLTOCWQ6jAEiTdGdUyJE5lz4jI= 814 | 815 | isarray@0.0.1: 816 | version "0.0.1" 817 | resolved "https://registry.npm.taobao.org/isarray/download/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 818 | integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= 819 | 820 | isarray@~1.0.0: 821 | version "1.0.0" 822 | resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 823 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 824 | 825 | json-buffer@3.0.0: 826 | version "3.0.0" 827 | resolved "https://registry.npm.taobao.org/json-buffer/download/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" 828 | integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= 829 | 830 | jsonfile@^6.0.1: 831 | version "6.0.1" 832 | resolved "https://registry.npm.taobao.org/jsonfile/download/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179" 833 | integrity sha1-mJZsuiFDeMjIS4LghZB7QL9hQXk= 834 | dependencies: 835 | universalify "^1.0.0" 836 | optionalDependencies: 837 | graceful-fs "^4.1.6" 838 | 839 | keygrip@~1.1.0: 840 | version "1.1.0" 841 | resolved "https://registry.npm.taobao.org/keygrip/download/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" 842 | integrity sha1-hxsWgdXhWcYqRFsMdLYV4JF+ciY= 843 | dependencies: 844 | tsscmp "1.0.6" 845 | 846 | keyv@^3.0.0: 847 | version "3.1.0" 848 | resolved "https://registry.npm.taobao.org/keyv/download/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" 849 | integrity sha1-7MIoSG9pmR5J6UdkhaW+Ho/FxNk= 850 | dependencies: 851 | json-buffer "3.0.0" 852 | 853 | koa-body@^4.1.1: 854 | version "4.1.1" 855 | resolved "https://registry.npm.taobao.org/koa-body/download/koa-body-4.1.1.tgz#50686d290891fc6f1acb986cf7cfcd605f855ef0" 856 | integrity sha1-UGhtKQiR/G8ay5hs98/NYF+FXvA= 857 | dependencies: 858 | "@types/formidable" "^1.0.31" 859 | co-body "^5.1.1" 860 | formidable "^1.1.1" 861 | 862 | koa-compose@^3.0.0: 863 | version "3.2.1" 864 | resolved "https://registry.npm.taobao.org/koa-compose/download/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7" 865 | integrity sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec= 866 | dependencies: 867 | any-promise "^1.1.0" 868 | 869 | koa-compose@^4.1.0: 870 | version "4.1.0" 871 | resolved "https://registry.npm.taobao.org/koa-compose/download/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" 872 | integrity sha1-UHMGuTcZAdtBEhyBLpI9DWfT6Hc= 873 | 874 | koa-convert@^1.2.0: 875 | version "1.2.0" 876 | resolved "https://registry.npm.taobao.org/koa-convert/download/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0" 877 | integrity sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA= 878 | dependencies: 879 | co "^4.6.0" 880 | koa-compose "^3.0.0" 881 | 882 | koa-router@^8.0.8: 883 | version "8.0.8" 884 | resolved "https://registry.npm.taobao.org/koa-router/download/koa-router-8.0.8.tgz#f0b70f90dae275db8c71a41e1efb625581fb3b5a" 885 | integrity sha1-8LcPkNridduMcaQeHvtiVYH7O1o= 886 | dependencies: 887 | debug "^4.1.1" 888 | http-errors "^1.7.3" 889 | koa-compose "^4.1.0" 890 | methods "^1.1.2" 891 | path-to-regexp "1.x" 892 | urijs "^1.19.2" 893 | 894 | koa2-cors@^2.0.6: 895 | version "2.0.6" 896 | resolved "https://registry.npm.taobao.org/koa2-cors/download/koa2-cors-2.0.6.tgz#9ad23df3a0b9bb84530b46f5944f3fb576086554" 897 | integrity sha1-mtI986C5u4RTC0b1lE8/tXYIZVQ= 898 | 899 | koa@^2.11.0: 900 | version "2.11.0" 901 | resolved "https://registry.npm.taobao.org/koa/download/koa-2.11.0.tgz?cache=0&sync_timestamp=1572232411139&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fkoa%2Fdownload%2Fkoa-2.11.0.tgz#fe5a51c46f566d27632dd5dc8fd5d7dd44f935a4" 902 | integrity sha1-/lpRxG9WbSdjLdXcj9XX3UT5NaQ= 903 | dependencies: 904 | accepts "^1.3.5" 905 | cache-content-type "^1.0.0" 906 | content-disposition "~0.5.2" 907 | content-type "^1.0.4" 908 | cookies "~0.8.0" 909 | debug "~3.1.0" 910 | delegates "^1.0.0" 911 | depd "^1.1.2" 912 | destroy "^1.0.4" 913 | encodeurl "^1.0.2" 914 | error-inject "^1.0.0" 915 | escape-html "^1.0.3" 916 | fresh "~0.5.2" 917 | http-assert "^1.3.0" 918 | http-errors "^1.6.3" 919 | is-generator-function "^1.0.7" 920 | koa-compose "^4.1.0" 921 | koa-convert "^1.2.0" 922 | on-finished "^2.3.0" 923 | only "~0.0.2" 924 | parseurl "^1.3.2" 925 | statuses "^1.5.0" 926 | type-is "^1.6.16" 927 | vary "^1.1.2" 928 | 929 | latest-version@^5.0.0: 930 | version "5.1.0" 931 | resolved "https://registry.npm.taobao.org/latest-version/download/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" 932 | integrity sha1-EZ3+kI/jjRXfpD7NE/oS7Igy+s4= 933 | dependencies: 934 | package-json "^6.3.0" 935 | 936 | lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: 937 | version "1.0.1" 938 | resolved "https://registry.npm.taobao.org/lowercase-keys/download/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" 939 | integrity sha1-b54wtHCE2XGnyCD/FabFFnt0wm8= 940 | 941 | lowercase-keys@^2.0.0: 942 | version "2.0.0" 943 | resolved "https://registry.npm.taobao.org/lowercase-keys/download/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" 944 | integrity sha1-JgPni3tLAAbLyi+8yKMgJVislHk= 945 | 946 | make-dir@^3.0.0: 947 | version "3.0.2" 948 | resolved "https://registry.npm.taobao.org/make-dir/download/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" 949 | integrity sha1-BKGsvyIiHh1u9DVZ9D4FqQ27Q5I= 950 | dependencies: 951 | semver "^6.0.0" 952 | 953 | media-typer@0.3.0: 954 | version "0.3.0" 955 | resolved "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 956 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= 957 | 958 | merge-descriptors@1.0.1: 959 | version "1.0.1" 960 | resolved "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 961 | integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= 962 | 963 | methods@^1.1.2, methods@~1.1.2: 964 | version "1.1.2" 965 | resolved "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 966 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 967 | 968 | mime-db@1.43.0: 969 | version "1.43.0" 970 | resolved "https://registry.npm.taobao.org/mime-db/download/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" 971 | integrity sha1-ChLgUCZQ5HPXNVNQUOfI9OtPrlg= 972 | 973 | mime-types@^2.1.18, mime-types@~2.1.24: 974 | version "2.1.26" 975 | resolved "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" 976 | integrity sha1-nJIfwJt+FJpl39wNpNIJlyALCgY= 977 | dependencies: 978 | mime-db "1.43.0" 979 | 980 | mime@1.6.0: 981 | version "1.6.0" 982 | resolved "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 983 | integrity sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE= 984 | 985 | mimic-response@^1.0.0, mimic-response@^1.0.1: 986 | version "1.0.1" 987 | resolved "https://registry.npm.taobao.org/mimic-response/download/mimic-response-1.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmimic-response%2Fdownload%2Fmimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" 988 | integrity sha1-SSNTiHju9CBjy4o+OweYeBSHqxs= 989 | 990 | min-document@^2.19.0: 991 | version "2.19.0" 992 | resolved "https://registry.npm.taobao.org/min-document/download/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" 993 | integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= 994 | dependencies: 995 | dom-walk "^0.1.0" 996 | 997 | minimatch@^3.0.4: 998 | version "3.0.4" 999 | resolved "https://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 1000 | integrity sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM= 1001 | dependencies: 1002 | brace-expansion "^1.1.7" 1003 | 1004 | minimist@^1.2.0, minimist@^1.2.5: 1005 | version "1.2.5" 1006 | resolved "https://registry.npm.taobao.org/minimist/download/minimist-1.2.5.tgz?cache=0&sync_timestamp=1584051509720&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fminimist%2Fdownload%2Fminimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" 1007 | integrity sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI= 1008 | 1009 | mkdirp@^0.5.1: 1010 | version "0.5.5" 1011 | resolved "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" 1012 | integrity sha1-2Rzv1i0UNsoPQWIOJRKI1CAJne8= 1013 | dependencies: 1014 | minimist "^1.2.5" 1015 | 1016 | moment@^2.24.0: 1017 | version "2.24.0" 1018 | resolved "https://registry.npm.taobao.org/moment/download/moment-2.24.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmoment%2Fdownload%2Fmoment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" 1019 | integrity sha1-DQVdU/UFKqZTyfbraLtdEr9cK1s= 1020 | 1021 | ms@2.0.0: 1022 | version "2.0.0" 1023 | resolved "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1024 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 1025 | 1026 | ms@2.1.1: 1027 | version "2.1.1" 1028 | resolved "https://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 1029 | integrity sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo= 1030 | 1031 | ms@^2.1.1: 1032 | version "2.1.2" 1033 | resolved "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1034 | integrity sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= 1035 | 1036 | multer@^1.4.2: 1037 | version "1.4.2" 1038 | resolved "https://registry.npm.taobao.org/multer/download/multer-1.4.2.tgz#2f1f4d12dbaeeba74cb37e623f234bf4d3d2057a" 1039 | integrity sha1-Lx9NEtuu66dMs35iPyNL9NPSBXo= 1040 | dependencies: 1041 | append-field "^1.0.0" 1042 | busboy "^0.2.11" 1043 | concat-stream "^1.5.2" 1044 | mkdirp "^0.5.1" 1045 | object-assign "^4.1.1" 1046 | on-finished "^2.3.0" 1047 | type-is "^1.6.4" 1048 | xtend "^4.0.0" 1049 | 1050 | multiparty@^4.2.1: 1051 | version "4.2.1" 1052 | resolved "https://registry.npm.taobao.org/multiparty/download/multiparty-4.2.1.tgz#d9b6c46d8b8deab1ee70c734b0af771dd46e0b13" 1053 | integrity sha1-2bbEbYuN6rHucMc0sK93HdRuCxM= 1054 | dependencies: 1055 | fd-slicer "1.1.0" 1056 | http-errors "~1.7.0" 1057 | safe-buffer "5.1.2" 1058 | uid-safe "2.1.5" 1059 | 1060 | negotiator@0.6.2: 1061 | version "0.6.2" 1062 | resolved "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" 1063 | integrity sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs= 1064 | 1065 | nodemon@^2.0.3: 1066 | version "2.0.3" 1067 | resolved "https://registry.npm.taobao.org/nodemon/download/nodemon-2.0.3.tgz#e9c64df8740ceaef1cb00e1f3da57c0a93ef3714" 1068 | integrity sha1-6cZN+HQM6u8csA4fPaV8CpPvNxQ= 1069 | dependencies: 1070 | chokidar "^3.2.2" 1071 | debug "^3.2.6" 1072 | ignore-by-default "^1.0.1" 1073 | minimatch "^3.0.4" 1074 | pstree.remy "^1.1.7" 1075 | semver "^5.7.1" 1076 | supports-color "^5.5.0" 1077 | touch "^3.1.0" 1078 | undefsafe "^2.0.2" 1079 | update-notifier "^4.0.0" 1080 | 1081 | nopt@~1.0.10: 1082 | version "1.0.10" 1083 | resolved "https://registry.npm.taobao.org/nopt/download/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" 1084 | integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= 1085 | dependencies: 1086 | abbrev "1" 1087 | 1088 | normalize-path@^3.0.0, normalize-path@~3.0.0: 1089 | version "3.0.0" 1090 | resolved "https://registry.npm.taobao.org/normalize-path/download/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 1091 | integrity sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU= 1092 | 1093 | normalize-url@^4.1.0: 1094 | version "4.5.0" 1095 | resolved "https://registry.npm.taobao.org/normalize-url/download/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" 1096 | integrity sha1-RTNUCH5sqWlXvY9br3U/WYIUISk= 1097 | 1098 | object-assign@^4.1.1: 1099 | version "4.1.1" 1100 | resolved "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1101 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 1102 | 1103 | on-finished@^2.3.0, on-finished@~2.3.0: 1104 | version "2.3.0" 1105 | resolved "https://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 1106 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 1107 | dependencies: 1108 | ee-first "1.1.1" 1109 | 1110 | once@^1.3.1, once@^1.4.0: 1111 | version "1.4.0" 1112 | resolved "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1113 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 1114 | dependencies: 1115 | wrappy "1" 1116 | 1117 | only@~0.0.2: 1118 | version "0.0.2" 1119 | resolved "https://registry.npm.taobao.org/only/download/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" 1120 | integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= 1121 | 1122 | p-cancelable@^1.0.0: 1123 | version "1.1.0" 1124 | resolved "https://registry.npm.taobao.org/p-cancelable/download/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" 1125 | integrity sha1-0HjRWjr0CSIMiG8dmgyi5EGrJsw= 1126 | 1127 | package-json@^6.3.0: 1128 | version "6.5.0" 1129 | resolved "https://registry.npm.taobao.org/package-json/download/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" 1130 | integrity sha1-b+7ayjXnVyWHbQsOZJdGl/7RRbA= 1131 | dependencies: 1132 | got "^9.6.0" 1133 | registry-auth-token "^4.0.0" 1134 | registry-url "^5.0.0" 1135 | semver "^6.2.0" 1136 | 1137 | parseurl@^1.3.2, parseurl@~1.3.3: 1138 | version "1.3.3" 1139 | resolved "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 1140 | integrity sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ= 1141 | 1142 | path-to-regexp@0.1.7: 1143 | version "0.1.7" 1144 | resolved "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 1145 | integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= 1146 | 1147 | path-to-regexp@1.x: 1148 | version "1.8.0" 1149 | resolved "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" 1150 | integrity sha1-iHs7qdhDk+h6CgufTLdWGYtTVIo= 1151 | dependencies: 1152 | isarray "0.0.1" 1153 | 1154 | pend@~1.2.0: 1155 | version "1.2.0" 1156 | resolved "https://registry.npm.taobao.org/pend/download/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" 1157 | integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= 1158 | 1159 | picomatch@^2.0.4, picomatch@^2.0.7: 1160 | version "2.2.2" 1161 | resolved "https://registry.npm.taobao.org/picomatch/download/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" 1162 | integrity sha1-IfMz6ba46v8CRo9RRupAbTRfTa0= 1163 | 1164 | prepend-http@^2.0.0: 1165 | version "2.0.0" 1166 | resolved "https://registry.npm.taobao.org/prepend-http/download/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" 1167 | integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= 1168 | 1169 | process-nextick-args@~2.0.0: 1170 | version "2.0.1" 1171 | resolved "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 1172 | integrity sha1-eCDZsWEgzFXKmud5JoCufbptf+I= 1173 | 1174 | process@^0.11.10: 1175 | version "0.11.10" 1176 | resolved "https://registry.npm.taobao.org/process/download/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" 1177 | integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= 1178 | 1179 | proxy-addr@~2.0.5: 1180 | version "2.0.6" 1181 | resolved "https://registry.npm.taobao.org/proxy-addr/download/proxy-addr-2.0.6.tgz?cache=0&sync_timestamp=1582556112011&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fproxy-addr%2Fdownload%2Fproxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" 1182 | integrity sha1-/cIzZQVEfT8vLGOO0nLK9hS7sr8= 1183 | dependencies: 1184 | forwarded "~0.1.2" 1185 | ipaddr.js "1.9.1" 1186 | 1187 | pstree.remy@^1.1.7: 1188 | version "1.1.7" 1189 | resolved "https://registry.npm.taobao.org/pstree.remy/download/pstree.remy-1.1.7.tgz#c76963a28047ed61542dc361aa26ee55a7fa15f3" 1190 | integrity sha1-x2ljooBH7WFULcNhqibuVaf6FfM= 1191 | 1192 | pump@^3.0.0: 1193 | version "3.0.0" 1194 | resolved "https://registry.npm.taobao.org/pump/download/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" 1195 | integrity sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ= 1196 | dependencies: 1197 | end-of-stream "^1.1.0" 1198 | once "^1.3.1" 1199 | 1200 | pupa@^2.0.1: 1201 | version "2.0.1" 1202 | resolved "https://registry.npm.taobao.org/pupa/download/pupa-2.0.1.tgz#dbdc9ff48ffbea4a26a069b6f9f7abb051008726" 1203 | integrity sha1-29yf9I/76komoGm2+fersFEAhyY= 1204 | dependencies: 1205 | escape-goat "^2.0.0" 1206 | 1207 | qs@6.7.0: 1208 | version "6.7.0" 1209 | resolved "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz?cache=0&sync_timestamp=1585168658937&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" 1210 | integrity sha1-QdwaAV49WB8WIXdr4xr7KHapsbw= 1211 | 1212 | qs@^6.4.0: 1213 | version "6.9.3" 1214 | resolved "https://registry.npm.taobao.org/qs/download/qs-6.9.3.tgz?cache=0&sync_timestamp=1585168658937&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" 1215 | integrity sha1-v63NKWwtVJ8d/6VgYZEyyXf1AI4= 1216 | 1217 | random-bytes@~1.0.0: 1218 | version "1.0.0" 1219 | resolved "https://registry.npm.taobao.org/random-bytes/download/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" 1220 | integrity sha1-T2ih3Arli9P7lYSMMDJNt11kNgs= 1221 | 1222 | range-parser@~1.2.1: 1223 | version "1.2.1" 1224 | resolved "https://registry.npm.taobao.org/range-parser/download/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" 1225 | integrity sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE= 1226 | 1227 | raw-body@2.4.0: 1228 | version "2.4.0" 1229 | resolved "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" 1230 | integrity sha1-oc5vucm8NWylLoklarWQWeE9AzI= 1231 | dependencies: 1232 | bytes "3.1.0" 1233 | http-errors "1.7.2" 1234 | iconv-lite "0.4.24" 1235 | unpipe "1.0.0" 1236 | 1237 | raw-body@^2.2.0: 1238 | version "2.4.1" 1239 | resolved "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" 1240 | integrity sha1-MKyC+Yu1rowVLmcUnayNVRU7Fow= 1241 | dependencies: 1242 | bytes "3.1.0" 1243 | http-errors "1.7.3" 1244 | iconv-lite "0.4.24" 1245 | unpipe "1.0.0" 1246 | 1247 | rc@^1.2.8: 1248 | version "1.2.8" 1249 | resolved "https://registry.npm.taobao.org/rc/download/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" 1250 | integrity sha1-zZJL9SAKB1uDwYjNa54hG3/A0+0= 1251 | dependencies: 1252 | deep-extend "^0.6.0" 1253 | ini "~1.3.0" 1254 | minimist "^1.2.0" 1255 | strip-json-comments "~2.0.1" 1256 | 1257 | readable-stream@1.1.x: 1258 | version "1.1.14" 1259 | resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" 1260 | integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= 1261 | dependencies: 1262 | core-util-is "~1.0.0" 1263 | inherits "~2.0.1" 1264 | isarray "0.0.1" 1265 | string_decoder "~0.10.x" 1266 | 1267 | readable-stream@^2.2.2: 1268 | version "2.3.7" 1269 | resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" 1270 | integrity sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c= 1271 | dependencies: 1272 | core-util-is "~1.0.0" 1273 | inherits "~2.0.3" 1274 | isarray "~1.0.0" 1275 | process-nextick-args "~2.0.0" 1276 | safe-buffer "~5.1.1" 1277 | string_decoder "~1.1.1" 1278 | util-deprecate "~1.0.1" 1279 | 1280 | readdirp@~3.3.0: 1281 | version "3.3.0" 1282 | resolved "https://registry.npm.taobao.org/readdirp/download/readdirp-3.3.0.tgz?cache=0&sync_timestamp=1584985807685&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freaddirp%2Fdownload%2Freaddirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17" 1283 | integrity sha1-mERY0ToeQuLp9YQbEp4WLzaa/xc= 1284 | dependencies: 1285 | picomatch "^2.0.7" 1286 | 1287 | registry-auth-token@^4.0.0: 1288 | version "4.1.1" 1289 | resolved "https://registry.npm.taobao.org/registry-auth-token/download/registry-auth-token-4.1.1.tgz#40a33be1e82539460f94328b0f7f0f84c16d9479" 1290 | integrity sha1-QKM74eglOUYPlDKLD38PhMFtlHk= 1291 | dependencies: 1292 | rc "^1.2.8" 1293 | 1294 | registry-url@^5.0.0: 1295 | version "5.1.0" 1296 | resolved "https://registry.npm.taobao.org/registry-url/download/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" 1297 | integrity sha1-6YM0tQ1UNLgRNrROxjjZwgCcUAk= 1298 | dependencies: 1299 | rc "^1.2.8" 1300 | 1301 | responselike@^1.0.2: 1302 | version "1.0.2" 1303 | resolved "https://registry.npm.taobao.org/responselike/download/responselike-1.0.2.tgz?cache=0&sync_timestamp=1570573217730&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fresponselike%2Fdownload%2Fresponselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" 1304 | integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= 1305 | dependencies: 1306 | lowercase-keys "^1.0.0" 1307 | 1308 | safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 1309 | version "5.1.2" 1310 | resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 1311 | integrity sha1-mR7GnSluAxN0fVm9/St0XDX4go0= 1312 | 1313 | "safer-buffer@>= 2.1.2 < 3": 1314 | version "2.1.2" 1315 | resolved "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 1316 | integrity sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo= 1317 | 1318 | semver-diff@^3.1.1: 1319 | version "3.1.1" 1320 | resolved "https://registry.npm.taobao.org/semver-diff/download/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" 1321 | integrity sha1-Bfd85Z8yXgDicGr9Z7tQbdscoys= 1322 | dependencies: 1323 | semver "^6.3.0" 1324 | 1325 | semver@^5.7.1: 1326 | version "5.7.1" 1327 | resolved "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1586886301819&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 1328 | integrity sha1-qVT5Ma66UI0we78Gnv8MAclhFvc= 1329 | 1330 | semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: 1331 | version "6.3.0" 1332 | resolved "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz?cache=0&sync_timestamp=1586886301819&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" 1333 | integrity sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0= 1334 | 1335 | send@0.17.1: 1336 | version "0.17.1" 1337 | resolved "https://registry.npm.taobao.org/send/download/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" 1338 | integrity sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg= 1339 | dependencies: 1340 | debug "2.6.9" 1341 | depd "~1.1.2" 1342 | destroy "~1.0.4" 1343 | encodeurl "~1.0.2" 1344 | escape-html "~1.0.3" 1345 | etag "~1.8.1" 1346 | fresh "0.5.2" 1347 | http-errors "~1.7.2" 1348 | mime "1.6.0" 1349 | ms "2.1.1" 1350 | on-finished "~2.3.0" 1351 | range-parser "~1.2.1" 1352 | statuses "~1.5.0" 1353 | 1354 | serve-static@1.14.1: 1355 | version "1.14.1" 1356 | resolved "https://registry.npm.taobao.org/serve-static/download/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" 1357 | integrity sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk= 1358 | dependencies: 1359 | encodeurl "~1.0.2" 1360 | escape-html "~1.0.3" 1361 | parseurl "~1.3.3" 1362 | send "0.17.1" 1363 | 1364 | setprototypeof@1.1.1: 1365 | version "1.1.1" 1366 | resolved "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz?cache=0&sync_timestamp=1563425414995&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsetprototypeof%2Fdownload%2Fsetprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" 1367 | integrity sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM= 1368 | 1369 | shancw-stdout@^1.0.0: 1370 | version "1.0.0" 1371 | resolved "https://registry.npm.taobao.org/shancw-stdout/download/shancw-stdout-1.0.0.tgz#d4ab7de4355c6a989a707ee096ba2191628385e6" 1372 | integrity sha1-1Kt95DVcapiacH7glrohkWKDheY= 1373 | 1374 | signal-exit@^3.0.2: 1375 | version "3.0.3" 1376 | resolved "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsignal-exit%2Fdownload%2Fsignal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" 1377 | integrity sha1-oUEMLt2PB3sItOJTyOrPyvBXRhw= 1378 | 1379 | "statuses@>= 1.5.0 < 2", statuses@^1.5.0, statuses@~1.5.0: 1380 | version "1.5.0" 1381 | resolved "https://registry.npm.taobao.org/statuses/download/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 1382 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 1383 | 1384 | streamsearch@0.1.2: 1385 | version "0.1.2" 1386 | resolved "https://registry.npm.taobao.org/streamsearch/download/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" 1387 | integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= 1388 | 1389 | string-width@^3.0.0: 1390 | version "3.1.0" 1391 | resolved "https://registry.npm.taobao.org/string-width/download/string-width-3.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring-width%2Fdownload%2Fstring-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" 1392 | integrity sha1-InZ74htirxCBV0MG9prFG2IgOWE= 1393 | dependencies: 1394 | emoji-regex "^7.0.1" 1395 | is-fullwidth-code-point "^2.0.0" 1396 | strip-ansi "^5.1.0" 1397 | 1398 | string-width@^4.0.0, string-width@^4.1.0: 1399 | version "4.2.0" 1400 | resolved "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring-width%2Fdownload%2Fstring-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" 1401 | integrity sha1-lSGCxGzHssMT0VluYjmSvRY7crU= 1402 | dependencies: 1403 | emoji-regex "^8.0.0" 1404 | is-fullwidth-code-point "^3.0.0" 1405 | strip-ansi "^6.0.0" 1406 | 1407 | string_decoder@~0.10.x: 1408 | version "0.10.31" 1409 | resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-0.10.31.tgz?cache=0&sync_timestamp=1565170823020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring_decoder%2Fdownload%2Fstring_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 1410 | integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= 1411 | 1412 | string_decoder@~1.1.1: 1413 | version "1.1.1" 1414 | resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz?cache=0&sync_timestamp=1565170823020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring_decoder%2Fdownload%2Fstring_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 1415 | integrity sha1-nPFhG6YmhdcDCunkujQUnDrwP8g= 1416 | dependencies: 1417 | safe-buffer "~5.1.0" 1418 | 1419 | strip-ansi@^5.1.0: 1420 | version "5.2.0" 1421 | resolved "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" 1422 | integrity sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4= 1423 | dependencies: 1424 | ansi-regex "^4.1.0" 1425 | 1426 | strip-ansi@^6.0.0: 1427 | version "6.0.0" 1428 | resolved "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" 1429 | integrity sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI= 1430 | dependencies: 1431 | ansi-regex "^5.0.0" 1432 | 1433 | strip-json-comments@~2.0.1: 1434 | version "2.0.1" 1435 | resolved "https://registry.npm.taobao.org/strip-json-comments/download/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 1436 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 1437 | 1438 | supports-color@^5.5.0: 1439 | version "5.5.0" 1440 | resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1441 | integrity sha1-4uaaRKyHcveKHsCzW2id9lMO/I8= 1442 | dependencies: 1443 | has-flag "^3.0.0" 1444 | 1445 | supports-color@^7.1.0: 1446 | version "7.1.0" 1447 | resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-7.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" 1448 | integrity sha1-aOMlkd9z4lrRxLSRCKLsUHliv9E= 1449 | dependencies: 1450 | has-flag "^4.0.0" 1451 | 1452 | term-size@^2.1.0: 1453 | version "2.2.0" 1454 | resolved "https://registry.npm.taobao.org/term-size/download/term-size-2.2.0.tgz#1f16adedfe9bdc18800e1776821734086fcc6753" 1455 | integrity sha1-Hxat7f6b3BiADhd2ghc0CG/MZ1M= 1456 | 1457 | to-readable-stream@^1.0.0: 1458 | version "1.0.0" 1459 | resolved "https://registry.npm.taobao.org/to-readable-stream/download/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" 1460 | integrity sha1-zgqgwvPfat+FLvtASng+d8BHV3E= 1461 | 1462 | to-regex-range@^5.0.1: 1463 | version "5.0.1" 1464 | resolved "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1465 | integrity sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ= 1466 | dependencies: 1467 | is-number "^7.0.0" 1468 | 1469 | toidentifier@1.0.0: 1470 | version "1.0.0" 1471 | resolved "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" 1472 | integrity sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM= 1473 | 1474 | touch@^3.1.0: 1475 | version "3.1.0" 1476 | resolved "https://registry.npm.taobao.org/touch/download/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" 1477 | integrity sha1-/jZfX3XsntTlaCXgu3bSSrdK+Ds= 1478 | dependencies: 1479 | nopt "~1.0.10" 1480 | 1481 | tsscmp@1.0.6: 1482 | version "1.0.6" 1483 | resolved "https://registry.npm.taobao.org/tsscmp/download/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" 1484 | integrity sha1-hbmVg6w1iexL/vgltQAKqRHWBes= 1485 | 1486 | type-fest@^0.8.1: 1487 | version "0.8.1" 1488 | resolved "https://registry.npm.taobao.org/type-fest/download/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" 1489 | integrity sha1-CeJJ696FHTseSNJ8EFREZn8XuD0= 1490 | 1491 | type-is@^1.6.14, type-is@^1.6.16, type-is@^1.6.4, type-is@~1.6.17, type-is@~1.6.18: 1492 | version "1.6.18" 1493 | resolved "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 1494 | integrity sha1-TlUs0F3wlGfcvE73Od6J8s83wTE= 1495 | dependencies: 1496 | media-typer "0.3.0" 1497 | mime-types "~2.1.24" 1498 | 1499 | typedarray-to-buffer@^3.1.5: 1500 | version "3.1.5" 1501 | resolved "https://registry.npm.taobao.org/typedarray-to-buffer/download/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" 1502 | integrity sha1-qX7nqf9CaRufeD/xvFES/j/KkIA= 1503 | dependencies: 1504 | is-typedarray "^1.0.0" 1505 | 1506 | typedarray@^0.0.6: 1507 | version "0.0.6" 1508 | resolved "https://registry.npm.taobao.org/typedarray/download/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 1509 | integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= 1510 | 1511 | uid-safe@2.1.5: 1512 | version "2.1.5" 1513 | resolved "https://registry.npm.taobao.org/uid-safe/download/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" 1514 | integrity sha1-Kz1cckDo/C5Y+Komnl7knAhXvTo= 1515 | dependencies: 1516 | random-bytes "~1.0.0" 1517 | 1518 | undefsafe@^2.0.2: 1519 | version "2.0.3" 1520 | resolved "https://registry.npm.taobao.org/undefsafe/download/undefsafe-2.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fundefsafe%2Fdownload%2Fundefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" 1521 | integrity sha1-axZucJStRjE7IgLafsws18xueq4= 1522 | dependencies: 1523 | debug "^2.2.0" 1524 | 1525 | unique-string@^2.0.0: 1526 | version "2.0.0" 1527 | resolved "https://registry.npm.taobao.org/unique-string/download/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" 1528 | integrity sha1-OcZFH4GvsnSd4rIz4/fF6IQ72J0= 1529 | dependencies: 1530 | crypto-random-string "^2.0.0" 1531 | 1532 | universalify@^1.0.0: 1533 | version "1.0.0" 1534 | resolved "https://registry.npm.taobao.org/universalify/download/universalify-1.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funiversalify%2Fdownload%2Funiversalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" 1535 | integrity sha1-thodoXPoQ1sv48Z9Kbmt+FlL0W0= 1536 | 1537 | unpipe@1.0.0, unpipe@~1.0.0: 1538 | version "1.0.0" 1539 | resolved "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 1540 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 1541 | 1542 | update-notifier@^4.0.0: 1543 | version "4.1.0" 1544 | resolved "https://registry.npm.taobao.org/update-notifier/download/update-notifier-4.1.0.tgz#4866b98c3bc5b5473c020b1250583628f9a328f3" 1545 | integrity sha1-SGa5jDvFtUc8AgsSUFg2KPmjKPM= 1546 | dependencies: 1547 | boxen "^4.2.0" 1548 | chalk "^3.0.0" 1549 | configstore "^5.0.1" 1550 | has-yarn "^2.1.0" 1551 | import-lazy "^2.1.0" 1552 | is-ci "^2.0.0" 1553 | is-installed-globally "^0.3.1" 1554 | is-npm "^4.0.0" 1555 | is-yarn-global "^0.3.0" 1556 | latest-version "^5.0.0" 1557 | pupa "^2.0.1" 1558 | semver-diff "^3.1.1" 1559 | xdg-basedir "^4.0.0" 1560 | 1561 | urijs@^1.19.2: 1562 | version "1.19.2" 1563 | resolved "https://registry.npm.taobao.org/urijs/download/urijs-1.19.2.tgz#f9be09f00c4c5134b7cb3cf475c1dd394526265a" 1564 | integrity sha1-+b4J8AxMUTS3yzz0dcHdOUUmJlo= 1565 | 1566 | url-parse-lax@^3.0.0: 1567 | version "3.0.0" 1568 | resolved "https://registry.npm.taobao.org/url-parse-lax/download/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" 1569 | integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= 1570 | dependencies: 1571 | prepend-http "^2.0.0" 1572 | 1573 | util-deprecate@~1.0.1: 1574 | version "1.0.2" 1575 | resolved "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1576 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 1577 | 1578 | utils-merge@1.0.1: 1579 | version "1.0.1" 1580 | resolved "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 1581 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= 1582 | 1583 | vary@^1.1.2, vary@~1.1.2: 1584 | version "1.1.2" 1585 | resolved "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 1586 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 1587 | 1588 | watch@0.5.0: 1589 | version "0.5.0" 1590 | resolved "https://registry.npm.taobao.org/watch/download/watch-0.5.0.tgz#1eb1399b3420960127431efa646b718da146d37f" 1591 | integrity sha1-HrE5mzQglgEnQx76ZGtxjaFG038= 1592 | 1593 | widest-line@^3.1.0: 1594 | version "3.1.0" 1595 | resolved "https://registry.npm.taobao.org/widest-line/download/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" 1596 | integrity sha1-gpIzO79my0X/DeFgOxNreuFJbso= 1597 | dependencies: 1598 | string-width "^4.0.0" 1599 | 1600 | wrappy@1: 1601 | version "1.0.2" 1602 | resolved "https://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1603 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1604 | 1605 | write-file-atomic@^3.0.0: 1606 | version "3.0.3" 1607 | resolved "https://registry.npm.taobao.org/write-file-atomic/download/write-file-atomic-3.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwrite-file-atomic%2Fdownload%2Fwrite-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" 1608 | integrity sha1-Vr1cWlxwSBzRnFcb05q5ZaXeVug= 1609 | dependencies: 1610 | imurmurhash "^0.1.4" 1611 | is-typedarray "^1.0.0" 1612 | signal-exit "^3.0.2" 1613 | typedarray-to-buffer "^3.1.5" 1614 | 1615 | xdg-basedir@^4.0.0: 1616 | version "4.0.0" 1617 | resolved "https://registry.npm.taobao.org/xdg-basedir/download/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" 1618 | integrity sha1-S8jZmEQDaWIl74OhVzy7y0552xM= 1619 | 1620 | xtend@^4.0.0: 1621 | version "4.0.2" 1622 | resolved "https://registry.npm.taobao.org/xtend/download/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" 1623 | integrity sha1-u3J3n1+kZRhrH0OPZ0+jR/2121Q= 1624 | 1625 | ylru@^1.2.0: 1626 | version "1.2.1" 1627 | resolved "https://registry.npm.taobao.org/ylru/download/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" 1628 | integrity sha1-9Xa2M0FUeYnB3nuiiHYJI7J/6E8= 1629 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pdf-demo", 3 | "version": "2.10.6", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^4.2.4", 7 | "@testing-library/react": "^9.3.2", 8 | "@testing-library/user-event": "^7.1.2", 9 | "@umijs/hooks": "^1.9.2", 10 | "antd": "^4.1.3", 11 | "axios": "^0.19.2", 12 | "http-proxy-middleware": "^1.0.3", 13 | "jquery": "^3.5.0", 14 | "pdfjs-dist": "^2.2.228", 15 | "react": "^16.13.1", 16 | "react-dom": "^16.13.1", 17 | "react-scripts": "3.4.1", 18 | "react-virtualized": "^9.21.2", 19 | "spark-md5": "^3.0.1", 20 | "webuploader": "^0.1.8" 21 | }, 22 | "scripts": { 23 | "start": "react-scripts start", 24 | "build": "react-scripts build", 25 | "test": "react-scripts test", 26 | "eject": "react-scripts eject" 27 | }, 28 | "eslintConfig": { 29 | "extends": "react-app" 30 | }, 31 | "browserslist": { 32 | "production": [ 33 | ">0.2%", 34 | "not dead", 35 | "not op_mini all" 36 | ], 37 | "development": [ 38 | "last 1 chrome version", 39 | "last 1 firefox version", 40 | "last 1 safari version" 41 | ] 42 | }, 43 | "proxy": "http://127.0.0.1:5000" 44 | } 45 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuSandy/react-pdf-render/7b7b8739b7fe3e06570a9d7a70b706a92ff63795/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuSandy/react-pdf-render/7b7b8739b7fe3e06570a9d7a70b706a92ff63795/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuSandy/react-pdf-render/7b7b8739b7fe3e06570a9d7a70b706a92ff63795/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Other from './pages/other' 3 | 4 | const Index = props => { 5 | return 6 | } 7 | 8 | export default Index; -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /src/components/PDF/index.js: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect, useState } from 'react'; 2 | import { TextLayerBuilder } from 'pdfjs-dist/web/pdf_viewer'; 3 | import 'pdfjs-dist/web/pdf_viewer.css'; 4 | import './style.css' 5 | 6 | import pdfjs from 'pdfjs-dist'; 7 | import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'; 8 | 9 | 10 | 11 | pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker; 12 | 13 | const src = 'http://127.0.0.1:9002/p2.pdf' 14 | const devicePixelRatio = window.devicePixelRatio; 15 | 16 | const Index = () => { 17 | const canvasRef = useRef(null) 18 | // 保存PDF实例 19 | const [pdfInstance, setPdfInstance] = useState(null); 20 | // 保存PDF页码 21 | const [numPages, setNumPages] = useState(0); 22 | // 当前页 23 | const [currentPage, setCurrentPage] = useState(1); 24 | // 设置大小 25 | const [scale, setScale] = useState(1) 26 | 27 | const renderPdf = async (pdf, num) => { 28 | 29 | const page = await pdf.getPage(num); 30 | 31 | const viewport = page.getViewport({ scale: scale * devicePixelRatio }); 32 | 33 | // Prepare canvas using PDF page dimensions 34 | const canvas = canvasRef.current; 35 | 36 | const context = canvas.getContext('2d'); 37 | canvas.height = viewport.height; 38 | canvas.width = viewport.width; 39 | 40 | // Render PDF page into canvas context 41 | const renderContext = { 42 | canvasContext: context, 43 | viewport: viewport 44 | }; 45 | const renderTask = page.render(renderContext); 46 | 47 | await renderTask.promise.then(() => { 48 | return page.getTextContent() 49 | }).then(textContent => { 50 | renderText(textContent, canvas, page, viewport) 51 | }) 52 | } 53 | 54 | const renderText = (textContent, canvas, page, viewport) => { 55 | const textLayerDiv = document.createElement('div'); 56 | 57 | textLayerDiv.setAttribute('class', 'textLayer'); 58 | 59 | textLayerDiv.style.width = `${canvas.width}px` 60 | textLayerDiv.style.height = `${canvas.height}px` 61 | 62 | // 将文本图层div添加至每页pdf的div中 63 | const pageDom = canvas.parentNode 64 | pageDom.appendChild(textLayerDiv); 65 | 66 | // 创建新的TextLayerBuilder实例 67 | const textLayer = new TextLayerBuilder({ 68 | textLayerDiv, 69 | pageIndex: page.pageIndex, 70 | viewport, 71 | }); 72 | 73 | textLayer.setTextContent(textContent); 74 | 75 | textLayer.render(); 76 | } 77 | 78 | useEffect(() => { 79 | const fetchPdf = async () => { 80 | const loadingTask = pdfjs.getDocument(src); 81 | 82 | const pdf = await loadingTask.promise; 83 | setPdfInstance(pdf); 84 | setNumPages(pdf.numPages) 85 | renderPdf(pdf, currentPage) 86 | }; 87 | 88 | 89 | fetchPdf(); 90 | }, [src]); 91 | 92 | const percentZoom = `${Number(scale*100).toFixed(0)}%` 93 | 94 | return ( 95 |
96 |
97 |
98 | 111 | { 117 | const val = parseInt(e.target.value) 118 | if (val >= 1 && val <= numPages) { 119 | setCurrentPage(val) 120 | renderPdf(pdfInstance, val) 121 | } 122 | }} 123 | /> 124 | / {numPages} 125 |      126 | 139 |
140 |
141 | 152 | 156 | 168 |
169 |
170 |
171 | 176 |
177 |
178 | 179 | 180 | ); 181 | } 182 | 183 | export default Index; 184 | -------------------------------------------------------------------------------- /src/components/PDF/style.css: -------------------------------------------------------------------------------- 1 | .toolBus { 2 | background: #4b4b4b; 3 | line-height: 30px; 4 | position:fixed; 5 | width: 100%; 6 | flex-direction: row; 7 | z-index: 1; 8 | } 9 | 10 | .pagination{ 11 | width: 300px; 12 | float: left; 13 | } 14 | .zoom { 15 | width: 300px; 16 | float: left; 17 | } 18 | 19 | input { 20 | /* width: 30px; */ 21 | margin: 0 10px; 22 | } 23 | 24 | .container { 25 | position: absolute; 26 | top: 30px; 27 | justify-content: center; 28 | align-items: center; 29 | } 30 | .container > canvas { 31 | margin: auto; 32 | box-shadow: 0 0 16px rgba(0,0,0,0.16); 33 | } 34 | -------------------------------------------------------------------------------- /src/components/PDFViewer/images/shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuSandy/react-pdf-render/7b7b8739b7fe3e06570a9d7a70b706a92ff63795/src/components/PDFViewer/images/shadow.png -------------------------------------------------------------------------------- /src/components/PDFViewer/index.js: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect, useState } from 'react' 2 | import pdfjs from 'pdfjs-dist'; 3 | import { useKeyPress } from '@umijs/hooks'; 4 | import { PDFLinkService, PDFFindController, PDFViewer, DownloadManager } from 'pdfjs-dist/web/pdf_viewer'; 5 | import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'; 6 | import 'pdfjs-dist/web/pdf_viewer.css'; 7 | import './style.css' 8 | import { getVisibleElements } from './utils'; 9 | 10 | pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker; 11 | 12 | // 显示文字类型 0 不显示 1 显示 2 启用增强 13 | const TEXT_LAYER_MODE = 0; 14 | // 是否通过CSS控制放大缩小 true false 15 | const USE_ONLY_CSS_ZOOM = true 16 | 17 | const Index = props => { 18 | const containerRef = useRef(null); 19 | 20 | const [viewer = {}, setViewer] = useState({}); 21 | const [currentPageNumber = 1, setCurrentPageNumber] = useState(1); 22 | const [numPages = 1, setNumPages] = useState(1); 23 | const [pageData = 1, setPageData] = useState([]); 24 | const [scale = 1, setScale] = useState("auto"); 25 | const [searcher = {}, setSearcher] = useState({ 26 | phraseSearch: true, 27 | query: '', 28 | findPrevious: true, 29 | highlightAll: true, 30 | }); 31 | const [pdfDom = 1, setPdfDom] = useState(null); 32 | const [matchesCount = {}, setMatchesCount] = useState({}); 33 | 34 | // 页面滚动时操作 35 | const scrollPages = () => { 36 | // 当前试图显示的页面 37 | // { 38 | // first: // 当前页面 39 | // last: // 最后一个页面 40 | // } 41 | const viewers = getVisibleElements(pdfDom, pageData, true, false); 42 | console.log("currentPage", viewers); 43 | } 44 | 45 | const changePage = (num) => { 46 | viewer.currentPageNumber = num 47 | setCurrentPageNumber(num) 48 | } 49 | 50 | // 渲染页面 51 | const initialViewer = (url) => { 52 | const linkService = new PDFLinkService(); 53 | const findController = new PDFFindController({ 54 | linkService, 55 | }); 56 | const newViewer = new PDFViewer({ 57 | container: containerRef.current, 58 | linkService, 59 | useOnlyCssZoom: USE_ONLY_CSS_ZOOM, 60 | textLayerMode: TEXT_LAYER_MODE, 61 | // renderer:'svg', 62 | findController, 63 | }); 64 | linkService.setViewer(newViewer); 65 | // 设置初始缩放 66 | newViewer.currentScaleValue = scale; 67 | 68 | const loadingTask = pdfjs.getDocument({ url }); 69 | loadingTask.promise.then(pdf => { 70 | if (pdf) { 71 | const nums = pdf.numPages 72 | setNumPages(nums) 73 | newViewer.setDocument(pdf); 74 | linkService.setDocument(pdf); 75 | setViewer(newViewer) 76 | // 判断是否已经渲染完毕 77 | const interval = setInterval(() => { loadPdf() }, 1000); 78 | function loadPdf() { 79 | if (newViewer.pageViewsReady) { 80 | // // 暂时没有用到 81 | const pdfDom = document.getElementById('innerContainer') 82 | const pageData = [] 83 | pdfDom.childNodes.forEach((item, index) => { 84 | pageData.push({ 85 | div: item, 86 | id: index 87 | }) 88 | }) 89 | clearInterval(interval); 90 | setPageData(pageData) 91 | setPdfDom(pdfDom) 92 | } 93 | } 94 | } 95 | }) 96 | } 97 | 98 | const { url } = props 99 | 100 | useEffect(() => { 101 | if (url) { 102 | initialViewer(url) 103 | } 104 | // 监听事件 105 | document.addEventListener('pagechanging', function (evt) { 106 | const page = evt.detail.pageNumber; 107 | changePage(page) 108 | }) 109 | }, [url]) 110 | 111 | useKeyPress('enter', event => { 112 | viewer.findController.executeCommand('findagain', searcher); 113 | }); 114 | 115 | useEffect(() => { 116 | window.addEventListener('updatefindcontrolstate', e => { 117 | setMatchesCount(e.detail.matchesCount); 118 | }); 119 | window.addEventListener('updatefindmatchescount', e => { 120 | setMatchesCount(e.detail.matchesCount); 121 | }) 122 | }) 123 | 124 | 125 | const getPageStyle = (div) => { 126 | const demo = window.getComputedStyle(div, null); 127 | let divStyles = {} 128 | Object.keys(demo).forEach(key => { 129 | 130 | if (`${key}` !== '0' && !parseInt(key) && demo[key]) { 131 | divStyles = { 132 | ...divStyles, 133 | [`${key}`]: demo[key] 134 | } 135 | } 136 | }) 137 | return divStyles 138 | } 139 | 140 | return ( 141 |
142 |
143 |
144 | 157 | { 162 | const val = parseInt(e.target.value) 163 | if (val >= 1 && val <= numPages) { 164 | changePage(val) 165 | } 166 | }} 167 | /> 168 | / {numPages} 169 |      170 | 182 |
183 |
184 | 206 |
207 |
208 | { 212 | setSearcher({ 213 | ...searcher, 214 | query: e.target.value, 215 | }); 216 | }} 217 | /> 218 | {matchesCount.total ? ( 219 | {`第 ${matchesCount.current} 项, 共匹配 ${matchesCount.total} 项`} 220 | ) : null} 221 |
222 |
223 |
228 |
232 |
233 | {pageData.map((page,index)=>( 234 |
{index}
235 | ))} 236 |
237 |
238 | 239 |
240 | ) 241 | } 242 | 243 | Index.displayName = "PDFViewer" 244 | 245 | export default Index; -------------------------------------------------------------------------------- /src/components/PDFViewer/style.css: -------------------------------------------------------------------------------- 1 | 2 | #viewerContainer { 3 | position: absolute; 4 | overflow: auto; 5 | width: 100%; 6 | top: 3rem; 7 | bottom: 4rem; 8 | left: 0; 9 | right: 0; 10 | } 11 | 12 | .page { 13 | box-sizing: content-box; 14 | } 15 | 16 | .toolBus { 17 | height: 3rem; 18 | background-color: antiquewhite; 19 | line-height: 30px; 20 | position: fixed; 21 | width: 100%; 22 | flex-direction: row; 23 | z-index: 1; 24 | } 25 | 26 | .toolBus .pagination { 27 | width: 400px; 28 | float: left; 29 | margin: auto; 30 | } 31 | 32 | input { 33 | width: 100px; 34 | margin: 0 10px; 35 | } 36 | 37 | .selection { 38 | width: 300px; 39 | float: left; 40 | } 41 | 42 | .otherViewer { 43 | width: 100%; 44 | position: absolute; 45 | left: 0; 46 | top: 0; 47 | display: block; 48 | margin: auto; 49 | } 50 | 51 | .otherViewer .page { 52 | direction: ltr; 53 | width: 816px; 54 | height: 1056px; 55 | margin: 1px auto -8px auto; 56 | position: relative; 57 | overflow: visible; 58 | border: 9px solid transparent; 59 | background-clip: content-box; 60 | } -------------------------------------------------------------------------------- /src/components/PDFViewer/utils.js: -------------------------------------------------------------------------------- 1 | 2 | function binarySearchFirstItem(items, condition) { 3 | let minIndex = 0; 4 | let maxIndex = items.length - 1; 5 | 6 | if (items.length === 0 || !condition(items[maxIndex])) { 7 | return items.length; 8 | } 9 | if (condition(items[minIndex])) { 10 | return minIndex; 11 | } 12 | 13 | while (minIndex < maxIndex) { 14 | let currentIndex = (minIndex + maxIndex) >> 1; 15 | let currentItem = items[currentIndex]; 16 | if (condition(currentItem)) { 17 | maxIndex = currentIndex; 18 | } else { 19 | minIndex = currentIndex + 1; 20 | } 21 | } 22 | return minIndex; /* === maxIndex */ 23 | } 24 | 25 | function backtrackBeforeAllVisibleElements(index, views, top) { 26 | // binarySearchFirstItem's assumption is that the input is ordered, with only 27 | // one index where the conditions flips from false to true: [false ..., 28 | // true...]. With vertical scrolling and spreads, it is possible to have 29 | // [false ..., true, false, true ...]. With wrapped scrolling we can have a 30 | // similar sequence, with many more mixed true and false in the middle. 31 | // 32 | // So there is no guarantee that the binary search yields the index of the 33 | // first visible element. It could have been any of the other visible elements 34 | // that were preceded by a hidden element. 35 | 36 | // Of course, if either this element or the previous (hidden) element is also 37 | // the first element, there's nothing to worry about. 38 | if (index < 2) { 39 | return index; 40 | } 41 | 42 | // That aside, the possible cases are represented below. 43 | // 44 | // **** = fully hidden 45 | // A*B* = mix of partially visible and/or hidden pages 46 | // CDEF = fully visible 47 | // 48 | // (1) Binary search could have returned A, in which case we can stop. 49 | // (2) Binary search could also have returned B, in which case we need to 50 | // check the whole row. 51 | // (3) Binary search could also have returned C, in which case we need to 52 | // check the whole previous row. 53 | // 54 | // There's one other possibility: 55 | // 56 | // **** = fully hidden 57 | // ABCD = mix of fully and/or partially visible pages 58 | // 59 | // (4) Binary search could only have returned A. 60 | 61 | // Initially assume that we need to find the beginning of the current row 62 | // (case 1, 2, or 4), which means finding a page that is above the current 63 | // page's top. If the found page is partially visible, we're definitely not in 64 | // case 3, and this assumption is correct. 65 | let elt = views[index].div; 66 | let pageTop = elt.offsetTop + elt.clientTop; 67 | 68 | if (pageTop >= top) { 69 | // The found page is fully visible, so we're actually either in case 3 or 4, 70 | // and unfortunately we can't tell the difference between them without 71 | // scanning the entire previous row, so we just conservatively assume that 72 | // we do need to backtrack to that row. In both cases, the previous page is 73 | // in the previous row, so use its top instead. 74 | elt = views[index - 1].div; 75 | pageTop = elt.offsetTop + elt.clientTop; 76 | } 77 | 78 | // Now we backtrack to the first page that still has its bottom below 79 | // `pageTop`, which is the top of a page in the first visible row (unless 80 | // we're in case 4, in which case it's the row before that). 81 | // `index` is found by binary search, so the page at `index - 1` is 82 | // invisible and we can start looking for potentially visible pages from 83 | // `index - 2`. (However, if this loop terminates on its first iteration, 84 | // which is the case when pages are stacked vertically, `index` should remain 85 | // unchanged, so we use a distinct loop variable.) 86 | for (let i = index - 2; i >= 0; --i) { 87 | elt = views[i].div; 88 | if (elt.offsetTop + elt.clientTop + elt.clientHeight <= pageTop) { 89 | // We have reached the previous row, so stop now. 90 | // This loop is expected to terminate relatively quickly because the 91 | // number of pages per row is expected to be small. 92 | break; 93 | } 94 | index = i; 95 | } 96 | return index; 97 | } 98 | 99 | 100 | export const getVisibleElements=(scrollEl, views, sortByVisibility = false, horizontal = false)=>{ 101 | const top = scrollEl.scrollTop, 102 | bottom = top + scrollEl.clientHeight; 103 | const left = scrollEl.scrollLeft, 104 | right = left + scrollEl.clientWidth; 105 | 106 | // Throughout this "generic" function, comments will assume we're working with 107 | // PDF document pages, which is the most important and complex case. In this 108 | // case, the visible elements we're actually interested is the page canvas, 109 | // which is contained in a wrapper which adds no padding/border/margin, which 110 | // is itself contained in `view.div` which adds no padding (but does add a 111 | // border). So, as specified in this function's doc comment, this function 112 | // does all of its work on the padding edge of the provided views, starting at 113 | // offsetLeft/Top (which includes margin) and adding clientLeft/Top (which is 114 | // the border). Adding clientWidth/Height gets us the bottom-right corner of 115 | // the padding edge. 116 | function isElementBottomAfterViewTop(view) { 117 | const element = view.div; 118 | const elementBottom = element.offsetTop + element.clientTop + element.clientHeight; 119 | return elementBottom > top; 120 | } 121 | 122 | function isElementRightAfterViewLeft(view) { 123 | const element = view.div; 124 | const elementRight = element.offsetLeft + element.clientLeft + element.clientWidth; 125 | return elementRight > left; 126 | } 127 | 128 | const visible = [], 129 | numViews = views.length; 130 | let firstVisibleElementInd = 131 | numViews === 0 132 | ? 0 133 | : binarySearchFirstItem( 134 | views, 135 | horizontal ? isElementRightAfterViewLeft : isElementBottomAfterViewTop 136 | ); 137 | 138 | // Please note the return value of the `binarySearchFirstItem` function when 139 | // no valid element is found (hence the `firstVisibleElementInd` check below). 140 | if (firstVisibleElementInd > 0 && firstVisibleElementInd < numViews && !horizontal) { 141 | // In wrapped scrolling (or vertical scrolling with spreads), with some page 142 | // sizes, isElementBottomAfterViewTop doesn't satisfy the binary search 143 | // condition: there can be pages with bottoms above the view top between 144 | // pages with bottoms below. This function detects and corrects that error; 145 | // see it for more comments. 146 | firstVisibleElementInd = backtrackBeforeAllVisibleElements(firstVisibleElementInd, views, top); 147 | } 148 | 149 | // lastEdge acts as a cutoff for us to stop looping, because we know all 150 | // subsequent pages will be hidden. 151 | // 152 | // When using wrapped scrolling or vertical scrolling with spreads, we can't 153 | // simply stop the first time we reach a page below the bottom of the view; 154 | // the tops of subsequent pages on the same row could still be visible. In 155 | // horizontal scrolling, we don't have that issue, so we can stop as soon as 156 | // we pass `right`, without needing the code below that handles the -1 case. 157 | let lastEdge = horizontal ? right : -1; 158 | 159 | for (let i = firstVisibleElementInd; i < numViews; i++) { 160 | const view = views[i], 161 | element = view.div; 162 | const currentWidth = element.offsetLeft + element.clientLeft; 163 | const currentHeight = element.offsetTop + element.clientTop; 164 | const viewWidth = element.clientWidth, 165 | viewHeight = element.clientHeight; 166 | const viewRight = currentWidth + viewWidth; 167 | const viewBottom = currentHeight + viewHeight; 168 | 169 | if (lastEdge === -1) { 170 | // As commented above, this is only needed in non-horizontal cases. 171 | // Setting lastEdge to the bottom of the first page that is partially 172 | // visible ensures that the next page fully below lastEdge is on the 173 | // next row, which has to be fully hidden along with all subsequent rows. 174 | if (viewBottom >= bottom) { 175 | lastEdge = viewBottom; 176 | } 177 | } else if ((horizontal ? currentWidth : currentHeight) > lastEdge) { 178 | break; 179 | } 180 | 181 | if ( 182 | viewBottom <= top || 183 | currentHeight >= bottom || 184 | viewRight <= left || 185 | currentWidth >= right 186 | ) { 187 | continue; 188 | } 189 | 190 | const hiddenHeight = Math.max(0, top - currentHeight) + Math.max(0, viewBottom - bottom); 191 | const hiddenWidth = Math.max(0, left - currentWidth) + Math.max(0, viewRight - right); 192 | const percent = 193 | (((viewHeight - hiddenHeight) * (viewWidth - hiddenWidth) * 100) / viewHeight / viewWidth) | 194 | 0; 195 | visible.push({ 196 | id: view.id, 197 | x: currentWidth, 198 | y: currentHeight, 199 | view, 200 | percent, 201 | }); 202 | } 203 | 204 | const first = visible[0], 205 | last = visible[visible.length - 1]; 206 | 207 | if (sortByVisibility) { 208 | visible.sort(function(a, b) { 209 | let pc = a.percent - b.percent; 210 | if (Math.abs(pc) > 0.001) { 211 | return -pc; 212 | } 213 | return a.id - b.id; // ensure stability 214 | }); 215 | } 216 | return { first, last, views: visible }; 217 | } -------------------------------------------------------------------------------- /src/components/Upload/index.js: -------------------------------------------------------------------------------- 1 | // 上传文件组件 2 | 3 | import React, { useState } from 'react' 4 | import PropTypes from 'prop-types'; 5 | import { Progress } from 'antd' 6 | import axios from 'axios' 7 | import 'antd/dist/antd.css' 8 | import './style.css' 9 | 10 | // 需要分片文件的大小 11 | const largeFileSize = 20 * 1000 * 1000; 12 | 13 | let loadedLen = 0 14 | let fileChunkLen = 0 15 | 16 | const Index = props => { 17 | 18 | const { disabled, accept, multiple, children, action } = props 19 | const [progress, setProgress] = useState(100); 20 | 21 | const { beforeUpload, onUploadProgress } = props 22 | 23 | const axiosConfig = { 24 | onUploadProgress: progressEvent => { 25 | const curPercent = (loadedLen / fileChunkLen * 100).toFixed(2) 26 | setProgress(curPercent) 27 | // onUploadProgress(curPercent) 28 | } 29 | }; 30 | 31 | 32 | const onUpload = file => { 33 | const params = new FormData() 34 | params.append('file', file) 35 | console.log("params", params); 36 | 37 | axios.request({ 38 | url: action, 39 | method: 'POST', 40 | headers: { 'Content-Type': 'multipart/form-data' }, 41 | data: params, 42 | }).then(res => { 43 | console.log("返回结果", res); 44 | }) 45 | } 46 | 47 | const onChooseFile = e => { 48 | const files = Object.assign({}, e.target.files); 49 | beforeUpload && beforeUpload(files).then(res => { 50 | Object.keys(res).map(fileItem => { 51 | const file = files[fileItem] 52 | const { size } = file 53 | if (size > largeFileSize) { 54 | submitUpload(file, "/upload") 55 | } else { 56 | onUpload(files[fileItem]) 57 | } 58 | }) 59 | }).catch(err => { 60 | // 文件存在问题,终止上传 61 | console.log("err", err); 62 | }) 63 | } 64 | 65 | const createLimitPromise = (limitNum, promiseListRaw) => { 66 | let resArr = []; 67 | let handling = 0; 68 | let resolvedNum = 0; 69 | let promiseList = [...promiseListRaw] 70 | let runTime = promiseListRaw.length 71 | 72 | return new Promise(resolve => { 73 | //并发执行limitNum 次 74 | for (let i = 1; i <= limitNum; i++) { 75 | run(); 76 | } 77 | 78 | function run() { 79 | if (!promiseList.length) return 80 | handling += 1; 81 | handle(promiseList.shift()) 82 | .then(res => { 83 | resArr.push(res); 84 | }) 85 | .catch(e => { 86 | //ignore 87 | console.log("catch error"); 88 | }) 89 | .finally(() => { 90 | handling -= 1; 91 | resolvedNum += 1; 92 | 93 | //进度条 变量 94 | loadedLen = resolvedNum 95 | 96 | if (resolvedNum === runTime) { 97 | resolve(resArr) 98 | } 99 | run(); 100 | }); 101 | } 102 | function handle(promise) { 103 | return new Promise((resolve, reject) => { 104 | promise.then(res => resolve(res)).catch(e => reject(e)); 105 | }); 106 | } 107 | }); 108 | } 109 | 110 | const createChunkPromiseList = (chunkList, name, TOKEN) => { 111 | return chunkList 112 | .map((chunk, index) => { 113 | // console.log(chunk); 114 | let formdata = new FormData(); 115 | formdata.append("type", "upload"); 116 | formdata.append("name", name); 117 | formdata.append("token", TOKEN); 118 | formdata.append("chunk", chunk); 119 | formdata.append("index", index); 120 | return formdata; 121 | }) 122 | .map(formdata => { 123 | return axios.post("/upload", formdata, axiosConfig); 124 | }); 125 | } 126 | 127 | const sliceFile = (file, chunkSize) => { 128 | let chunkList = []; 129 | let start = 0; 130 | let end = chunkSize; 131 | while (true) { 132 | let curChunk = file.slice(start, end); 133 | if (!curChunk.size) break; 134 | chunkList.push(curChunk); 135 | start += chunkSize; 136 | end = start + chunkSize; 137 | } 138 | return chunkList; 139 | } 140 | 141 | const submitUpload = async (file, url) => { 142 | const CHUNKSIZE = 1 * 1024 * 1024; // 2M 143 | const TOKEN = Date.now(); 144 | //切割数组 145 | const chunkList = sliceFile(file, CHUNKSIZE); 146 | fileChunkLen = chunkList.length 147 | //创建formdata 并上传 148 | let promiseList = createChunkPromiseList(chunkList, file.name, TOKEN); 149 | //并发控制 上传 150 | await createLimitPromise(2, promiseList); 151 | 152 | //合并分片 153 | let mergeFormData = new FormData(); 154 | mergeFormData.append("type", "merge"); 155 | mergeFormData.append("token", TOKEN); 156 | mergeFormData.append("chunkCount", chunkList.length); 157 | mergeFormData.append("fileName", file.name); 158 | //结束后发送合并请求 159 | let res = await axios.post(url, mergeFormData, axiosConfig); 160 | } 161 | 162 | return ( 163 |
164 |
165 | 173 | {children} 174 |
175 | {progress ? ( 176 |
177 | 181 |
182 | ) : null} 183 | 184 |
185 | 186 | ) 187 | } 188 | 189 | Index.defaultProps = { 190 | disabled: false, 191 | multiple: false, 192 | accept: '.pdf', 193 | action: '/upload' 194 | } 195 | 196 | Index.propTypes = { 197 | action: PropTypes.string, // 上传的地址 198 | disabled: PropTypes.bool,// 是否禁用 199 | accept: PropTypes.string,// 上传接受的文件类型多个类型使用逗号隔开 200 | multiple: PropTypes.bool,// 是否支持多文件上传 201 | beforeUpload: PropTypes.func,// 上传文件之前的钩子,参数为上传的文件,若返回 false 则停止上传。支持返回一个 Promise 对象 202 | } 203 | 204 | 205 | export default Index; -------------------------------------------------------------------------------- /src/components/Upload/style.css: -------------------------------------------------------------------------------- 1 | .container { 2 | width: 100%; 3 | text-align: center; 4 | } 5 | 6 | .uploadContainer { 7 | position: relative; 8 | margin: auto; 9 | display: flex; 10 | text-align: center; 11 | width: 380px; 12 | height: 150px; 13 | background-color: #fafafa; 14 | border: 1px dashed #d9d9d9; 15 | padding: 16px; 16 | } 17 | 18 | .uploadContainer:hover { 19 | border: 1px dashed #1890ff; 20 | } 21 | 22 | .progress-container { 23 | margin: auto; 24 | padding: 16px; 25 | width: 380px; 26 | height: 50px; 27 | margin-top: 16px; 28 | border: 1px dashed #1890ff; 29 | } 30 | 31 | .fileInput { 32 | left: 0; 33 | top: 0; 34 | background-color: #666666; 35 | position: absolute; 36 | opacity: 0; 37 | cursor: pointer; 38 | font-size: 0; 39 | width: auto; 40 | height: auto; 41 | width: 100%; 42 | height: 100%; 43 | } -------------------------------------------------------------------------------- /src/components/VirtualizedPdf/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react' 2 | import pdfjs from 'pdfjs-dist'; 3 | import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'; 4 | import { List as VList } from 'react-virtualized'; 5 | import { TextLayerBuilder } from 'pdfjs-dist/web/pdf_viewer'; 6 | import 'pdfjs-dist/web/pdf_viewer.css'; 7 | import './style.css'; 8 | 9 | pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker; 10 | 11 | const src = 'http://127.0.0.1:9002/p2.pdf'; 12 | 13 | const firstPageNumber = 1; 14 | const devicePixelRatio = window.devicePixelRatio; 15 | 16 | const Index = props => { 17 | 18 | const [numPages, setNumPages] = useState([]); 19 | 20 | const [pdf, setPdf] = useState(null); 21 | 22 | const [scale, setScale] = useState(1); 23 | 24 | const [currentPage, setCurrentPage] = useState(2) 25 | 26 | 27 | const renderPdf = async (num, curPdf) => { 28 | 29 | const page = await curPdf.getPage(num + 1); 30 | const viewport = page.getViewport({ scale: scale * devicePixelRatio }); 31 | 32 | // Prepare canvas using PDF page dimensions 33 | const canvas = document.querySelector(`canvas[data-page-number='${num + 1}']`); 34 | 35 | const context = canvas.getContext('2d'); 36 | canvas.height = viewport.height; 37 | canvas.width = viewport.width; 38 | 39 | // Render PDF page into canvas context 40 | const renderContext = { 41 | canvasContext: context, 42 | viewport: viewport 43 | }; 44 | const renderTask = page.render(renderContext); 45 | 46 | await renderTask.promise.then(() => { 47 | return page.getTextContent() 48 | }).then(textContent => { 49 | renderText(textContent, num, page, viewport) 50 | }) 51 | } 52 | 53 | const renderText = (textContent, num, page, viewport) => { 54 | const textLayerDiv = document.querySelector(`div[data-page-number='${num + 1}']`) 55 | if (textLayerDiv) { 56 | // 创建新的TextLayerBuilder实例 57 | const textLayer = new TextLayerBuilder({ 58 | textLayerDiv, 59 | pageIndex: page.pageIndex, 60 | viewport, 61 | }); 62 | 63 | textLayer.setTextContent(textContent); 64 | 65 | textLayer.render(); 66 | } 67 | } 68 | 69 | const getPageInfo = async (curPdf) => { 70 | 71 | const page = await curPdf.getPage(firstPageNumber); 72 | const viewport = page.getViewport({ scale: scale * devicePixelRatio }); 73 | const width = viewport.width; 74 | const height = viewport.height; 75 | const array = [] 76 | for (let index = 0; index < curPdf.numPages; index++) { 77 | array.push({ width, height }) 78 | } 79 | setNumPages(array) 80 | } 81 | 82 | const getItemHeight = ({ index }) => numPages[index].height; 83 | 84 | const renderItem = ({ key, index, style }) => ( 85 |
86 | 90 |
95 |
96 | ) 97 | 98 | const fetchPdf = async () => { 99 | const loadingTask = pdfjs.getDocument(src); 100 | 101 | const curPdf = await loadingTask.promise; 102 | await setPdf(curPdf); 103 | getPageInfo(curPdf); 104 | }; 105 | 106 | useEffect(() => { 107 | fetchPdf(); 108 | 109 | }, []) 110 | 111 | return ( 112 |
113 |
114 |
115 | 127 | 133 | / {numPages.length} 134 |      135 | 147 |
148 |
149 |
150 | {pdf && numPages.length ? ( 151 | { 169 | renderPdf(startIndex, pdf) 170 | setCurrentPage(stopIndex + 1) 171 | }} 172 | /> 173 | ) : null} 174 |
175 | 176 |
177 | ) 178 | } 179 | 180 | export default Index; -------------------------------------------------------------------------------- /src/components/VirtualizedPdf/style.css: -------------------------------------------------------------------------------- 1 | .toolBus { 2 | background: #4b4b4b; 3 | line-height: 30px; 4 | position:fixed; 5 | width: 100%; 6 | flex-direction: row; 7 | z-index: 1; 8 | } 9 | 10 | .pagination{ 11 | width: 300px; 12 | float: left; 13 | } 14 | .zoom { 15 | width: 300px; 16 | float: left; 17 | } 18 | 19 | input { 20 | width: 30px; 21 | margin: 0 10px; 22 | } 23 | 24 | .container { 25 | position: absolute; 26 | top: 30px; 27 | justify-content: center; 28 | align-items: center; 29 | } 30 | .container > canvas { 31 | margin: auto; 32 | box-shadow: 0 0 16px rgba(0,0,0,0.16); 33 | } 34 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Upload } from './Upload' 2 | // export { default as PDF } from './PDF' 3 | // export { default as VirtualizedPdf } from './VirtualizedPdf' 4 | export { default as PDFViewer } from './PDFViewer' -------------------------------------------------------------------------------- /src/demo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuSandy/react-pdf-render/7b7b8739b7fe3e06570a9d7a70b706a92ff63795/src/demo.pdf -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want your app to work offline and load faster, you can change 15 | // unregister() to register() below. Note this comes with some pitfalls. 16 | // Learn more about service workers: https://bit.ly/CRA-PWA 17 | serviceWorker.unregister(); 18 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/pages/other/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { PDFViewer } from '../../components' 3 | 4 | const url = 'http://127.0.0.1:9002/p4.pdf' 5 | 6 | const Index = props => { 7 | return (
8 | 9 |
) 10 | } 11 | 12 | export default Index; -------------------------------------------------------------------------------- /src/pages/uploadFile/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import axios from 'axios' 3 | import { InboxOutlined } from '@ant-design/icons'; 4 | import './style.css' 5 | import { FileUpload, Upload } from '../../components' 6 | 7 | const Index = props => { 8 | 9 | const testConnection = () => { 10 | axios({ 11 | url: '/test-connection', 12 | method: 'GET' 13 | }) 14 | } 15 | 16 | return ( 17 |
18 | {/* */} 19 | { 21 | return new Promise((resolve, reject) => { 22 | resolve(file) 23 | }); 24 | }} 25 | onUploadProgress={curPercent => { 26 | console.log("上传进度", `${curPercent}%`); 27 | 28 | }} 29 | > 30 |
31 |

32 | 33 |

34 |

Click or drag file to this area to upload

35 |

36 | Support for a single or bulk upload. Strictly prohibit from uploading company data or other 37 | band files 38 |

39 |
40 |
41 |
42 | ) 43 | } 44 | 45 | export default Index; -------------------------------------------------------------------------------- /src/pages/uploadFile/style.css: -------------------------------------------------------------------------------- 1 | .ant-upload-text { 2 | margin: 0 0 4px; 3 | color: rgba(0, 0, 0, 0.85); 4 | font-size: 16px; 5 | } 6 | 7 | .ant-upload-hint { 8 | color: rgba(0, 0, 0, 0.45); 9 | font-size: 14px; 10 | } -------------------------------------------------------------------------------- /src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.0/8 are considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl, { 104 | headers: { 'Service-Worker': 'script' }, 105 | }) 106 | .then(response => { 107 | // Ensure service worker exists, and that we really are getting a JS file. 108 | const contentType = response.headers.get('content-type'); 109 | if ( 110 | response.status === 404 || 111 | (contentType != null && contentType.indexOf('javascript') === -1) 112 | ) { 113 | // No service worker found. Probably a different app. Reload the page. 114 | navigator.serviceWorker.ready.then(registration => { 115 | registration.unregister().then(() => { 116 | window.location.reload(); 117 | }); 118 | }); 119 | } else { 120 | // Service worker found. Proceed as normal. 121 | registerValidSW(swUrl, config); 122 | } 123 | }) 124 | .catch(() => { 125 | console.log( 126 | 'No internet connection found. App is running in offline mode.' 127 | ); 128 | }); 129 | } 130 | 131 | export function unregister() { 132 | if ('serviceWorker' in navigator) { 133 | navigator.serviceWorker.ready 134 | .then(registration => { 135 | registration.unregister(); 136 | }) 137 | .catch(error => { 138 | console.error(error.message); 139 | }); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | --------------------------------------------------------------------------------